Main readme updated, documentation updated, Makefiles updated. Experimental features snapshot. 1.14: Crafting table item rendering added. Recipe collision resolver added. Lang files updated.

This commit is contained in:
stfwi 2019-09-17 17:56:08 +02:00
parent bc76fed9d6
commit 03957b423a
52 changed files with 893 additions and 267 deletions

View file

@ -28,7 +28,7 @@ wildcardr=$(foreach d,$(wildcard $1*),$(call wildcardr,$d/,$2) $(filter $(subst
# #
# Targets # Targets
# #
.PHONY: default mod init clean clean-all mrproper all run install sanatize dist-check dist start-server port-languages .PHONY: default mod init clean clean-all mrproper all run install sanatize dist-check dist dist-files start-server port-languages
default: mod default: mod
@ -94,12 +94,14 @@ dist-check:
@echo "[1.12] Running dist checks ..." @echo "[1.12] Running dist checks ..."
@djs tasks.js dist-check @djs tasks.js dist-check
dist: sanatize dist-check clean-all init mod dist-files: clean-all init mod
@echo "[1.12] Distribution files ..." @echo "[1.12] Distribution files ..."
@mkdir -p dist @mkdir -p dist
@cp build/libs/$(MOD_JAR_PREFIX)* dist/ @cp build/libs/$(MOD_JAR_PREFIX)* dist/
@djs tasks.js dist @djs tasks.js dist
dist: sanatize dist-check dist-files
port-languages: port-languages:
@echo "[1.12] Porting language files to 1.14 ..." @echo "[1.12] Porting language files to 1.14 ..."
@djs tasks.js port-languages @djs tasks.js port-languages

View file

@ -10,7 +10,11 @@ Mod sources for Minecraft version 1.12.2.
---- ----
## Version history ## Version history
~ v1.0.12-b2 [A] Lang files updated. ~ v1.0.12-b2 [A] Crafting Table: Added recipe collision resolver,
also applies to crafting history refabrication.
[A] Crafting Table: Added rendering of placed items
on the top surface of the table.
[M] Lang files updated.
- v1.0.12-b1 [A] Mineal Smelter non-experimental now. - v1.0.12-b1 [A] Mineal Smelter non-experimental now.
[M] Window submodels stripped (reopened issue #19, thx overchoice). [M] Window submodels stripped (reopened issue #19, thx overchoice).

View file

@ -25,6 +25,7 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
@ -595,6 +596,11 @@ public class ModContent
for(Item e:registeredItems) { for(Item e:registeredItems) {
if(e instanceof ItemDecor) ((ItemDecor)e).initModel(); if(e instanceof ItemDecor) ((ItemDecor)e).initModel();
} }
if(!ModConfig.optout.without_tesrs) {
if(!ModConfig.isOptedOut(TREATED_WOOD_CRAFTING_TABLE)) {
ClientRegistry.bindTileEntitySpecialRenderer(BlockDecorCraftingTable.BTileEntity.class, new ModTesrs.TesrDecorCraftingTable());
}
}
} }
// Invoked from CommonProxy.registerItems() // Invoked from CommonProxy.registerItems()

View file

@ -9,24 +9,29 @@
*/ */
package wile.engineersdecor.blocks; package wile.engineersdecor.blocks;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import wile.engineersdecor.ModEngineersDecor; import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.Networking; import wile.engineersdecor.detail.Networking;
import net.minecraft.world.World;
import net.minecraft.world.Explosion;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.SoundType; import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.world.World; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.world.Explosion;
import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.*; import net.minecraft.inventory.*;
import net.minecraft.init.Items;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.init.Items; import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.Ingredient; import net.minecraft.item.crafting.Ingredient;
import net.minecraft.network.play.server.SPacketSetSlot;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*; import net.minecraft.util.*;
@ -342,12 +347,13 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
protected static final int BUTTON_NEXT = 0; protected static final int BUTTON_NEXT = 0;
protected static final int BUTTON_PREV = 1; protected static final int BUTTON_PREV = 1;
protected static final int BUTTON_CLEAR_GRID = 2; protected static final int BUTTON_CLEAR_GRID = 2;
protected static final int BUTTON_FROM_STORAGE = 3; protected static final int BUTTON_NEXT_COLLISION_RECIPE = 3;
protected static final int BUTTON_TO_STORAGE = 4; protected static final int BUTTON_FROM_STORAGE = 4;
protected static final int BUTTON_FROM_PLAYER = 5; protected static final int BUTTON_TO_STORAGE = 5;
protected static final int BUTTON_TO_PLAYER = 6; protected static final int BUTTON_FROM_PLAYER = 6;
protected static final int ACTION_PLACE_CURRENT_HISTORY_SEL = 7; protected static final int BUTTON_TO_PLAYER = 7;
protected static final int ACTION_PLACE_SHIFTCLICKED_STACK = 8; protected static final int ACTION_PLACE_CURRENT_HISTORY_SEL = 8;
protected static final int ACTION_PLACE_SHIFTCLICKED_STACK = 9;
protected static final ResourceLocation BACKGROUND = new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/treated_wood_crafting_table.png"); protected static final ResourceLocation BACKGROUND = new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/treated_wood_crafting_table.png");
protected final BTileEntity te; protected final BTileEntity te;
@ -369,6 +375,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
buttons.add(addButton(new GuiButtonImage(BUTTON_NEXT, x0+158,y0+44, 12,12, 194,44, 12, BACKGROUND))); 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_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_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)));
if(with_assist_quickmove_buttons) { 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_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_TO_STORAGE, x0+49, y0+52, 9,17, 208,16, 17, BACKGROUND)));
@ -381,6 +388,10 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
@Override @Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) 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();
}
drawDefaultBackground(); drawDefaultBackground();
super.drawScreen(mouseX, mouseY, partialTicks); super.drawScreen(mouseX, mouseY, partialTicks);
renderHoveredToolTip(mouseX, mouseY); renderHoveredToolTip(mouseX, mouseY);
@ -476,7 +487,8 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
case BUTTON_TO_STORAGE: case BUTTON_TO_STORAGE:
case BUTTON_FROM_PLAYER: case BUTTON_FROM_PLAYER:
case BUTTON_TO_PLAYER: case BUTTON_TO_PLAYER:
case ACTION_PLACE_CURRENT_HISTORY_SEL: { case ACTION_PLACE_CURRENT_HISTORY_SEL:
case BUTTON_NEXT_COLLISION_RECIPE: {
NBTTagCompound nbt = new NBTTagCompound(); NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("action", button.id); nbt.setInteger("action", button.id);
Networking.PacketTileNotify.sendToServer(te, nbt); Networking.PacketTileNotify.sendToServer(te, nbt);
@ -615,8 +627,32 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
@Override @Override
public void onCraftMatrixChanged(IInventory inv) public void onCraftMatrixChanged(IInventory inv)
{ {
if(world.isRemote) return;
try { try {
slotChangedCraftingGrid(world, player, craftMatrix, craftResult); InventoryCrafting grid = craftMatrix;
InventoryCraftResult result = craftResult;
EntityPlayerMP pl = (EntityPlayerMP)player;
ItemStack stack = ItemStack.EMPTY;
List<IRecipe> matching_recipes = new ArrayList<IRecipe>();
final IRecipe current_recipe = result.getRecipeUsed();
final ItemStack current_recipe_stack = result.getStackInSlot(0);
IRecipe current_recipe_matching = null;
for(IRecipe r:CraftingManager.REGISTRY) {
if((r==null) || (!r.matches(grid, world))) continue;
if((!r.isDynamic()) && (world.getGameRules().getBoolean("doLimitedCrafting")) && (!pl.getRecipeBook().isUnlocked(r))) continue;
matching_recipes.add(r);
ItemStack recipe_result_stack = r.getCraftingResult(grid);
if((r==current_recipe) || (recipe_result_stack.isItemEqual(current_recipe_stack))) current_recipe_matching = r;
}
te.has_recipe_collision_ = (matching_recipes.size() > 1);
if(matching_recipes.size() > 0) {
if(current_recipe_matching==null) current_recipe_matching = matching_recipes.get(0);
result.setRecipeUsed(current_recipe_matching);
stack = current_recipe_matching.getCraftingResult(grid);
}
result.setInventorySlotContents(0, stack);
pl.connection.sendPacket(new SPacketSetSlot(this.windowId, 0, stack));
te.syncProperties(player);
} catch(Throwable exc) { } catch(Throwable exc) {
ModEngineersDecor.logger.error("Recipe failed:", exc); ModEngineersDecor.logger.error("Recipe failed:", exc);
} }
@ -676,6 +712,31 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
public void setCraftingMatrixSlot(int slot_index, ItemStack stack) public void setCraftingMatrixSlot(int slot_index, ItemStack stack)
{ craftMatrix.setInventorySlotContents(slot_index, stack.copy()); } { craftMatrix.setInventorySlotContents(slot_index, stack.copy()); }
public void select_next_collision_recipe(IInventory inv, EntityPlayer player)
{
if(world.isRemote) return;
try {
EntityPlayerMP pl = (EntityPlayerMP) player;
List<IRecipe> matching_recipes = new ArrayList<IRecipe>();
final IRecipe current_recipe = craftResult.getRecipeUsed();
final ItemStack current_recipe_stack = craftResult.getStackInSlot(0);
int next_recipe_index = 0;
for(IRecipe r:CraftingManager.REGISTRY) {
if((r==null) || (!r.matches(craftMatrix, world))) continue;
if((!r.isDynamic()) && (world.getGameRules().getBoolean("doLimitedCrafting")) && (!pl.getRecipeBook().isUnlocked(r))) continue;
matching_recipes.add(r);
ItemStack recipe_result_stack = r.getCraftingResult(craftMatrix);
if((r==current_recipe) || (recipe_result_stack.isItemEqual(current_recipe_stack))) next_recipe_index = matching_recipes.size();
}
IRecipe next_recipe = matching_recipes.get((next_recipe_index >= matching_recipes.size()) ? 0 : next_recipe_index);
craftResult.setInventorySlotContents(0, next_recipe.getCraftingResult(craftMatrix));
craftResult.setRecipeUsed(next_recipe);
onCraftMatrixChanged(inv);
} catch(Throwable exc) {
ModEngineersDecor.logger.error("Recipe failed:", exc);
}
}
} }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
@ -741,6 +802,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
public static final int NUM_OF_SLOTS = NUM_OF_CRAFTING_SLOTS+NUM_OF_STORAGE_SLOTS; public static final int NUM_OF_SLOTS = NUM_OF_CRAFTING_SLOTS+NUM_OF_STORAGE_SLOTS;
protected NonNullList<ItemStack> stacks; protected NonNullList<ItemStack> stacks;
protected final CraftingHistory history = new CraftingHistory(); protected final CraftingHistory history = new CraftingHistory();
protected boolean has_recipe_collision_ = false;
public BTileEntity() public BTileEntity()
{ stacks = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY); } { stacks = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY); }
@ -764,6 +826,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
// private aux methods --------------------------------------------------------------------- // private aux methods ---------------------------------------------------------------------
private boolean has_recipe_collision()
{ return has_recipe_collision_; }
private boolean itemstack_recipe_match(ItemStack grid_stack, ItemStack history_stack) private boolean itemstack_recipe_match(ItemStack grid_stack, ItemStack history_stack)
{ {
if(history.current_recipe()!=null) { if(history.current_recipe()!=null) {
@ -948,7 +1013,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
} }
enum EnumRefabPlacement { UNCHANGED, INCOMPLETE, PLACED } enum EnumRefabPlacement { UNCHANGED, INCOMPLETE, PLACED }
private EnumRefabPlacement place_refab_stacks(IInventory inventory, final int slot_begin, final int slot_end) private EnumRefabPlacement place_refab_stacks(IInventory inventory, final int slot_begin, final int slot_end, @Nullable EntityPlayer player)
{ {
List<ItemStack> to_fill = crafting_slot_stacks_to_add(); List<ItemStack> to_fill = crafting_slot_stacks_to_add();
boolean slots_changed = false; boolean slots_changed = false;
@ -978,6 +1043,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
if(!slots_updated) break; if(!slots_updated) break;
} }
} }
if((history.current_recipe() != null) && (player!=null) && (player.openContainer instanceof BContainer)) {
((BContainer)player.openContainer).craftResult.setRecipeUsed(history.current_recipe());
}
if(!slots_changed) { if(!slots_changed) {
return EnumRefabPlacement.UNCHANGED; return EnumRefabPlacement.UNCHANGED;
} else if(missing_item) { } else if(missing_item) {
@ -1094,25 +1162,25 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; } if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; }
} break; } break;
case BGui.BUTTON_FROM_STORAGE: { case BGui.BUTTON_FROM_STORAGE: {
EnumRefabPlacement from_storage = place_refab_stacks(this, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN + NUM_OF_STORAGE_SLOTS); EnumRefabPlacement from_storage = place_refab_stacks(this, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN + NUM_OF_STORAGE_SLOTS, player);
if(from_storage != EnumRefabPlacement.UNCHANGED) te_changed = true; if(from_storage != EnumRefabPlacement.UNCHANGED) te_changed = true;
} break; } break;
case BGui.BUTTON_FROM_PLAYER: { case BGui.BUTTON_FROM_PLAYER: {
EnumRefabPlacement from_player_inv = place_refab_stacks(player.inventory, 9, 36); EnumRefabPlacement from_player_inv = place_refab_stacks(player.inventory, 9, 36, player);
if(from_player_inv != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; } if(from_player_inv != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; }
if(from_player_inv != EnumRefabPlacement.PLACED) { if(from_player_inv != EnumRefabPlacement.PLACED) {
EnumRefabPlacement from_hotbar = place_refab_stacks(player.inventory, 0, 9); EnumRefabPlacement from_hotbar = place_refab_stacks(player.inventory, 0, 9, player);
if(from_hotbar != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; } if(from_hotbar != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; }
} }
} break; } break;
case BGui.ACTION_PLACE_CURRENT_HISTORY_SEL: { case BGui.ACTION_PLACE_CURRENT_HISTORY_SEL: {
EnumRefabPlacement from_storage = place_refab_stacks(this, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN + NUM_OF_STORAGE_SLOTS); EnumRefabPlacement from_storage = place_refab_stacks(this, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN + NUM_OF_STORAGE_SLOTS, player);
if(from_storage != EnumRefabPlacement.UNCHANGED) te_changed = true; if(from_storage != EnumRefabPlacement.UNCHANGED) te_changed = true;
if(from_storage != EnumRefabPlacement.PLACED) { if(from_storage != EnumRefabPlacement.PLACED) {
EnumRefabPlacement from_player_inv = place_refab_stacks(player.inventory, 9, 36); EnumRefabPlacement from_player_inv = place_refab_stacks(player.inventory, 9, 36, player);
if(from_player_inv != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; } if(from_player_inv != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; }
if(from_player_inv != EnumRefabPlacement.PLACED) { if(from_player_inv != EnumRefabPlacement.PLACED) {
EnumRefabPlacement from_hotbar = place_refab_stacks(player.inventory, 0, 9); EnumRefabPlacement from_hotbar = place_refab_stacks(player.inventory, 0, 9, player);
if(from_hotbar != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; } if(from_hotbar != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; }
} }
} }
@ -1132,6 +1200,11 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
if(stat != EnumRefabPlacement.UNCHANGED) { player_inventory_changed = true; te_changed = true; } if(stat != EnumRefabPlacement.UNCHANGED) { player_inventory_changed = true; te_changed = true; }
} }
} break; } break;
case BGui.BUTTON_NEXT_COLLISION_RECIPE: {
if(player.openContainer instanceof BContainer) {
((BContainer)player.openContainer).select_next_collision_recipe(this, player);
}
} break;
} }
} }
if(te_changed) markDirty(); if(te_changed) markDirty();
@ -1146,6 +1219,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
public void onServerPacketReceived(NBTTagCompound nbt) public void onServerPacketReceived(NBTTagCompound nbt)
{ {
if(nbt.hasKey("historydata")) history.read(nbt.getCompoundTag("historydata")); if(nbt.hasKey("historydata")) history.read(nbt.getCompoundTag("historydata"));
if(nbt.hasKey("hascollision")) has_recipe_collision_ = nbt.getBoolean("hascollision");
} }
private void syncHistory(EntityPlayer player) private void syncHistory(EntityPlayer player)
@ -1155,6 +1229,15 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
history.write(history_nbt); history.write(history_nbt);
NBTTagCompound rnbt = new NBTTagCompound(); NBTTagCompound rnbt = new NBTTagCompound();
rnbt.setTag("historydata", history_nbt); rnbt.setTag("historydata", history_nbt);
rnbt.setBoolean("hascollision", has_recipe_collision_);
Networking.PacketTileNotify.sendToPlayer(player, this, rnbt);
}
private void syncProperties(EntityPlayer player)
{
if(!with_assist) return;
NBTTagCompound rnbt = new NBTTagCompound();
rnbt.setBoolean("hascollision", has_recipe_collision_);
Networking.PacketTileNotify.sendToPlayer(player, this, rnbt); Networking.PacketTileNotify.sendToPlayer(player, this, rnbt);
} }
@ -1173,9 +1256,26 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
{ super.writeToNBT(nbt); writenbt(nbt); return nbt; } { super.writeToNBT(nbt); writenbt(nbt); return nbt; }
@Override @Override
public NBTTagCompound getUpdateTag() public NBTTagCompound getUpdateTag() // on server
{ NBTTagCompound nbt = new NBTTagCompound(); super.writeToNBT(nbt); writenbt(nbt); return nbt; } { NBTTagCompound nbt = new NBTTagCompound(); super.writeToNBT(nbt); writenbt(nbt); return nbt; }
@Override
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) // on client
{ super.readFromNBT(pkt.getNbtCompound()); readnbt(pkt.getNbtCompound()); super.onDataPacket(net, pkt); }
@Override
public SPacketUpdateTileEntity getUpdatePacket() // on server
{ return new SPacketUpdateTileEntity(pos, 1, getUpdateTag()); }
@Override
public void handleUpdateTag(NBTTagCompound tag) // on client
{ readFromNBT(tag); }
@Override
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared()
{ return 400; }
// IWorldNamable --------------------------------------------------------------------------- // IWorldNamable ---------------------------------------------------------------------------
@Override @Override
@ -1256,7 +1356,6 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
@Override @Override
public void clear() public void clear()
{ stacks.clear(); } { stacks.clear(); }
} }
} }

View file

@ -191,6 +191,10 @@ public class ModConfig
@Config.Comment({"Disable CTRL-SHIFT item tooltip display."}) @Config.Comment({"Disable CTRL-SHIFT item tooltip display."})
@Config.Name("Without tooltips") @Config.Name("Without tooltips")
public boolean without_tooltips = false; public boolean without_tooltips = false;
@Config.Comment({"Disable all tile entity special renderers."})
@Config.Name("Without TESRs")
public boolean without_tesrs = false;
} }
@Config.Comment({ @Config.Comment({

View file

@ -0,0 +1,85 @@
/*
* @file ModTesrs.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2018 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Yet unstructured initial experiments with TESRs.
* May be structured after I know what I am doing there.
*/
package wile.engineersdecor.detail;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.blocks.BlockDecorCraftingTable;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class ModTesrs
{
//--------------------------------------------------------------------------------------------------------------------
// Crafting table
//--------------------------------------------------------------------------------------------------------------------
@SideOnly(Side.CLIENT)
public static class TesrDecorCraftingTable extends TileEntitySpecialRenderer<BlockDecorCraftingTable.BTileEntity>
{
private static int tesr_error_counter = 4;
private static double scaler = 0.10;
private static double gap = 0.19;
private static double yrotations[] = {0, 90, 180, 270}; // [hdirection] S-W-N-E
private static double offsets[][][] = { // [hdirection][slotindex][xz]
{ {-1,-1},{+0,-1},{+1,-1}, {-1,+0},{+0,+0},{+1,+0}, {-1,+1},{+0,+1},{+1,+1} }, // S
{ {+1,-1},{+1,+0},{+1,+1}, {+0,-1},{+0,+0},{+0,+1}, {-1,-1},{-1,+0},{-1,+1} }, // W
{ {+1,+1},{+0,+1},{-1,+1}, {+1,+0},{+0,+0},{-1,+0}, {+1,-1},{+0,-1},{-1,-1} }, // N
{ {-1,+1},{-1,+0},{-1,-1}, {+0,+1},{+0,+0},{+0,-1}, {+1,+1},{+1,+0},{+1,-1} }, // E
};
@Override
public void render(final BlockDecorCraftingTable.BTileEntity 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 {
int di = MathHelper.clamp(te.getWorld().getBlockState(te.getPos()).getValue(BlockDecorCraftingTable.FACING).getHorizontalIndex(), 0, 3);
long posrnd = te.getPos().toLong();
posrnd = (posrnd>>16)^(posrnd<<1);
for(int i=0; i<BlockDecorCraftingTable.BTileEntity.NUM_OF_CRAFTING_SLOTS; ++i) {
final ItemStack stack = te.getStackInSlot(BlockDecorCraftingTable.BTileEntity.CRAFTING_SLOTS_BEGIN+i);
if(stack.isEmpty()) continue;
boolean isblock = (stack.getItem() instanceof ItemBlock);
double prnd = ((double)(((Integer.rotateRight(stack.getItem().hashCode()^(int)posrnd,(stack.getCount()+i)&31)))&1023))/1024.0;
double rndo = gap * ((prnd*0.1)-0.05);
double ox = gap * offsets[di][i][0], oz = gap * offsets[di][i][1];
double oy = 0.5;
double ry = ((yrotations[di]+180) + ((prnd*60)-30)) % 360;
if(stack.isEmpty()) return;
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
RenderHelper.enableStandardItemLighting();
GlStateManager.translate(x+0.5+ox, y+0.5+oy, z+0.5+oz);
GlStateManager.rotate((float)90, 1, 0, 0);
GlStateManager.rotate((float)ry, 0, 0, 1);
GlStateManager.translate(rndo, rndo, 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("TESR was disabled because broken, exception was: " + e.getMessage());
ModEngineersDecor.logger.error(e.getStackTrace());
}
}
}
}
}

View file

@ -37,6 +37,10 @@ public class RecipeCondModSpecific implements IConditionFactory
public BooleanSupplier parse(JsonContext context, JsonObject json) { public BooleanSupplier parse(JsonContext context, JsonObject json) {
if(ModConfig.isWithoutRecipes()) return exclude(); if(ModConfig.isWithoutRecipes()) return exclude();
try { try {
final JsonPrimitive experimental = json.getAsJsonPrimitive("experimental");
if((experimental!=null) && (experimental.getAsBoolean())) {
if(!ModConfig.zmisc.with_experimental) return exclude();
}
final IForgeRegistry<Block> block_registry = ForgeRegistries.BLOCKS; final IForgeRegistry<Block> block_registry = ForgeRegistries.BLOCKS;
final IForgeRegistry<Item> item_registry = ForgeRegistries.ITEMS; final IForgeRegistry<Item> item_registry = ForgeRegistries.ITEMS;
final JsonArray items = json.getAsJsonArray("required"); final JsonArray items = json.getAsJsonArray("required");

View file

@ -199,11 +199,16 @@
"display": { "display": {
"thirdperson_righthand": { "thirdperson_righthand": {
"rotation": [85, 3, -10], "rotation": [85, 3, -10],
"translation": [1.75, -0.75, -2.25], "translation": [0.75, 0.25, 0.5],
"scale": [0.35, 0.35, 0.35] "scale": [0.35, 0.35, 0.35]
}, },
"firstperson_righthand": {
"rotation": [18, 22, 0],
"translation": [1.25, 0, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": { "ground": {
"translation": [0, -0.75, 0], "translation": [0, -1.25, 0],
"scale": [0.2, 0.2, 0.2] "scale": [0.2, 0.2, 0.2]
}, },
"gui": { "gui": {

View file

@ -0,0 +1,22 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"experimental": true
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"DDD",
" D ",
" D "
],
"key": {
"D": { "item": "minecraft:stone", "data":3 }
},
"result": {
"item": "minecraft:stone",
"data": 0,
"count": 1
}
}

View file

@ -0,0 +1,22 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"experimental": true
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"DDD",
" D ",
" D "
],
"key": {
"D": { "item": "minecraft:stone", "data":3 }
},
"result": {
"item": "minecraft:stone",
"data": 1,
"count": 1
}
}

View file

@ -0,0 +1,22 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"experimental": true
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"DDD",
" D ",
" D "
],
"key": {
"D": { "item": "minecraft:stone", "data":3 }
},
"result": {
"item": "minecraft:stone",
"data": 5,
"count": 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before After
Before After

View file

@ -72,12 +72,14 @@ dist-check:
@echo "[1.14] Running dist checks ..." @echo "[1.14] Running dist checks ..."
@djs tasks.js dist-check @djs tasks.js dist-check
dist: sanatize dist-check clean-all init mod dist-files: clean-all init mod
@echo "[1.14] Distribution files ..." @echo "[1.14] Distribution files ..."
@mkdir -p dist @mkdir -p dist
@cp build/libs/$(MOD_JAR_PREFIX)* dist/ @cp build/libs/$(MOD_JAR_PREFIX)* dist/
@djs tasks.js dist @djs tasks.js dist
dist: sanatize dist-check dist-files
assets: assets:
@echo "[1.14] Running asset generators ..." @echo "[1.14] Running asset generators ..."
@djs tasks.js create-slab-assets @djs tasks.js create-slab-assets

View file

@ -19,21 +19,12 @@ version = "${version_engineersdecor}"
group = "wile.engineersdecor" group = "wile.engineersdecor"
archivesBaseName = "engineersdecor-${version_minecraft}" archivesBaseName = "engineersdecor-${version_minecraft}"
def signing = { -> def signingData = { ->
def sp = new Properties() def sp = new Properties()
if(file("signing.properties").exists()) file("signing.properties").withInputStream { sp.load(it) } if(file("signing.properties").exists()) file("signing.properties").withInputStream { sp.load(it) }
return sp return sp
}() }()
def git_version = { ->
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'log', '-1', '--format=%h'
standardOutput = stdout
}
return stdout.toString().trim()
}()
repositories { repositories {
maven { name = "Progwml6 maven"; url = "https://dvs1.progwml6.com/files/maven/" } // JEI files maven { name = "Progwml6 maven"; url = "https://dvs1.progwml6.com/files/maven/" } // JEI files
maven { name = "ModMaven"; url = "modmaven.k-4u.nl" } // JEI files, fallback maven { name = "ModMaven"; url = "modmaven.k-4u.nl" } // JEI files, fallback
@ -83,6 +74,11 @@ dependencies {
runtimeOnly fg.deobf("mezz.jei:jei-${version_jei}") runtimeOnly fg.deobf("mezz.jei:jei-${version_jei}")
} }
processResources {
outputs.upToDateWhen { false } // thx to @tterrag for this hint
doLast { file("${sourceSets.main.output.resourcesDir}/.gitversion").text = 'git log "-1" "--format=%h"'.execute().in.text.trim() }
}
jar { jar {
manifest { manifest {
attributes([ attributes([

View file

@ -5,4 +5,4 @@ version_minecraft=1.14.4
version_forge_minecraft=1.14.4-28.0.105 version_forge_minecraft=1.14.4-28.0.105
version_fml_mappings=20190719-1.14.3 version_fml_mappings=20190719-1.14.3
version_jei=1.14.4:6.0.0.10 version_jei=1.14.4:6.0.0.10
version_engineersdecor=1.0.12-b2 version_engineersdecor=1.0.12-b3

View file

@ -1,7 +1,7 @@
## Engineer's Decor (MC1.14.3) ## Engineer's Decor (MC1.14.4)
Mod sources for Minecraft version 1.14.3. Mod sources for Minecraft version 1.14.4.
- Description, credits, and features: Please see the readme in the repository root. - Description, credits, and features: Please see the readme in the repository root.
@ -11,6 +11,12 @@ Mod sources for Minecraft version 1.14.3.
## Version history ## Version history
~ v1.0.12-b3 [A] Crafting Table: Added recipe collision resolver,
also applies to crafting history refabrication.
[A] Crafting Table: Added rendering of placed items
on the top surface of the table.
[A] Waterlogging of non-full-blocks added.
- v1.0.12-b2 [U] Updated to Forge 1.14.4-28.0.105/20190719-1.14.3. - v1.0.12-b2 [U] Updated to Forge 1.14.4-28.0.105/20190719-1.14.3.
[A] Small Solar Panel added. [A] Small Solar Panel added.
[M] Items fall through the Steel Floor Grating like in 1.12.2 version. [M] Items fall through the Steel Floor Grating like in 1.12.2 version.

View file

@ -12,6 +12,7 @@
*/ */
package wile.engineersdecor; package wile.engineersdecor;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import wile.engineersdecor.blocks.*; import wile.engineersdecor.blocks.*;
import wile.engineersdecor.detail.ModAuxiliaries; import wile.engineersdecor.detail.ModAuxiliaries;
@ -32,6 +33,8 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;
import wile.engineersdecor.detail.ModTesrs;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Collections; import java.util.Collections;
@ -40,12 +43,11 @@ import javax.annotation.Nonnull;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class ModContent public class ModContent
{ {
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Blocks // Blocks
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
public static final BlockDecorFull CLINKER_BRICK_BLOCK = (BlockDecorFull)(new BlockDecorFull( public static final BlockDecor CLINKER_BRICK_BLOCK = (BlockDecor)(new BlockDecor(
BlockDecor.CFG_DEFAULT, BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE) Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "clinker_brick_block")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "clinker_brick_block"));
@ -68,7 +70,7 @@ public class ModContent
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorFull CLINKER_BRICK_STAINED_BLOCK = (BlockDecorFull)(new BlockDecorFull( public static final BlockDecor CLINKER_BRICK_STAINED_BLOCK = (BlockDecor)(new BlockDecor(
BlockDecor.CFG_DEFAULT, BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE) Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "clinker_brick_stained_block")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "clinker_brick_stained_block"));
@ -86,7 +88,7 @@ public class ModContent
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorFull SLAG_BRICK_BLOCK = (BlockDecorFull)(new BlockDecorFull( public static final BlockDecor SLAG_BRICK_BLOCK = (BlockDecor)(new BlockDecor(
BlockDecor.CFG_DEFAULT, BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE) Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "slag_brick_block")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "slag_brick_block"));
@ -109,7 +111,7 @@ public class ModContent
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorFull REBAR_CONCRETE_BLOCK = (BlockDecorFull)(new BlockDecorFull( public static final BlockDecor REBAR_CONCRETE_BLOCK = (BlockDecor)(new BlockDecor(
BlockDecor.CFG_DEFAULT, BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE) Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete"));
@ -131,13 +133,13 @@ public class ModContent
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete_wall")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete_wall"));
public static final BlockDecorHalfSlab HALFSLAB_REBARCONCRETE = (BlockDecorHalfSlab)(new BlockDecorHalfSlab( public static final BlockDecorHalfSlab HALFSLAB_REBARCONCRETE = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_DEFAULT, BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE) Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_rebar_concrete")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_rebar_concrete"));
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorFull REBAR_CONCRETE_TILE = (BlockDecorFull)(new BlockDecorFull( public static final BlockDecor REBAR_CONCRETE_TILE = (BlockDecor)(new BlockDecor(
BlockDecor.CFG_DEFAULT, BlockDecor.CFG_DEFAULT,
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE) Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete_tile")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete_tile"));
@ -184,7 +186,7 @@ public class ModContent
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
public static final BlockDecor TREATED_WOOD_TABLE = (BlockDecor)(new BlockDecor( public static final BlockDecor.WaterLoggable TREATED_WOOD_TABLE = (BlockDecor.WaterLoggable)(new BlockDecor.WaterLoggable(
BlockDecor.CFG_CUTOUT, BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD), Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(1,0,1, 15,15.9,15) ModAuxiliaries.getPixeledAABB(1,0,1, 15,15.9,15)
@ -196,25 +198,25 @@ public class ModContent
ModAuxiliaries.getPixeledAABB(4.1,0,4.1, 11.8,8.8,11.8) ModAuxiliaries.getPixeledAABB(4.1,0,4.1, 11.8,8.8,11.8)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_stool")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_stool"));
public static final BlockDecor TREATED_WOOD_SIDE_TABLE = (BlockDecor)(new BlockDecor( public static final BlockDecor.WaterLoggable TREATED_WOOD_SIDE_TABLE = (BlockDecor.WaterLoggable)(new BlockDecor.WaterLoggable(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD), Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(2,0,2, 14,15.9,14) ModAuxiliaries.getPixeledAABB(2,0,2, 14,15.9,14)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_side_table")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_side_table"));
public static final BlockDecorDirected TREATED_WOOD_WINDOWSILL = (BlockDecorDirected)(new BlockDecorDirected( public static final BlockDecorDirected.WaterLoggable TREATED_WOOD_WINDOWSILL = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_FACING_PLACEMENT, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_FACING_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD), Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(0.5,15,10.5, 15.5,16,16) ModAuxiliaries.getPixeledAABB(0.5,15,10.5, 15.5,16,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_windowsill")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_windowsill"));
public static final BlockDecorDirected INSET_LIGHT_IRON = (BlockDecorDirected)(new BlockDecorDirected( public static final BlockDecorDirected.WaterLoggable INSET_LIGHT_IRON = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).lightValue(15), Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).lightValue(15),
ModAuxiliaries.getPixeledAABB(5.2,5.2,15.7, 10.8,10.8,16.0) ModAuxiliaries.getPixeledAABB(5.2,5.2,15.7, 10.8,10.8,16.0)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "iron_inset_light")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "iron_inset_light"));
public static final BlockDecor STEEL_TABLE = (BlockDecor)(new BlockDecor( public static final BlockDecor.WaterLoggable STEEL_TABLE = (BlockDecor.WaterLoggable)(new BlockDecor.WaterLoggable(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD), Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16) ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
@ -292,43 +294,42 @@ public class ModContent
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorDirected SIGN_MODLOGO = (BlockDecorDirected)(new BlockDecorDirected( public static final BlockDecorDirected.WaterLoggable SIGN_MODLOGO = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1000f).sound(SoundType.WOOD).lightValue(1), Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1000f).sound(SoundType.WOOD).lightValue(1),
ModAuxiliaries.getPixeledAABB(0,0,15.6, 16,16,16.0) ModAuxiliaries.getPixeledAABB(0,0,15.6, 16,16,16.0)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_decor")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_decor"));
public static final BlockDecorDirected SIGN_HOTWIRE = (BlockDecorDirected)(new BlockDecorDirected( public static final BlockDecorDirected.WaterLoggable SIGN_HOTWIRE = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD), Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16) ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_hotwire")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_hotwire"));
public static final BlockDecorDirected SIGN_DANGER = (BlockDecorDirected)(new BlockDecorDirected( public static final BlockDecorDirected.WaterLoggable SIGN_DANGER = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD), Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16) ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_danger")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_danger"));
public static final BlockDecorDirected SIGN_DEFENSE = (BlockDecorDirected)(new BlockDecorDirected( public static final BlockDecorDirected.WaterLoggable SIGN_DEFENSE = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD), Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16) ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_defense")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_defense"));
public static final BlockDecorDirected SIGN_FACTORY_AREA = (BlockDecorDirected)(new BlockDecorDirected( public static final BlockDecorDirected.WaterLoggable SIGN_FACTORY_AREA = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD), Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16) ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_factoryarea")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_factoryarea"));
public static final BlockDecorDirected SIGN_EXIT = (BlockDecorDirected)(new BlockDecorDirected( public static final BlockDecorDirected.WaterLoggable SIGN_EXIT = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD), Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
ModAuxiliaries.getPixeledAABB(3,7,15.6, 13,13,16) ModAuxiliaries.getPixeledAABB(3,7,15.6, 13,13,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_exit")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_exit"));
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
public static final BlockDecorCraftingTable TREATED_WOOD_CRAFTING_TABLE = (BlockDecorCraftingTable)(new BlockDecorCraftingTable( public static final BlockDecorCraftingTable TREATED_WOOD_CRAFTING_TABLE = (BlockDecorCraftingTable)(new BlockDecorCraftingTable(
@ -410,32 +411,32 @@ public class ModContent
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_concrete")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_concrete"));
public static final BlockDecorHalfSlab HALFSLAB_TREATEDWOOD = (BlockDecorHalfSlab)(new BlockDecorHalfSlab( public static final BlockDecorHalfSlab HALFSLAB_TREATEDWOOD = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HARD_IE_DEPENDENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 4f).sound(SoundType.WOOD) Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 4f).sound(SoundType.WOOD)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_treated_wood")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_treated_wood"));
public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALIRON = (BlockDecorHalfSlab)(new BlockDecorHalfSlab( public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALIRON = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HARD_IE_DEPENDENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL) Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_iron")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_iron"));
public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALSTEEL = (BlockDecorHalfSlab)(new BlockDecorHalfSlab( public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALSTEEL = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HARD_IE_DEPENDENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL) Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_steel")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_steel"));
public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALCOPPER = (BlockDecorHalfSlab)(new BlockDecorHalfSlab( public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALCOPPER = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HARD_IE_DEPENDENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL) Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_copper")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_copper"));
public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALGOLD = (BlockDecorHalfSlab)(new BlockDecorHalfSlab( public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALGOLD = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HARD_IE_DEPENDENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL) Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_gold")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_gold"));
public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALALUMINIUM = (BlockDecorHalfSlab)(new BlockDecorHalfSlab( public static final BlockDecorHalfSlab HALFSLAB_SHEETMETALALUMINIUM = (BlockDecorHalfSlab)(new BlockDecorHalfSlab(
BlockDecor.CFG_CUTOUT, BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HARD_IE_DEPENDENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL) Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 10f).sound(SoundType.METAL)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_aluminum")); )).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_aluminum"));
@ -701,4 +702,9 @@ public class ModContent
ScreenManager.registerFactory(CT_WASTE_INCINERATOR, BlockDecorWasteIncinerator.BGui::new); ScreenManager.registerFactory(CT_WASTE_INCINERATOR, BlockDecorWasteIncinerator.BGui::new);
} }
@OnlyIn(Dist.CLIENT)
public static final void registerTileEntityRenderers(final FMLClientSetupEvent event)
{
ClientRegistry.bindTileEntitySpecialRenderer(BlockDecorCraftingTable.BTileEntity.class, new ModTesrs.TesrDecorCraftingTable());
}
} }

View file

@ -1,16 +1,15 @@
package wile.engineersdecor; package wile.engineersdecor;
import wile.engineersdecor.detail.ModConfig; import wile.engineersdecor.detail.ModConfig;
import wile.engineersdecor.detail.OptionalRecipeCondition;
import wile.engineersdecor.detail.Networking; import wile.engineersdecor.detail.Networking;
import wile.engineersdecor.blocks.*; import wile.engineersdecor.blocks.*;
import wile.engineersdecor.detail.OptionalRecipeCondition.Serializer;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@ -33,7 +32,6 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import wile.engineersdecor.detail.OptionalRecipeCondition.Serializer;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -70,7 +68,7 @@ public class ModEngineersDecor
} }
private void onClientSetup(final FMLClientSetupEvent event) private void onClientSetup(final FMLClientSetupEvent event)
{ ModContent.registerContainerGuis(event); } { ModContent.registerContainerGuis(event); ModContent.registerTileEntityRenderers(event); }
private void onSendImc(final InterModEnqueueEvent event) private void onSendImc(final InterModEnqueueEvent event)
{} {}
@ -78,12 +76,8 @@ public class ModEngineersDecor
private void onRecvImc(final InterModProcessEvent event) private void onRecvImc(final InterModProcessEvent event)
{} {}
@SubscribeEvent
public void onServerStarting(FMLServerStartingEvent event)
{}
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
public static class RegistryEvents public static class ForgeEvents
{ {
@SubscribeEvent @SubscribeEvent
public static void onBlocksRegistry(final RegistryEvent.Register<Block> event) public static void onBlocksRegistry(final RegistryEvent.Register<Block> event)
@ -104,6 +98,32 @@ public class ModEngineersDecor
@SubscribeEvent @SubscribeEvent
public static void onRegisterContainerTypes(final RegistryEvent.Register<ContainerType<?>> event) public static void onRegisterContainerTypes(final RegistryEvent.Register<ContainerType<?>> event)
{ ModContent.registerContainers(event); } { ModContent.registerContainers(event); }
// @SubscribeEvent
public static void onServerStarting(FMLServerStartingEvent event)
{}
// @SubscribeEvent
public static void onConfigLoad(net.minecraftforge.fml.config.ModConfig.Loading configEvent)
{
try {
ModEngineersDecor.logger().info("Loaded config file {}", configEvent.getConfig().getFileName());
ModConfig.apply();
} catch(Throwable e) {
ModEngineersDecor.logger().error("Failed to load config: " + e.getMessage());
}
}
@SubscribeEvent
public static void onConfigFileChange(net.minecraftforge.fml.config.ModConfig.ConfigReloading configEvent)
{
try {
ModEngineersDecor.logger().info("Config file changed {}", configEvent.getConfig().getFileName());
ModConfig.apply();
} catch(Throwable e) {
ModEngineersDecor.logger().error("Failed to load changed config: " + e.getMessage());
}
}
} }
// //

View file

@ -12,10 +12,16 @@
*/ */
package wile.engineersdecor.blocks; package wile.engineersdecor.blocks;
import net.minecraft.block.IWaterLoggable;
import net.minecraft.state.StateContainer;
import wile.engineersdecor.detail.ModAuxiliaries; import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.IFluidState; import net.minecraft.fluid.IFluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.world.IWorld;
import net.minecraft.world.Explosion; import net.minecraft.world.Explosion;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
@ -26,6 +32,7 @@ import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.material.PushReaction; import net.minecraft.block.material.PushReaction;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.storage.loot.LootContext; import net.minecraft.world.storage.loot.LootContext;
@ -54,18 +61,20 @@ public class BlockDecor extends Block implements IDecorBlock
public static final long CFG_REDSTONE_CONTROLLED = 0x0000000000020000L; // Denotes if a component has somehow a redstone control input public static final long CFG_REDSTONE_CONTROLLED = 0x0000000000020000L; // Denotes if a component has somehow a redstone control input
public static final long CFG_ANALOG = 0x0000000000040000L; // Denotes if a component has analog behaviour public static final long CFG_ANALOG = 0x0000000000040000L; // Denotes if a component has analog behaviour
public static final long CFG_HARD_IE_DEPENDENT = 0x8000000000000000L; // The block is implicitly opt'ed out if IE is not installed public static final long CFG_HARD_IE_DEPENDENT = 0x8000000000000000L; // The block is implicitly opt'ed out if IE is not installed
public static final long CFG_WATERLOGGABLE = 0x4000000000000000L; // The derived block extends IWaterLoggable
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public final long config; public final long config;
public final VoxelShape vshape; public final VoxelShape vshape;
public BlockDecor(long config, Block.Properties properties) public BlockDecor(long conf, Block.Properties properties)
{ this(config, properties, ModAuxiliaries.getPixeledAABB(0, 0, 0, 16, 16,16 )); } { this(conf, properties, ModAuxiliaries.getPixeledAABB(0, 0, 0, 16, 16,16 )); }
public BlockDecor(long config, Block.Properties properties, AxisAlignedBB aabb) public BlockDecor(long conf, Block.Properties properties, AxisAlignedBB aabb)
{ super(properties); this.config = config; this.vshape = VoxelShapes.create(aabb); } { super(properties); config = conf; vshape = VoxelShapes.create(aabb); }
public BlockDecor(long config, Block.Properties properties, VoxelShape voxel_shape) public BlockDecor(long conf, Block.Properties properties, VoxelShape voxel_shape)
{ super(properties); this.config = config; this.vshape = voxel_shape; } { super(properties); config = conf; vshape = voxel_shape; }
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@ -87,6 +96,18 @@ public class BlockDecor extends Block implements IDecorBlock
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext) public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
{ return vshape; } { return vshape; }
@Override
@Nullable
public BlockState getStateForPlacement(BlockItemUseContext context)
{
BlockState state = super.getStateForPlacement(context);
if((config & CFG_WATERLOGGABLE)!=0) {
IFluidState fs = context.getWorld().getFluidState(context.getPos());
state = state.with(WATERLOGGED,fs.getFluid()==Fluids.WATER);
}
return state;
}
@Override @Override
public boolean canSpawnInBlock() public boolean canSpawnInBlock()
{ return false; } { return false; }
@ -130,4 +151,52 @@ public class BlockDecor extends Block implements IDecorBlock
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder)
{ return Collections.singletonList(ItemStack.EMPTY); } // { return Collections.singletonList(new ItemStack(this.asItem())); } // { return Collections.singletonList(ItemStack.EMPTY); } // { return Collections.singletonList(new ItemStack(this.asItem())); } //
@Override
public boolean propagatesSkylightDown(BlockState state, IBlockReader reader, BlockPos pos)
{
if((config & CFG_WATERLOGGABLE)!=0) {
if(state.get(WATERLOGGED)) return false;
}
return super.propagatesSkylightDown(state, reader, pos);
}
@Override
@SuppressWarnings("deprecation")
public IFluidState getFluidState(BlockState state)
{
if((config & CFG_WATERLOGGABLE)!=0) {
return state.get(WATERLOGGED) ? Fluids.WATER.getStillFluidState(false) : super.getFluidState(state);
}
return super.getFluidState(state);
}
@Override
@SuppressWarnings("deprecation")
public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState facingState, IWorld world, BlockPos pos, BlockPos facingPos)
{
if((config & CFG_WATERLOGGABLE)!=0) {
if(state.get(WATERLOGGED)) world.getPendingFluidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
}
return state;
}
/**
* Water loggable version of the basic block.
*/
public static class WaterLoggable extends BlockDecor implements IWaterLoggable
{
public WaterLoggable(long config, Block.Properties properties)
{ super(config|CFG_WATERLOGGABLE, properties); }
public WaterLoggable(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(config|CFG_WATERLOGGABLE, properties, aabb); }
public WaterLoggable(long config, Block.Properties properties, VoxelShape voxel_shape)
{ super(config|CFG_WATERLOGGABLE, properties, voxel_shape); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }
}
} }

View file

@ -28,7 +28,7 @@ import java.util.List;
import java.util.Random; import java.util.Random;
public class BlockDecorChair extends BlockDecorDirected public class BlockDecorChair extends BlockDecorDirected.WaterLoggable
{ {
private static boolean sitting_enabled = true; private static boolean sitting_enabled = true;
private static double sitting_probability = 0.1; private static double sitting_probability = 0.1;

View file

@ -11,16 +11,10 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent; import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor; import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.Networking; import wile.engineersdecor.detail.Networking;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.client.gui.widget.button.ImageButton;
import net.minecraft.inventory.container.*; import net.minecraft.inventory.container.*;
import net.minecraft.item.Items;
import net.minecraft.item.crafting.ICraftingRecipe;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.network.play.server.SSetSlotPacket; import net.minecraft.network.play.server.SSetSlotPacket;
import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.network.NetworkManager;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.world.*; import net.minecraft.world.*;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -31,7 +25,11 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.ICraftingRecipe;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.IRecipe;
import net.minecraft.inventory.*; import net.minecraft.inventory.*;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
@ -40,8 +38,12 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.client.gui.widget.button.ImageButton;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
@ -51,9 +53,10 @@ import com.mojang.blaze3d.platform.GlStateManager;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
public class BlockDecorCraftingTable extends BlockDecorDirected public class BlockDecorCraftingTable extends BlockDecorDirected.WaterLoggable
{ {
public static boolean with_assist = true; public static boolean with_assist = true;
public static boolean with_assist_direct_history_refab = false; public static boolean with_assist_direct_history_refab = false;
@ -68,7 +71,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
} }
public BlockDecorCraftingTable(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB) public BlockDecorCraftingTable(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); } { super(config|CFG_WATERLOGGABLE, builder, unrotatedAABB); }
@Override @Override
public boolean hasTileEntity(BlockState state) public boolean hasTileEntity(BlockState state)
@ -168,20 +171,33 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
// TileEntity ------------------------------------------------------------------------------ // TileEntity ------------------------------------------------------------------------------
@Override @Override
public void read(CompoundNBT compound) public void read(CompoundNBT nbt)
{ super.read(compound); readnbt(compound); } { super.read(nbt); readnbt(nbt); }
@Override @Override
public CompoundNBT write(CompoundNBT compound) public CompoundNBT write(CompoundNBT nbt)
{ super.write(compound); writenbt(compound); return compound; } { super.write(nbt); writenbt(nbt); return nbt; }
@Override @Override
public CompoundNBT getUpdateTag() public CompoundNBT getUpdateTag()
{ CompoundNBT nbt = super.getUpdateTag(); writenbt(nbt); return nbt; } { CompoundNBT nbt = super.getUpdateTag(); writenbt(nbt); return nbt; }
@Override @Override
public void onLoad() @Nullable
{} public SUpdateTileEntityPacket getUpdatePacket()
{ return new SUpdateTileEntityPacket(pos, 1, getUpdateTag()); }
@Override
public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) // on client
{ super.read(pkt.getNbtCompound()); readnbt(pkt.getNbtCompound()); super.onDataPacket(net, pkt); }
@Override
public void handleUpdateTag(CompoundNBT tag) // on client
{ read(tag); }
@OnlyIn(Dist.CLIENT)
public double getMaxRenderDistanceSquared()
{ return 400; }
// INameable --------------------------------------------------------------------------- // INameable ---------------------------------------------------------------------------
@ -251,7 +267,13 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
@Override @Override
public void closeInventory(PlayerEntity player) public void closeInventory(PlayerEntity player)
{ this.markDirty(); } {
markDirty();
if(world instanceof World) {
BlockState state = world.getBlockState(pos);
world.notifyBlockUpdate(pos, state, state, 1|2);
}
}
@Override @Override
public boolean isItemValidForSlot(int index, ItemStack stack) public boolean isItemValidForSlot(int index, ItemStack stack)
@ -356,6 +378,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
private final CraftingHistory history_; private final CraftingHistory history_;
private final BInventoryCrafting matrix_; private final BInventoryCrafting matrix_;
private final CraftResultInventory result_; private final CraftResultInventory result_;
private boolean has_recipe_collision_;
public BContainer(int cid, PlayerInventory pinv) public BContainer(int cid, PlayerInventory pinv)
{ this(cid, pinv, new Inventory(BTileEntity.NUM_OF_SLOTS), IWorldPosCallable.DUMMY); } { this(cid, pinv, new Inventory(BTileEntity.NUM_OF_SLOTS), IWorldPosCallable.DUMMY); }
@ -423,15 +446,22 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
//craft(windowId, world, player_, matrix_, result_); //craft(windowId, world, player_, matrix_, result_);
ServerPlayerEntity player = (ServerPlayerEntity) player_; ServerPlayerEntity player = (ServerPlayerEntity) player_;
ItemStack stack = ItemStack.EMPTY; ItemStack stack = ItemStack.EMPTY;
Optional<ICraftingRecipe> optional = world.getServer().getRecipeManager().getRecipe(IRecipeType.CRAFTING, matrix_, world); List<ICraftingRecipe> recipes = world.getServer().getRecipeManager().getRecipes(IRecipeType.CRAFTING, matrix_, world);
if(optional.isPresent()) { has_recipe_collision_ = false;
ICraftingRecipe icraftingrecipe = optional.get(); if(recipes.size() > 0) {
if(result_.canUseRecipe(world, player, icraftingrecipe)) { ICraftingRecipe recipe = recipes.get(0);
stack = icraftingrecipe.getCraftingResult(matrix_); IRecipe<?> currently_used = result_.getRecipeUsed();
has_recipe_collision_ = (recipes.size() > 1);
if((recipes.size() > 1) && (currently_used instanceof ICraftingRecipe) && (recipes.contains(currently_used))) {
recipe = (ICraftingRecipe)currently_used;
}
if(result_.canUseRecipe(world, player, recipe)) {
stack = recipe.getCraftingResult(matrix_);
} }
} }
result_.setInventorySlotContents(0, stack); result_.setInventorySlotContents(0, stack);
player.connection.sendPacket(new SSetSlotPacket(windowId, 0, stack)); player.connection.sendPacket(new SSetSlotPacket(windowId, 0, stack));
syncProperties(player);
} catch(Throwable exc) { } catch(Throwable exc) {
ModEngineersDecor.logger().error("Recipe failed:", exc); ModEngineersDecor.logger().error("Recipe failed:", exc);
} }
@ -492,6 +522,39 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
// private aux methods --------------------------------------------------------------------- // private aux methods ---------------------------------------------------------------------
public boolean has_recipe_collision()
{ return has_recipe_collision_; }
public void select_next_collision_recipe(IInventory inv)
{
wpc_.consume((world,pos)->{
if(world.isRemote) return;
try {
ServerPlayerEntity player = (ServerPlayerEntity) player_;
final List<ICraftingRecipe> matching_recipes = world.getServer().getRecipeManager().getRecipes(IRecipeType.CRAFTING, matrix_, world);
if(matching_recipes.size() < 2) return; // nothing to change
IRecipe<?> currently_used = result_.getRecipeUsed();
List<ICraftingRecipe> usable_recipes = matching_recipes.stream()
.filter((r)->result_.canUseRecipe(world,player,r))
.sorted((a,b)->Integer.compare(a.getId().hashCode(), b.getId().hashCode()))
.collect(Collectors.toList());
for(int i=0; i<usable_recipes.size(); ++i) {
if(usable_recipes.get(i) == currently_used) {
if(++i >= usable_recipes.size()) i=0;
currently_used = usable_recipes.get(i);
ItemStack stack = ((ICraftingRecipe)currently_used).getCraftingResult(matrix_);
result_.setInventorySlotContents(0, stack);
result_.setRecipeUsed(currently_used);
break;
}
}
onCraftMatrixChanged(inv);
} catch(Throwable exc) {
ModEngineersDecor.logger().error("Recipe failed:", exc);
}
});
}
private boolean itemstack_recipe_match(ItemStack grid_stack, ItemStack history_stack) private boolean itemstack_recipe_match(ItemStack grid_stack, ItemStack history_stack)
{ {
if(history_.current_recipe()!=null) { if(history_.current_recipe()!=null) {
@ -680,6 +743,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
private EnumRefabPlacement place_refab_stacks(IInventory inventory, final int slot_begin, final int slot_end) private EnumRefabPlacement place_refab_stacks(IInventory inventory, final int slot_begin, final int slot_end)
{ {
List<ItemStack> to_fill = crafting_slot_stacks_to_add(); List<ItemStack> to_fill = crafting_slot_stacks_to_add();
if(history_.current_recipe() != null) result_.setRecipeUsed(history_.current_recipe());
boolean slots_changed = false; boolean slots_changed = false;
boolean missing_item = false; boolean missing_item = false;
int num_slots_placed = 0; int num_slots_placed = 0;
@ -719,6 +783,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
private EnumRefabPlacement distribute_stack(IInventory inventory, final int slotno) private EnumRefabPlacement distribute_stack(IInventory inventory, final int slotno)
{ {
List<ItemStack> to_refab = crafting_slot_stacks_to_add(); List<ItemStack> to_refab = crafting_slot_stacks_to_add();
if(history_.current_recipe() != null) result_.setRecipeUsed(history_.current_recipe());
ItemStack to_distribute = inventory.getStackInSlot(slotno).copy(); ItemStack to_distribute = inventory.getStackInSlot(slotno).copy();
if(to_distribute.isEmpty()) return EnumRefabPlacement.UNCHANGED; if(to_distribute.isEmpty()) return EnumRefabPlacement.UNCHANGED;
int matching_grid_stack_sizes[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1}; int matching_grid_stack_sizes[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1};
@ -796,9 +861,8 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
public void onServerPacketReceived(int windowId, CompoundNBT nbt) public void onServerPacketReceived(int windowId, CompoundNBT nbt)
{ {
if(nbt.contains("history")) { if(nbt.contains("history")) history_.read(nbt.getCompound("history"));
history_.read(nbt.getCompound("history")); if(nbt.contains("hascollision")) has_recipe_collision_ = nbt.getBoolean("hascollision");
}
} }
public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt) public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt)
@ -871,6 +935,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
if(stat != EnumRefabPlacement.UNCHANGED) { player_inventory_changed = true; changed = true; } if(stat != EnumRefabPlacement.UNCHANGED) { player_inventory_changed = true; changed = true; }
} }
} break; } break;
case BGui.BUTTON_NEXT_COLLISION_RECIPE: {
select_next_collision_recipe(inventory_);
} break;
} }
} }
if(changed) inventory_.markDirty(); if(changed) inventory_.markDirty();
@ -895,6 +962,14 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
} }
final CompoundNBT nbt = new CompoundNBT(); final CompoundNBT nbt = new CompoundNBT();
nbt.put("history", hist_nbt); nbt.put("history", hist_nbt);
nbt.putBoolean("hascollision", has_recipe_collision_);
Networking.PacketContainerSyncServerToClient.sendToPlayer(player, windowId, nbt);
}
private void syncProperties(PlayerEntity player)
{
final CompoundNBT nbt = new CompoundNBT();
nbt.putBoolean("hascollision", has_recipe_collision_);
Networking.PacketContainerSyncServerToClient.sendToPlayer(player, windowId, nbt); Networking.PacketContainerSyncServerToClient.sendToPlayer(player, windowId, nbt);
} }
} }
@ -913,6 +988,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
protected static final String BUTTON_TO_STORAGE = "to-storage"; protected static final String BUTTON_TO_STORAGE = "to-storage";
protected static final String BUTTON_FROM_PLAYER = "from-player"; protected static final String BUTTON_FROM_PLAYER = "from-player";
protected static final String BUTTON_TO_PLAYER = "to-player"; protected static final String BUTTON_TO_PLAYER = "to-player";
protected static final String BUTTON_NEXT_COLLISION_RECIPE = "next-recipe";
protected static final String ACTION_PLACE_CURRENT_HISTORY_SEL = "place-refab"; protected static final String ACTION_PLACE_CURRENT_HISTORY_SEL = "place-refab";
protected static final String ACTION_PLACE_SHIFTCLICKED_STACK = "place-stack"; protected static final String ACTION_PLACE_SHIFTCLICKED_STACK = "place-stack";
protected static final ResourceLocation BACKGROUND = new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/treated_wood_crafting_table.png"); protected static final ResourceLocation BACKGROUND = new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/treated_wood_crafting_table.png");
@ -936,6 +1012,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
buttons.add(addButton(new ImageButton(x0+158,y0+44, 12,12, 194,44, 12, BACKGROUND, (bt)->action(BUTTON_NEXT)))); buttons.add(addButton(new ImageButton(x0+158,y0+44, 12,12, 194,44, 12, BACKGROUND, (bt)->action(BUTTON_NEXT))));
buttons.add(addButton(new ImageButton(x0+158,y0+30, 12,12, 180,30, 12, BACKGROUND, (bt)->action(BUTTON_PREV)))); buttons.add(addButton(new ImageButton(x0+158,y0+30, 12,12, 180,30, 12, BACKGROUND, (bt)->action(BUTTON_PREV))));
buttons.add(addButton(new ImageButton(x0+158,y0+58, 12,12, 194,8, 12, BACKGROUND, (bt)->action(BUTTON_CLEAR_GRID)))); buttons.add(addButton(new ImageButton(x0+158,y0+58, 12,12, 194,8, 12, BACKGROUND, (bt)->action(BUTTON_CLEAR_GRID))));
buttons.add(addButton(new ImageButton(x0+132,y0+18, 20,10, 183,95, 12, BACKGROUND, (bt)->action(BUTTON_NEXT_COLLISION_RECIPE))));
if(with_assist_quickmove_buttons) { if(with_assist_quickmove_buttons) {
buttons.add(addButton(new ImageButton(x0+49, y0+34, 9,17, 219,34, 17, BACKGROUND, (bt)->action(BUTTON_FROM_STORAGE)))); buttons.add(addButton(new ImageButton(x0+49, y0+34, 9,17, 219,34, 17, BACKGROUND, (bt)->action(BUTTON_FROM_STORAGE))));
buttons.add(addButton(new ImageButton(x0+49, y0+52, 9,17, 208,16, 17, BACKGROUND, (bt)->action(BUTTON_TO_STORAGE)))); buttons.add(addButton(new ImageButton(x0+49, y0+52, 9,17, 208,16, 17, BACKGROUND, (bt)->action(BUTTON_TO_STORAGE))));
@ -948,6 +1025,11 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
@Override @Override
public void render(int mouseX, int mouseY, float partialTicks) public void render(int mouseX, int mouseY, float partialTicks)
{ {
if(with_assist) {
boolean is_collision = getContainer().has_recipe_collision();
buttons.get(3).visible = is_collision;
buttons.get(3).active = is_collision;
}
renderBackground(); renderBackground();
super.render(mouseX, mouseY, partialTicks); super.render(mouseX, mouseY, partialTicks);
renderHoveredToolTip(mouseX, mouseY); renderHoveredToolTip(mouseX, mouseY);

View file

@ -8,6 +8,7 @@
*/ */
package wile.engineersdecor.blocks; package wile.engineersdecor.blocks;
import net.minecraft.block.IWaterLoggable;
import wile.engineersdecor.detail.ModAuxiliaries; import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.state.StateContainer; import net.minecraft.state.StateContainer;
@ -77,7 +78,7 @@ public class BlockDecorDirected extends BlockDecor
@Override @Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(FACING); } { super.fillStateContainer(builder); builder.add(FACING); }
@Override @Override
@Nullable @Nullable
@ -98,7 +99,20 @@ public class BlockDecorDirected extends BlockDecor
} }
if((config & CFG_OPPOSITE_PLACEMENT)!=0) facing = facing.getOpposite(); if((config & CFG_OPPOSITE_PLACEMENT)!=0) facing = facing.getOpposite();
if(((config & CFG_FLIP_PLACEMENT_SHIFTCLICK) != 0) && (context.getPlayer().isSneaking())) facing = facing.getOpposite(); if(((config & CFG_FLIP_PLACEMENT_SHIFTCLICK) != 0) && (context.getPlayer().isSneaking())) facing = facing.getOpposite();
return getDefaultState().with(FACING, facing); return super.getStateForPlacement(context).with(FACING, facing);
}
/**
* Water loggable version of directed blocks.
*/
public static class WaterLoggable extends BlockDecorDirected implements IWaterLoggable
{
public WaterLoggable(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(config|CFG_WATERLOGGABLE, properties, aabb); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }
} }
} }

View file

@ -10,6 +10,7 @@
package wile.engineersdecor.blocks; package wile.engineersdecor.blocks;
import net.minecraft.block.HorizontalBlock; import net.minecraft.block.HorizontalBlock;
import net.minecraft.block.IWaterLoggable;
import net.minecraft.util.Mirror; import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation; import net.minecraft.util.Rotation;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
@ -80,7 +81,7 @@ public class BlockDecorDirectedHorizontal extends BlockDecor
@Override @Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(HORIZONTAL_FACING); } { super.fillStateContainer(builder); builder.add(HORIZONTAL_FACING); }
@Override @Override
@Nullable @Nullable
@ -96,7 +97,7 @@ public class BlockDecorDirectedHorizontal extends BlockDecor
} }
if((config & CFG_OPPOSITE_PLACEMENT)!=0) facing = facing.getOpposite(); if((config & CFG_OPPOSITE_PLACEMENT)!=0) facing = facing.getOpposite();
if(((config & CFG_FLIP_PLACEMENT_SHIFTCLICK) != 0) && (context.getPlayer().isSneaking())) facing = facing.getOpposite(); if(((config & CFG_FLIP_PLACEMENT_SHIFTCLICK) != 0) && (context.getPlayer().isSneaking())) facing = facing.getOpposite();
return getDefaultState().with(HORIZONTAL_FACING, facing); return super.getStateForPlacement(context).with(HORIZONTAL_FACING, facing);
} }
@Override @Override
@ -109,4 +110,17 @@ public class BlockDecorDirectedHorizontal extends BlockDecor
public BlockState mirror(BlockState state, Mirror mirrorIn) public BlockState mirror(BlockState state, Mirror mirrorIn)
{ return state.rotate(mirrorIn.toRotation(state.get(HORIZONTAL_FACING))); } { return state.rotate(mirrorIn.toRotation(state.get(HORIZONTAL_FACING))); }
/**
* Water loggable version of directed blocks.
*/
public static class WaterLoggable extends BlockDecorDirectedHorizontal implements IWaterLoggable
{
public WaterLoggable(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(config|CFG_WATERLOGGABLE, properties, aabb); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }
}
} }

View file

@ -73,7 +73,7 @@ public class BlockDecorDropper extends BlockDecorDirected
@Override @Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(FACING, OPEN); } { super.fillStateContainer(builder); builder.add(OPEN); }
@Override @Override
@Nullable @Nullable

View file

@ -22,10 +22,10 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class BlockDecorFloorGrating extends BlockDecor public class BlockDecorFloorGrating extends BlockDecor.WaterLoggable
{ {
public BlockDecorFloorGrating(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB) public BlockDecorFloorGrating(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder); } { super(config|CFG_WATERLOGGABLE, builder); }
@Override @Override
public boolean propagatesSkylightDown(BlockState state, IBlockReader reader, BlockPos pos) public boolean propagatesSkylightDown(BlockState state, IBlockReader reader, BlockPos pos)

View file

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

View file

@ -84,7 +84,7 @@ public class BlockDecorFurnace extends BlockDecorDirected
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockItemUseContext context) public BlockState getStateForPlacement(BlockItemUseContext context)
{ return getDefaultState().with(FACING, context.getPlacementHorizontalFacing().getOpposite()).with(LIT, false); } { return super.getStateForPlacement(context).with(FACING, context.getPlacementHorizontalFacing().getOpposite()).with(LIT, false); }
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")

View file

@ -38,7 +38,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
public class BlockDecorHalfSlab extends BlockDecor public class BlockDecorHalfSlab extends BlockDecor implements IWaterLoggable
{ {
public static final IntegerProperty PARTS = IntegerProperty.create("parts", 0, 14); public static final IntegerProperty PARTS = IntegerProperty.create("parts", 0, 14);
@ -61,12 +61,10 @@ public class BlockDecorHalfSlab extends BlockDecor
VoxelShapes.create(new AxisAlignedBB(0,0,0,1,1,1)) // <- with 4bit fill VoxelShapes.create(new AxisAlignedBB(0,0,0,1,1,1)) // <- with 4bit fill
}; };
protected static final int num_slabs_contained_in_parts_[] = { protected static final int num_slabs_contained_in_parts_[] = { 1,2,3,4,5,6,7,8,7,6,5,4,3,2,1 ,0x1 }; // <- with 4bit fill
1,2,3,4,5,6,7,8,7,6,5,4,3,2,1 ,0x1 // <- with 4bit fill
};
public BlockDecorHalfSlab(long config, Block.Properties builder) public BlockDecorHalfSlab(long config, Block.Properties builder)
{ super(config, builder); } { super(config|CFG_WATERLOGGABLE, builder); }
protected boolean is_cube(BlockState state) protected boolean is_cube(BlockState state)
{ return state.get(PARTS) == 0x07; } { return state.get(PARTS) == 0x07; }
@ -105,7 +103,7 @@ public class BlockDecorHalfSlab extends BlockDecor
@Override @Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(PARTS); } { super.fillStateContainer(builder); builder.add(PARTS, WATERLOGGED); }
@Override @Override
@Nullable @Nullable
@ -113,7 +111,7 @@ public class BlockDecorHalfSlab extends BlockDecor
{ {
final Direction facing = context.getFace(); final Direction facing = context.getFace();
double y = context.getHitVec().getY(); double y = context.getHitVec().getY();
return getDefaultState().with(PARTS, ((facing==Direction.UP) || ((facing!=Direction.DOWN) && (y < 0.6))) ? 0 : 14); return super.getStateForPlacement(context).with(PARTS, ((facing==Direction.UP) || ((facing!=Direction.DOWN) && (y < 0.6))) ? 0 : 14);
} }
@Override @Override

View file

@ -9,6 +9,7 @@
*/ */
package wile.engineersdecor.blocks; package wile.engineersdecor.blocks;
import net.minecraft.block.IWaterLoggable;
import wile.engineersdecor.ModContent; import wile.engineersdecor.ModContent;
import wile.engineersdecor.detail.ModAuxiliaries; import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
@ -35,7 +36,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
public class BlockDecorHorizontalSupport extends BlockDecor public class BlockDecorHorizontalSupport extends BlockDecor implements IWaterLoggable
{ {
public static final BooleanProperty EASTWEST = BooleanProperty.create("eastwest"); public static final BooleanProperty EASTWEST = BooleanProperty.create("eastwest");
public static final BooleanProperty LEFTBEAM = BooleanProperty.create("leftbeam"); public static final BooleanProperty LEFTBEAM = BooleanProperty.create("leftbeam");
@ -45,7 +46,7 @@ public class BlockDecorHorizontalSupport extends BlockDecor
public BlockDecorHorizontalSupport(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB) public BlockDecorHorizontalSupport(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ {
super(config|CFG_HORIZIONTAL, builder); super(config|CFG_HORIZIONTAL|CFG_WATERLOGGABLE, builder);
AABBs = new ArrayList<VoxelShape>(Arrays.asList( AABBs = new ArrayList<VoxelShape>(Arrays.asList(
// Effective bounding box // Effective bounding box
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB.grow(2.0/16, 0, 0), Direction.NORTH, true)), VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB.grow(2.0/16, 0, 0), Direction.NORTH, true)),
@ -80,12 +81,12 @@ public class BlockDecorHorizontalSupport extends BlockDecor
@Override @Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(EASTWEST, RIGHTBEAM, LEFTBEAM, DOWNCONNECT); } { super.fillStateContainer(builder); builder.add(EASTWEST, RIGHTBEAM, LEFTBEAM, DOWNCONNECT, WATERLOGGED); }
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockItemUseContext context) public BlockState getStateForPlacement(BlockItemUseContext context)
{ return temp_block_update_until_better(getDefaultState().with(EASTWEST, context.getPlacementHorizontalFacing().getAxis()==Direction.Axis.X), context.getWorld(), context.getPos()); } { return temp_block_update_until_better(super.getStateForPlacement(context).with(EASTWEST, context.getPlacementHorizontalFacing().getAxis()==Direction.Axis.X), context.getWorld(), context.getPos()); }
private BlockState temp_block_update_until_better(BlockState state, IWorld world, BlockPos pos) private BlockState temp_block_update_until_better(BlockState state, IWorld world, BlockPos pos)
{ {

View file

@ -70,7 +70,6 @@ public class BlockDecorMineralSmelter extends BlockDecorDirectedHorizontal
public BlockState getStateForPlacement(BlockItemUseContext context) public BlockState getStateForPlacement(BlockItemUseContext context)
{ return super.getStateForPlacement(context).with(PHASE, 0); } { return super.getStateForPlacement(context).with(PHASE, 0); }
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean hasComparatorInputOverride(BlockState state) public boolean hasComparatorInputOverride(BlockState state)

View file

@ -9,6 +9,7 @@
*/ */
package wile.engineersdecor.blocks; package wile.engineersdecor.blocks;
import net.minecraft.block.IWaterLoggable;
import wile.engineersdecor.ModContent; import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor; import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.state.BooleanProperty; import net.minecraft.state.BooleanProperty;
@ -36,7 +37,7 @@ import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class BlockDecorPipeValve extends BlockDecorDirected public class BlockDecorPipeValve extends BlockDecorDirected implements IWaterLoggable
{ {
public static final BooleanProperty RS_CN_N = BooleanProperty.create("rs_n"); public static final BooleanProperty RS_CN_N = BooleanProperty.create("rs_n");
public static final BooleanProperty RS_CN_S = BooleanProperty.create("rs_s"); public static final BooleanProperty RS_CN_S = BooleanProperty.create("rs_s");
@ -53,7 +54,7 @@ public class BlockDecorPipeValve extends BlockDecorDirected
} }
public BlockDecorPipeValve(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB) public BlockDecorPipeValve(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); } { super(config|CFG_WATERLOGGABLE, builder, unrotatedAABB); }
private BlockState get_rsconnector_state(BlockState state, IWorld world, BlockPos pos, @Nullable BlockPos fromPos) private BlockState get_rsconnector_state(BlockState state, IWorld world, BlockPos pos, @Nullable BlockPos fromPos)
{ {
@ -88,7 +89,7 @@ public class BlockDecorPipeValve extends BlockDecorDirected
@Override @Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(FACING, RS_CN_N, RS_CN_S, RS_CN_E, RS_CN_W, RS_CN_U, RS_CN_D); } { super.fillStateContainer(builder); builder.add(RS_CN_N, RS_CN_S, RS_CN_E, RS_CN_W, RS_CN_U, RS_CN_D, WATERLOGGED); }
@Override @Override
@Nullable @Nullable

View file

@ -51,7 +51,7 @@ public class BlockDecorSlab extends BlockDecor
{ return state.get(PARTS) >= 2; } { return state.get(PARTS) >= 2; }
public BlockDecorSlab(long config, Block.Properties builder) public BlockDecorSlab(long config, Block.Properties builder)
{ super(config, builder); } { super(config|CFG_WATERLOGGABLE, builder); }
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@ -87,7 +87,7 @@ public class BlockDecorSlab extends BlockDecor
@Override @Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(PARTS, TEXTURE_VARIANT); } { super.fillStateContainer(builder); builder.add(PARTS, TEXTURE_VARIANT, WATERLOGGED); }
@Override @Override
@Nullable @Nullable
@ -96,7 +96,7 @@ public class BlockDecorSlab extends BlockDecor
final Direction facing = context.getFace(); final Direction facing = context.getFace();
double y = context.getHitVec().getY(); double y = context.getHitVec().getY();
int rnd = MathHelper.clamp((int)(MathHelper.getPositionRandom(context.getPos()) % 4), 0, 3); int rnd = MathHelper.clamp((int)(MathHelper.getPositionRandom(context.getPos()) % 4), 0, 3);
return getDefaultState().with(PARTS, ((facing==Direction.UP) || ((facing!=Direction.DOWN) && (y < 0.6))) ? 0 : 1).with(TEXTURE_VARIANT, rnd); return super.getStateForPlacement(context).with(PARTS, ((facing==Direction.UP) || ((facing!=Direction.DOWN) && (y < 0.6))) ? 0 : 1).with(TEXTURE_VARIANT, rnd);
} }
@Override @Override

View file

@ -46,7 +46,7 @@ public class BlockDecorSolarPanel extends BlockDecor
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockItemUseContext context) public BlockState getStateForPlacement(BlockItemUseContext context)
{ return getDefaultState(); } { return super.getStateForPlacement(context); }
@Override @Override
public boolean hasTileEntity(BlockState state) public boolean hasTileEntity(BlockState state)

View file

@ -10,7 +10,10 @@ package wile.engineersdecor.blocks;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.IWaterLoggable;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.StateContainer;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
@ -18,22 +21,27 @@ import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class BlockDecorStraightPole extends BlockDecorDirected public class BlockDecorStraightPole extends BlockDecorDirected implements IWaterLoggable
{ {
public BlockDecorStraightPole(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB) public BlockDecorStraightPole(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); } { super(config|CFG_WATERLOGGABLE, builder, unrotatedAABB); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockItemUseContext context) public BlockState getStateForPlacement(BlockItemUseContext context)
{ {
Direction facing = context.getFace(); Direction facing = context.getFace();
BlockState state = getDefaultState().with(FACING, facing); final boolean waterlogged = context.getWorld().getFluidState(context.getPos()).getFluid()==Fluids.WATER;
BlockState state = super.getStateForPlacement(context).with(FACING, facing).with(WATERLOGGED, waterlogged);
if((config & CFG_FLIP_PLACEMENT_IF_SAME) != 0) { if((config & CFG_FLIP_PLACEMENT_IF_SAME) != 0) {
World world = context.getWorld(); World world = context.getWorld();
BlockPos pos = context.getPos(); BlockPos pos = context.getPos();
if(world.getBlockState(pos.offset(facing.getOpposite())).getBlock() instanceof BlockDecorStraightPole) { if(world.getBlockState(pos.offset(facing.getOpposite())).getBlock() instanceof BlockDecorStraightPole) {
state = state.with(FACING, state.get(FACING).getOpposite()); state = state.with(FACING, state.get(FACING).getOpposite()).with(WATERLOGGED, waterlogged);
} }
} }
return state; return state;

View file

@ -71,7 +71,7 @@ public class BlockDecorWasteIncinerator extends BlockDecor
@Override @Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ builder.add(LIT); } { super.fillStateContainer(builder); builder.add(LIT); }
@Override @Override
@Nullable @Nullable

View file

@ -10,15 +10,17 @@ package wile.engineersdecor.blocks;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.IWaterLoggable;
import net.minecraft.state.StateContainer;
import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
public class BlockDecorWindow extends BlockDecorDirected public class BlockDecorWindow extends BlockDecorDirected implements IWaterLoggable
{ {
public BlockDecorWindow(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB) public BlockDecorWindow(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); } { super(config|CFG_WATERLOGGABLE, builder, unrotatedAABB); }
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@ -29,4 +31,8 @@ public class BlockDecorWindow extends BlockDecorDirected
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public boolean canRenderInLayer(BlockState state, BlockRenderLayer layer) public boolean canRenderInLayer(BlockState state, BlockRenderLayer layer)
{ return (layer==BlockRenderLayer.CUTOUT) || (layer==BlockRenderLayer.TRANSLUCENT); } { return (layer==BlockRenderLayer.CUTOUT) || (layer==BlockRenderLayer.TRANSLUCENT); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }
} }

View file

@ -11,13 +11,12 @@ package wile.engineersdecor.detail;
import wile.engineersdecor.ModContent; import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor; import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.blocks.BlockDecorSolarPanel.BTileEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.blocks.BlockDecorSolarPanel.BTileEntity;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -45,14 +44,6 @@ public class ModConfig
CLIENT = client_.getLeft(); CLIENT = client_.getLeft();
} }
@SubscribeEvent
public static void onLoad(final net.minecraftforge.fml.config.ModConfig.Loading configEvent)
{ apply(); ModEngineersDecor.logger().info("Loaded config file {}", configEvent.getConfig().getFileName()); }
@SubscribeEvent
public static void onFileChange(final net.minecraftforge.fml.config.ModConfig.ConfigReloading configEvent)
{ ModEngineersDecor.logger().info("Config file changed {}", configEvent.getConfig().getFileName()); }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
public static class ClientConfig public static class ClientConfig
@ -465,6 +456,9 @@ public class ModConfig
return false; return false;
} }
public static boolean withExperimental()
{ return with_experimental_features_; }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Cache // Cache
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
@ -472,6 +466,7 @@ public class ModConfig
private static final ArrayList<String> excludes_ = new ArrayList<String>(); private static final ArrayList<String> excludes_ = new ArrayList<String>();
public static boolean without_crafting_table = false; public static boolean without_crafting_table = false;
public static boolean immersiveengineering_installed = false; public static boolean immersiveengineering_installed = false;
private static boolean with_experimental_features_ = false;
public static final void apply() public static final void apply()
{ {
@ -484,10 +479,14 @@ public class ModConfig
BlockDecorSolarPanel.BTileEntity.on_config(COMMON.small_solar_panel_peak_production.get()); BlockDecorSolarPanel.BTileEntity.on_config(COMMON.small_solar_panel_peak_production.get());
without_crafting_table = isOptedOut(ModContent.TREATED_WOOD_CRAFTING_TABLE); without_crafting_table = isOptedOut(ModContent.TREATED_WOOD_CRAFTING_TABLE);
immersiveengineering_installed = ModAuxiliaries.isModLoaded("immersiveengineering"); immersiveengineering_installed = ModAuxiliaries.isModLoaded("immersiveengineering");
with_experimental_features_ = COMMON.with_experimental.get();
if(with_experimental_features_) {
ModEngineersDecor.logger().info("Config: EXPERIMENTAL FEATURES ENABLED.");
}
{ {
String inc = COMMON.pattern_includes.get().toLowerCase().replaceAll(ModEngineersDecor.MODID+":", "").replaceAll("[^*_,a-z0-9]", ""); String inc = COMMON.pattern_includes.get().toLowerCase().replaceAll(ModEngineersDecor.MODID+":", "").replaceAll("[^*_,a-z0-9]", "");
if(COMMON.pattern_includes.get() != inc) COMMON.pattern_includes.set(inc); if(COMMON.pattern_includes.get() != inc) COMMON.pattern_includes.set(inc);
if(!inc.isEmpty()) ModEngineersDecor.logger().info("Pattern includes: '" + inc + "'"); if(!inc.isEmpty()) ModEngineersDecor.logger().info("Config pattern includes: '" + inc + "'");
String[] incl = inc.split(","); String[] incl = inc.split(",");
includes_.clear(); includes_.clear();
for(int i=0; i< incl.length; ++i) { for(int i=0; i< incl.length; ++i) {
@ -497,7 +496,7 @@ public class ModConfig
} }
{ {
String exc = COMMON.pattern_includes.get().toLowerCase().replaceAll(ModEngineersDecor.MODID+":", "").replaceAll("[^*_,a-z0-9]", ""); String exc = COMMON.pattern_includes.get().toLowerCase().replaceAll(ModEngineersDecor.MODID+":", "").replaceAll("[^*_,a-z0-9]", "");
if(!exc.isEmpty()) ModEngineersDecor.logger().info("Pattern excludes: '" + exc + "'"); if(!exc.isEmpty()) ModEngineersDecor.logger().info("Config pattern excludes: '" + exc + "'");
String[] excl = exc.split(","); String[] excl = exc.split(",");
excludes_.clear(); excludes_.clear();
for(int i=0; i< excl.length; ++i) { for(int i=0; i< excl.length; ++i) {
@ -505,8 +504,5 @@ public class ModConfig
if(!excl[i].isEmpty()) excludes_.add(excl[i]); if(!excl[i].isEmpty()) excludes_.add(excl[i]);
} }
} }
} }
} }

View file

@ -0,0 +1,84 @@
/*
* @file ModTesrs.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2018 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Yet unstructured initial experiments with TESRs.
* May be structured after I know what I am doing there.
*/
package wile.engineersdecor.detail;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.blocks.BlockDecorCraftingTable;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import com.mojang.blaze3d.platform.GlStateManager;
public class ModTesrs
{
//--------------------------------------------------------------------------------------------------------------------
// Crafting table
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class TesrDecorCraftingTable extends TileEntityRenderer<BlockDecorCraftingTable.BTileEntity>
{
private static int tesr_error_counter = 4;
private static double scaler = 0.10;
private static double gap = 0.19;
private static double yrotations[] = {0, 90, 180, 270}; // [hdirection] S-W-N-E
private static double offsets[][][] = { // [hdirection][slotindex][xz]
{ {-1,-1},{+0,-1},{+1,-1}, {-1,+0},{+0,+0},{+1,+0}, {-1,+1},{+0,+1},{+1,+1} }, // S
{ {+1,-1},{+1,+0},{+1,+1}, {+0,-1},{+0,+0},{+0,+1}, {-1,-1},{-1,+0},{-1,+1} }, // W
{ {+1,+1},{+0,+1},{-1,+1}, {+1,+0},{+0,+0},{-1,+0}, {+1,-1},{+0,-1},{-1,-1} }, // N
{ {-1,+1},{-1,+0},{-1,-1}, {+0,+1},{+0,+0},{+0,-1}, {+1,+1},{+1,+0},{+1,-1} }, // E
};
@Override
@SuppressWarnings("deprecation")
public void render(final BlockDecorCraftingTable.BTileEntity te, double x, double y, double z, float partialTicks, int destroyStage)
{
if(tesr_error_counter<=0) return;
try {
int di = MathHelper.clamp(te.getWorld().getBlockState(te.getPos()).get(BlockDecorCraftingTable.FACING).getHorizontalIndex(), 0, 3);
long posrnd = te.getPos().toLong();
posrnd = (posrnd>>16)^(posrnd<<1);
for(int i=0; i<9; ++i) {
final ItemStack stack = te.getStackInSlot(i);
if(stack.isEmpty()) continue;
double prnd = ((double)(((Integer.rotateRight(stack.getItem().hashCode()^(int)posrnd,(stack.getCount()+i)&31)))&1023))/1024.0;
double rndo = gap * ((prnd*0.1)-0.05);
double ox = gap * offsets[di][i][0], oz = gap * offsets[di][i][1];
double oy = 0.5;
double ry = ((yrotations[di]+180) + ((prnd*60)-30)) % 360;
if(stack.isEmpty()) return;
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
RenderHelper.enableStandardItemLighting();
GlStateManager.translated(x+0.5+ox, y+0.5+oy, z+0.5+oz);
GlStateManager.rotated(90, 1, 0, 0);
GlStateManager.rotated(ry, 0, 0, 1);
GlStateManager.translated(rndo, rndo, 0);
GlStateManager.scaled(scaler, scaler, scaler);
Minecraft.getInstance().getItemRenderer().renderItem(stack, net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType.FIXED);
RenderHelper.disableStandardItemLighting();
GlStateManager.enableLighting();
GlStateManager.popMatrix();
}
} catch(Throwable e) {
if(--tesr_error_counter<=0) {
ModEngineersDecor.logger().error("TESR was disabled because broken, exception was: " + e.getMessage());
ModEngineersDecor.logger().error(e.getStackTrace());
}
}
}
}
}

View file

@ -32,9 +32,10 @@ public class OptionalRecipeCondition implements ICondition
private final List<ResourceLocation> all_required; private final List<ResourceLocation> all_required;
private final List<ResourceLocation> any_missing; private final List<ResourceLocation> any_missing;
private final @Nullable ResourceLocation result; private final @Nullable ResourceLocation result;
private final boolean experimental;
public OptionalRecipeCondition(ResourceLocation result, List<ResourceLocation> required, List<ResourceLocation> missing) public OptionalRecipeCondition(ResourceLocation result, List<ResourceLocation> required, List<ResourceLocation> missing, boolean isexperimental)
{ all_required = required; any_missing = missing; this.result = result; } { all_required = required; any_missing = missing; this.result = result; experimental=isexperimental; }
@Override @Override
public ResourceLocation getID() public ResourceLocation getID()
@ -49,12 +50,14 @@ public class OptionalRecipeCondition implements ICondition
sb.delete(sb.length()-1, sb.length()).append("], any-missing: ["); sb.delete(sb.length()-1, sb.length()).append("], any-missing: [");
for(ResourceLocation e:any_missing) sb.append(e.toString()).append(","); for(ResourceLocation e:any_missing) sb.append(e.toString()).append(",");
sb.delete(sb.length()-1, sb.length()).append("]"); sb.delete(sb.length()-1, sb.length()).append("]");
if(experimental) sb.append(" EXPERIMENTAL");
return sb.toString(); return sb.toString();
} }
@Override @Override
public boolean test() public boolean test()
{ {
if((experimental) && (!ModConfig.withExperimental())) return false;
final IForgeRegistry<Block> block_registry = ForgeRegistries.BLOCKS; final IForgeRegistry<Block> block_registry = ForgeRegistries.BLOCKS;
final IForgeRegistry<Item> item_registry = ForgeRegistries.ITEMS; final IForgeRegistry<Item> item_registry = ForgeRegistries.ITEMS;
if(result != null) { if(result != null) {
@ -103,6 +106,7 @@ public class OptionalRecipeCondition implements ICondition
List<ResourceLocation> required = new ArrayList<>(); List<ResourceLocation> required = new ArrayList<>();
List<ResourceLocation> missing = new ArrayList<>(); List<ResourceLocation> missing = new ArrayList<>();
ResourceLocation result = null; ResourceLocation result = null;
boolean experimental = false;
if(json.has("result")) result = new ResourceLocation(json.get("result").getAsString()); if(json.has("result")) result = new ResourceLocation(json.get("result").getAsString());
if(json.has("required")) { if(json.has("required")) {
for(JsonElement e:JSONUtils.getJsonArray(json, "required")) required.add(new ResourceLocation(e.getAsString())); for(JsonElement e:JSONUtils.getJsonArray(json, "required")) required.add(new ResourceLocation(e.getAsString()));
@ -110,7 +114,8 @@ public class OptionalRecipeCondition implements ICondition
if(json.has("missing")) { if(json.has("missing")) {
for(JsonElement e:JSONUtils.getJsonArray(json, "missing")) missing.add(new ResourceLocation(e.getAsString())); for(JsonElement e:JSONUtils.getJsonArray(json, "missing")) missing.add(new ResourceLocation(e.getAsString()));
} }
return new OptionalRecipeCondition(result, required, missing); if(json.has("experimental")) experimental = json.get("experimental").getAsBoolean();
return new OptionalRecipeCondition(result, required, missing, experimental);
} }
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before After
Before After

View file

@ -0,0 +1,21 @@
{
"conditions": [
{
"type": "engineersdecor:optional",
"experimental": true
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"DDD",
" D ",
" D "
],
"key": {
"D": { "item": "minecraft:diorite" }
},
"result": {
"item": "minecraft:stone",
"count": 1
}
}

View file

@ -0,0 +1,21 @@
{
"conditions": [
{
"type": "engineersdecor:optional",
"experimental": true
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"DDD",
" D ",
" D "
],
"key": {
"D": { "item": "minecraft:diorite" }
},
"result": {
"item": "minecraft:granite",
"count": 1
}
}

View file

@ -0,0 +1,21 @@
{
"conditions": [
{
"type": "engineersdecor:optional",
"experimental": true
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"DDD",
" D ",
" D "
],
"key": {
"D": { "item": "minecraft:diorite" }
},
"result": {
"item": "minecraft:andesite",
"count": 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

View file

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 410 KiB

After

Width:  |  Height:  |  Size: 410 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 222 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 226 KiB

After

Width:  |  Height:  |  Size: 226 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 242 KiB

Before After
Before After

View file

@ -3,6 +3,7 @@
![](engineers-decor-v103-summary.png) ![](engineers-decor-v103-summary.png)
![](engineers-decor-v104a-craftinggui.png) ![](engineers-decor-v104a-craftinggui.png)
![](engineers-decor-crafting-table-items.png)
![](engineers-decor-v103-labfurnacegui.png) ![](engineers-decor-v103-labfurnacegui.png)
![](engineers-decor-v103-labfurnace-electrical-speedup.png) ![](engineers-decor-v103-labfurnace-electrical-speedup.png)
![](engineers-decor-v100a-concrete-stuff.png) ![](engineers-decor-v100a-concrete-stuff.png)
@ -18,8 +19,8 @@
![](engineers-decor-v106a-wasteincinerator-gui.png) ![](engineers-decor-v106a-wasteincinerator-gui.png)
![](engineers-decor-v104a-redstone-valves.png) ![](engineers-decor-v104a-redstone-valves.png)
![](engineers-decor-v106a-factorydropper.png) ![](engineers-decor-v106a-factorydropper.png)
![](factory-dropper-gui.png) ![](engineers-decor-factory-dropper-gui.png)
![](factory-dropper-metal-press-compression.png) ![](engineers-decor-factory-dropper-metal-press-compression.png)
![](small-mineral-smelter-vanilla-automated.png) ![](engineers-decor-small-mineral-smelter-vanilla-automated.png)
![](small-solar-panel.png) ![](engineers-decor-small-solar-panel.png)
![](small-tree-cutter.png) ![](engineers-decor-small-tree-cutter.png)

168
readme.md
View file

@ -22,136 +22,134 @@ Main distribution channel for this mod is CurseForge:
The mod has its focus decorative blocks and devices helping you to build nice The mod has its focus decorative blocks and devices helping you to build nice
looking manufacturing contraptions. Current feature set: looking manufacturing contraptions. Current feature set:
- *Treated wood crafting table*: 3x3 crafting table with IE style GUI and a model - *Treated Wood Crafting Table*: 3x3 crafting table with IE style GUI and a model
fitting better in the engineer's workshop. Keeps its inventory, has eight additional fitting better in the engineer's workshop. Keeps its inventory, has eight additional
storage slots on the left side of the crafting grid. Crafted 2x2 with three storage slots on the left side of the crafting grid. Crafting history for fast
treated wood planks and one vanilla crafting table. refabrication of previous recipes. Providesa a recipe collision resolver (selection
button for ambiguous recipes). Quick-move buttons (opt-in) to from/to storage or
player inventory. Smart shift-click placement (balanced placing of items in the
crafting grid). Shows the placed items on the top of the table.
- *Small laboratory furnace*: Solid fuel consuming, updraught. Slightly hotter and - *Small Laboratory Furnace*: Solid fuel consuming, updraught. Slightly hotter and
better isolated than a cobblestone furnace, therefore more efficient. Has internal better isolated than a cobblestone furnace, therefore more efficient. Has internal
hopper FiFos for input, output, and fuel (two stacks each). Two auxilliary slots hopper FiFos for input, output, and fuel (two stacks each). Two auxilliary slots
(storage tray). Keeps inventory when relocated. Crafted with one cobblestone (storage tray). Keeps inventory when relocated. Can be boosted with RF power when
furnace, one hopper, and seven metal plates. a IE heater is placed in the furnace.
- *Small electrical furnace*: Pass-through electrical furnace. Can pull items out - *Small Electrical Furnace*: Pass-through electrical furnace. Can pull items out of
input side inventories, inserts items into inventories at the output side. Internal inventories at the input side, inserts items into inventories at the output side.
fifo slots. Automatically bypasses items that cannot be cooked or smelted. Electrical Internal fifo slots. Automatically bypasses items that cannot be cooked or smelted.
RF/FE power can be applied on all sides. Items can be inserted or drawn from all Electrical RF/FE power can be applied on all sides. Items can be inserted or drawn
sides (e.g. with filtered hopper or whatever). Fits ideally into a conveyor belt from all sides (e.g. with filtered hopper or whatever). Fits ideally into a conveyor
line/lane. Consumption and efficiency tunable via config. belt line/lane. Consumption and efficiency tunable via config.
- *Factory dropper*: Dropper with GUI configurable drop force, direction, stack size, - *Factory Dropper*: Dropper with GUI configurable drop force, direction, stack size,
trigger cool-down delay, and trigger logic. Three trigger slots ("filter slots") can trigger cool-down delay, and trigger logic. Three trigger slots ("filter slots") can
be used as internal trigger. They emit an internal signal if their item is found in be used as internal trigger. They emit an internal signal if their item is found in
in the dropper inventory (also at least the stack size of a trigger slot). Internal in the dropper inventory (also at least the stack size of a trigger slot). Internal
triggers can be easily combined with the external redstone signal trigger using triggers can be easily combined with the external redstone signal trigger using
logical *AND* or *OR* gates. If internal triggers match, the dropper will spit out logical *AND* or *OR* gates. If internal triggers match, the dropper will spit out
exactly the stacks in these slots. That allows to drop e.g. always nine lapis, exactly the stacks in these slots. That allows to drop e.g. always nine Lapis,
redstone, nuggets, etc on a conveyor to feed a compression metal press - instantly Redstone, nuggets, etc on a conveyor to feed a compression metal press - instantly
and automatically after nine of these items have been inserted into the dropper. and automatically after nine of these items have been inserted into the dropper.
Provides redstone pulse mode (drop like a vanilla dropper) or continuous mode
(continue dropping as long as the redstone signal is on).
- *Small waste incinerator*: Buffered and delayed item disposal device. 16 fifo - *Small Waste Incinerator*: Buffered and delayed item disposal device. 16 fifo
slots are filled when new items are pushed in from any side. A GUI allows to slots are filled when new items are pushed in from any side. A GUI allows to
take out accidentally trashed items or put in items to get rid of. When the fifo take out accidentally trashed items or put in items to get rid of. When the fifo
is full, the oldest stack will be disposed. The processing speed can be increased is full, the oldest stack will be disposed. The processing speed can be increased
by connecting electrical RF/FE power. by connecting electrical RF/FE power.
- *Clinker bricks*: Slightly darker and more colorful version of the vanilla brick - *Clinker Bricks*: Slightly darker and more colorful version of the vanilla brick
block. Eight position dependent texture variations are implemented to make the block. Eight position dependent texture variations are implemented to make the
wall look more "alive". Crafted 3x3 with a brick block in the centre and any wall look more "alive". Crafted 3x3 with a brick block in the centre and any
combination of bricks and nether bricks around (actually, anything where the combination of bricks and nether bricks around (actually, anything where the
ore dictionary says it's a "brick ingot"). Higher explosion resistance than the ore dictionary says it's a "brick ingot" - useful for bigger industrial buildings
vanilla bricks. Also available as stairs and wall, crafted as usual. There where clay is a rare resource). Higher explosion resistance than the vanilla
is a reverse recipe to get three clinker brick blocks back from stairs or walls. bricks. Also available as stairs and wall, crafted as usual. There is a reverse
recipe to get three clinker brick blocks back from stairs or walls. There are
also *Stained Clinker Bricks* (crafted Dirt and Clinkers), which can be mixed
in Clinker walls for more variations.
- *Slag bricks*: Gray-brownish brick, also eight texture variations. Crafted 3x3 - *Slag Bricks*: Gray-brownish brick, also eight texture variations. Crafted 3x3
from slag in the centre and any kind of bricks ("brick ingot") around. Has a higher from slag in the centre and any kind of bricks ("brick ingot") around. Has a higher
explosion resistance than bricks. Also available as stairs and wall, also with explosion resistance than bricks. Also available as stairs and wall, also with
reverse recipes. reverse recipes.
- Rebar (steel) reinforced concrete: Expensive but creeper-proof. Crafted 3x3 from - *Rebar Concrete*: Steel reinforced concrete. Expensive, creeper-proof.
four concrete blocks and five steel rods. Texture design oriented at the IE concrete, Texture design oriented at the IE concrete, slightly darker, eight (position
slightly darker, eight (position dependent) random texture variations with rust dependent) random texture variations with rust traces. Also creaftable in form
traces. Also creaftable in form of *stairs* and *walls*. Like the IE contrete *tiles*, of *stairs* and *walls*. Like the IE contrete *tiles*, you can craft rebar
you can craft rebar concrete tiles with corresponding stairs. Reverse recipes concrete tiles with corresponding stairs. Reverse recipes available for all
available for all blocks crafted from rebar concrete. blocks crafted from rebar concrete.
- Concrete wall: Solid concrete wall (not the vanilla wall design), crafted 3x3 - *Concrete Wall*: Solid concrete wall (not the vanilla wall design).
from six IE concrete blocks (normal wall recipe).
- *Treated wood ladder*: Crafted 3x3 with the known ladder pattern, items are - *Treated Wood Ladder*: Stylish ladder, climbing is faster if looking up/down and not
treated wood sticks. Climbing is faster if looking up/down and not sneaking. sneaking (but not OP-fast).
- *Metal rung ladder*: Industrial wall-fixed ladder with horizontal bent rods. - *Metal Rung Ladder*: Industrial wall-fixed ladder with horizontal bent rods. Climbing
Crafted 3x3 with five iron or steel rods in a "U" pattern. Climbing is faster is faster if looking up/down and not sneaking.
if looking up/down and not sneaking.
- *Staggered metal steps*: Industrial wall-fixed sparse ladder with steps in a - *Staggered Metal Steps*: Industrial wall-fixed sparse ladder with steps in a zip pattern.
zip pattern. Crafted 3x3 with six iron or steel rods in a zip pattern. Climbing Climbing is faster when looking up/down and not sneaking.
is faster when looking up/down and not sneaking.
- *Panzer glass*: Reinforced, dark gray tinted glass block. Explosion-proof. - *Panzer Glass*: Reinforced, dark gray tinted glass block. Explosion-proof. Faint
Faint structural lines are visible, multiple texture variations for seemless structural lines are visible, multiple texture variations for seemless look.
look. Crafted 3x3 with four metal rods, four glass blocks, and one diamond.
- *Treated wood table*: Four leg table made out of treated wood. Crafted 3x3 - *Treated Wood Table*: Four leg table made out of treated wood.
with three treated wood slabs and four treated wood poles. Guess the pattern.
- *Treated wood stool*: Simple small stool fitting to the table. Crafted 3x3 - *Treated Wood Stool*: Simple small stool fitting to the table. You can sit on it, and
with three treated wood slabs and one treated wood pole. also mobs will occationally do that (only mobs which actually can sit).
- *Treated wood pole*: Pole fragment that can be placed in all directions. It - *Treated Wood Pole*: Pole fragment that can be placed in all directions. It does
does intentionally not connect to posts, fences, etc - just a straigt pole. intentionally not connect to posts, fences, etc - just a straigt pole. Can be used e.g.
Can be used e.g. for structural support or wire relay post, where the height for structural support or wire relay post, where the height of the IE wire posts does
of the IE wire posts does not match. not match.
- *Thin and thick steel support poles*: Hollow steel pole fragments, can be - *Thin and thick Steel Support Poles*: Hollow steel pole fragments, can be placed in all
placed in all directions. Also with head/food end components. Thin poles crafted directions. Also with head/food end components.
3x3 from three steel ingots (output 12), thick poles crafted 3x3 from six thin
steel poles.
- *Double-T steel support*: Horizontal top-aligned support beam, placed in the - *Double-T Steel Support*: Horizontal top-aligned support beam, placed in the direction
direction you look. Auto connects to adjacent beams if facing towards them. Auto you look. Auto connects to adjacent beams if facing towards them. Auto connects to steel
connects to steel poles underneath. Crafted 3x3 from thin steel poles in a T-shape poles underneath. Note: When sneaking you can pass underneath it, not all mobs sneak.
(output: 6 beams).
- *Inset spot light*: Small metal framed glowstone based light source for ceiling, - *Inset Spot Light*: Small metal framed glowstone based light source for ceiling, wall,
wall, or floor. Light level like a torch. Thin, hence not blocking the way. or floor. Light level like a torch. Thin, hence not blocking the way. Allows illuminating
Allows illuminating places where electrical light installations are problematic. places where electrical light installations are problematic.
- *Industrial signs*: "Danger", "Electrical Hazard", "Exit", etc. - *Industrial Signs*: "Danger", "Electrical Hazard", "Exit", etc. Makes a factory looking
more alive.
- *Slab slices*: Decorative stackable thin slabs made of of IE metal sheets, - *Slab Slices*: Decorative stackable thin slabs made of of IE metal sheets, concretes,
concretes, treated wood. Useful e.g. for roofs or ramps. Left-clicking with treated wood. Useful e.g. for roofs or ramps. Left-clicking with the same slab type in
the same slab type in your hand while looking up/down removes slices again. your hand while looking up/down removes slices again.
Crafted 3x3 from four slabs.
- *Fluid pipe check valve*: Check valve: IE fluid pipe styled straight valve that - *Fluid Pipe Check Valve*: IE fluid pipe styled straight valve that conducts fluids only
conducts fluids only in one direction. Crafted from 3x3 from three fluid pipes. in one direction. Crafted from 3x3 from three fluid pipes. Supports IE pressurized fluid
Supports IE pressurized fluid transfer. transfer.
- *Redstone controlled valves*: Conduct only in one direction, on-off - *Redstone Controlled Valves*: Conduct only in one direction, on-off variant (open on redstone
variant (open on redstone power) and analog variant (closed at power 0, linear power) and analog variant (closed at power 0, linear flow slope, fully open at power 15).
flow slope, fully open at power 15). Support IE pressurized fluid transfer. Support IE pressurized fluid transfer.
- *Passive fluid accumulator*: Block with one output and five input sides, that - *Passive Fluid Accumulator*: Block with one output and five input sides, that draws fluids
draws fluids out of adjacent tanks when a pump drains fluid from the output port. out of adjacent tanks when a pump drains fluid from the output port. Implicit round-robin
Implicit round-robin balanced drain from adjacent blocks. Random initial fluid balanced drain from adjacent blocks. Random initial fluid drip-in to allow pumps to detect
drip-in to allow pumps to detect that fluids can be drained. The accumulator that fluids can be drained. The accumulator has a vacuum suction delay.
has a vacuum suction delay.
- *Small Solar Panel*: Produces a small amount of RF power, comparable to a - *Small Solar Panel*: Produces a small amount of RF power, comparable to a IE thermal
IE thermal peltier generator over one day cycle. No power at night, reduced peltier generator over one day cycle. No power at night, reduced power when raining. The
power when raining. The power curve during day time is non-linear. Useful power curve during day time is non-linear. Useful for electrical lighting of remote places.
for electrical lighting of remote places.
- *Small Tree Cutter*: A slab sized device that chops a tree in front of it. - *Small Tree Cutter*: A slab sized device that chops a tree in front of it. Needs by default
Needs by default about one minute, with RF power less than 10 seconds. Useful about one minute, with RF power less than 10 seconds. Useful to build a contraptive automated
to build a contraptive automated tree farm. tree farm.
- *Small Mineral Smelter*: Device that slowly converts most stones or sands to - *Small Mineral Smelter*: Device that slowly converts most stones or sands to magma blocks and
magma blocks and finally to lava. Needs a lot of power. When the lava is cooled finally to lava. Needs a lot of power. When the lava is cooled down in the smelter by removing
down in the smelter by removing the RF power, obsidian is generated. the RF power, obsidian is generated.
More to come slowly but steadily. More to come slowly but steadily.