Main readme updated, documentation updated, Makefiles updated. Experimental features snapshot. 1.14: Crafting table item rendering added. Recipe collision resolver added. Lang files updated.
|
@ -28,7 +28,7 @@ wildcardr=$(foreach d,$(wildcard $1*),$(call wildcardr,$d/,$2) $(filter $(subst
|
|||
#
|
||||
# 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
|
||||
|
||||
|
@ -94,12 +94,14 @@ dist-check:
|
|||
@echo "[1.12] Running dist checks ..."
|
||||
@djs tasks.js dist-check
|
||||
|
||||
dist: sanatize dist-check clean-all init mod
|
||||
dist-files: clean-all init mod
|
||||
@echo "[1.12] Distribution files ..."
|
||||
@mkdir -p dist
|
||||
@cp build/libs/$(MOD_JAR_PREFIX)* dist/
|
||||
@djs tasks.js dist
|
||||
|
||||
dist: sanatize dist-check dist-files
|
||||
|
||||
port-languages:
|
||||
@echo "[1.12] Porting language files to 1.14 ..."
|
||||
@djs tasks.js port-languages
|
||||
|
|
|
@ -10,7 +10,11 @@ Mod sources for Minecraft version 1.12.2.
|
|||
----
|
||||
## 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.
|
||||
[M] Window submodels stripped (reopened issue #19, thx overchoice).
|
||||
|
|
|
@ -25,6 +25,7 @@ import net.minecraft.util.ResourceLocation;
|
|||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import net.minecraftforge.client.model.ModelLoader;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
@ -595,6 +596,11 @@ public class ModContent
|
|||
for(Item e:registeredItems) {
|
||||
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()
|
||||
|
|
|
@ -9,24 +9,29 @@
|
|||
*/
|
||||
package wile.engineersdecor.blocks;
|
||||
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
|
||||
import wile.engineersdecor.ModEngineersDecor;
|
||||
import wile.engineersdecor.detail.Networking;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.*;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.Item;
|
||||
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.Ingredient;
|
||||
import net.minecraft.network.play.server.SPacketSetSlot;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
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_PREV = 1;
|
||||
protected static final int BUTTON_CLEAR_GRID = 2;
|
||||
protected static final int BUTTON_FROM_STORAGE = 3;
|
||||
protected static final int BUTTON_TO_STORAGE = 4;
|
||||
protected static final int BUTTON_FROM_PLAYER = 5;
|
||||
protected static final int BUTTON_TO_PLAYER = 6;
|
||||
protected static final int ACTION_PLACE_CURRENT_HISTORY_SEL = 7;
|
||||
protected static final int ACTION_PLACE_SHIFTCLICKED_STACK = 8;
|
||||
protected static final int BUTTON_NEXT_COLLISION_RECIPE = 3;
|
||||
protected static final int BUTTON_FROM_STORAGE = 4;
|
||||
protected static final int BUTTON_TO_STORAGE = 5;
|
||||
protected static final int BUTTON_FROM_PLAYER = 6;
|
||||
protected static final int BUTTON_TO_PLAYER = 7;
|
||||
protected static final int ACTION_PLACE_CURRENT_HISTORY_SEL = 8;
|
||||
protected static final int ACTION_PLACE_SHIFTCLICKED_STACK = 9;
|
||||
|
||||
protected static final ResourceLocation BACKGROUND = new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/treated_wood_crafting_table.png");
|
||||
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_PREV, x0+158,y0+30, 12,12, 180,30, 12, BACKGROUND)));
|
||||
buttons.add(addButton(new GuiButtonImage(BUTTON_CLEAR_GRID, x0+158,y0+58, 12,12, 194,8, 12, BACKGROUND)));
|
||||
buttons.add(addButton(new GuiButtonImage(BUTTON_NEXT_COLLISION_RECIPE, x0+132,y0+18, 20,10, 183,95, 12, BACKGROUND)));
|
||||
if(with_assist_quickmove_buttons) {
|
||||
buttons.add(addButton(new GuiButtonImage(BUTTON_FROM_STORAGE, x0+49, y0+34, 9,17, 219,34, 17, BACKGROUND)));
|
||||
buttons.add(addButton(new GuiButtonImage(BUTTON_TO_STORAGE, x0+49, y0+52, 9,17, 208,16, 17, BACKGROUND)));
|
||||
|
@ -381,6 +388,10 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
@Override
|
||||
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();
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
renderHoveredToolTip(mouseX, mouseY);
|
||||
|
@ -476,7 +487,8 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
case BUTTON_TO_STORAGE:
|
||||
case BUTTON_FROM_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();
|
||||
nbt.setInteger("action", button.id);
|
||||
Networking.PacketTileNotify.sendToServer(te, nbt);
|
||||
|
@ -615,8 +627,32 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
@Override
|
||||
public void onCraftMatrixChanged(IInventory inv)
|
||||
{
|
||||
if(world.isRemote) return;
|
||||
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) {
|
||||
ModEngineersDecor.logger.error("Recipe failed:", exc);
|
||||
}
|
||||
|
@ -676,6 +712,31 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
|
||||
public void setCraftingMatrixSlot(int slot_index, ItemStack stack)
|
||||
{ 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;
|
||||
protected NonNullList<ItemStack> stacks;
|
||||
protected final CraftingHistory history = new CraftingHistory();
|
||||
protected boolean has_recipe_collision_ = false;
|
||||
|
||||
public BTileEntity()
|
||||
{ stacks = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY); }
|
||||
|
@ -764,6 +826,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
|
||||
// private aux methods ---------------------------------------------------------------------
|
||||
|
||||
private boolean has_recipe_collision()
|
||||
{ return has_recipe_collision_; }
|
||||
|
||||
private boolean itemstack_recipe_match(ItemStack grid_stack, ItemStack history_stack)
|
||||
{
|
||||
if(history.current_recipe()!=null) {
|
||||
|
@ -948,7 +1013,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
}
|
||||
|
||||
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();
|
||||
boolean slots_changed = false;
|
||||
|
@ -978,6 +1043,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
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) {
|
||||
return EnumRefabPlacement.UNCHANGED;
|
||||
} 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; }
|
||||
} break;
|
||||
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;
|
||||
} break;
|
||||
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.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; }
|
||||
}
|
||||
} break;
|
||||
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.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.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; }
|
||||
}
|
||||
}
|
||||
|
@ -1132,6 +1200,11 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
if(stat != EnumRefabPlacement.UNCHANGED) { player_inventory_changed = true; te_changed = true; }
|
||||
}
|
||||
} 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();
|
||||
|
@ -1146,6 +1219,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
public void onServerPacketReceived(NBTTagCompound nbt)
|
||||
{
|
||||
if(nbt.hasKey("historydata")) history.read(nbt.getCompoundTag("historydata"));
|
||||
if(nbt.hasKey("hascollision")) has_recipe_collision_ = nbt.getBoolean("hascollision");
|
||||
}
|
||||
|
||||
private void syncHistory(EntityPlayer player)
|
||||
|
@ -1155,6 +1229,15 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
history.write(history_nbt);
|
||||
NBTTagCompound rnbt = new NBTTagCompound();
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1173,9 +1256,26 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
{ super.writeToNBT(nbt); writenbt(nbt); return nbt; }
|
||||
|
||||
@Override
|
||||
public NBTTagCompound getUpdateTag()
|
||||
public NBTTagCompound getUpdateTag() // on server
|
||||
{ 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 ---------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
|
@ -1256,7 +1356,6 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
@Override
|
||||
public void clear()
|
||||
{ stacks.clear(); }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -191,6 +191,10 @@ public class ModConfig
|
|||
@Config.Comment({"Disable CTRL-SHIFT item tooltip display."})
|
||||
@Config.Name("Without tooltips")
|
||||
public boolean without_tooltips = false;
|
||||
|
||||
@Config.Comment({"Disable all tile entity special renderers."})
|
||||
@Config.Name("Without TESRs")
|
||||
public boolean without_tesrs = false;
|
||||
}
|
||||
|
||||
@Config.Comment({
|
||||
|
|
85
1.12/src/main/java/wile/engineersdecor/detail/ModTesrs.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -37,6 +37,10 @@ public class RecipeCondModSpecific implements IConditionFactory
|
|||
public BooleanSupplier parse(JsonContext context, JsonObject json) {
|
||||
if(ModConfig.isWithoutRecipes()) return exclude();
|
||||
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<Item> item_registry = ForgeRegistries.ITEMS;
|
||||
final JsonArray items = json.getAsJsonArray("required");
|
||||
|
|
|
@ -199,11 +199,16 @@
|
|||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"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]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [18, 22, 0],
|
||||
"translation": [1.25, 0, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [0, -0.75, 0],
|
||||
"translation": [0, -1.25, 0],
|
||||
"scale": [0.2, 0.2, 0.2]
|
||||
},
|
||||
"gui": {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 27 KiB |
|
@ -72,12 +72,14 @@ dist-check:
|
|||
@echo "[1.14] Running dist checks ..."
|
||||
@djs tasks.js dist-check
|
||||
|
||||
dist: sanatize dist-check clean-all init mod
|
||||
dist-files: clean-all init mod
|
||||
@echo "[1.14] Distribution files ..."
|
||||
@mkdir -p dist
|
||||
@cp build/libs/$(MOD_JAR_PREFIX)* dist/
|
||||
@djs tasks.js dist
|
||||
|
||||
dist: sanatize dist-check dist-files
|
||||
|
||||
assets:
|
||||
@echo "[1.14] Running asset generators ..."
|
||||
@djs tasks.js create-slab-assets
|
||||
|
|
|
@ -19,21 +19,12 @@ version = "${version_engineersdecor}"
|
|||
group = "wile.engineersdecor"
|
||||
archivesBaseName = "engineersdecor-${version_minecraft}"
|
||||
|
||||
def signing = { ->
|
||||
def signingData = { ->
|
||||
def sp = new Properties()
|
||||
if(file("signing.properties").exists()) file("signing.properties").withInputStream { sp.load(it) }
|
||||
return sp
|
||||
}()
|
||||
|
||||
def git_version = { ->
|
||||
def stdout = new ByteArrayOutputStream()
|
||||
exec {
|
||||
commandLine 'git', 'log', '-1', '--format=%h'
|
||||
standardOutput = stdout
|
||||
}
|
||||
return stdout.toString().trim()
|
||||
}()
|
||||
|
||||
repositories {
|
||||
maven { name = "Progwml6 maven"; url = "https://dvs1.progwml6.com/files/maven/" } // JEI files
|
||||
maven { name = "ModMaven"; url = "modmaven.k-4u.nl" } // JEI files, fallback
|
||||
|
@ -83,6 +74,11 @@ dependencies {
|
|||
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 {
|
||||
manifest {
|
||||
attributes([
|
||||
|
|
|
@ -5,4 +5,4 @@ version_minecraft=1.14.4
|
|||
version_forge_minecraft=1.14.4-28.0.105
|
||||
version_fml_mappings=20190719-1.14.3
|
||||
version_jei=1.14.4:6.0.0.10
|
||||
version_engineersdecor=1.0.12-b2
|
||||
version_engineersdecor=1.0.12-b3
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
@ -11,6 +11,12 @@ Mod sources for Minecraft version 1.14.3.
|
|||
|
||||
## 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.
|
||||
[A] Small Solar Panel added.
|
||||
[M] Items fall through the Steel Floor Grating like in 1.12.2 version.
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
package wile.engineersdecor;
|
||||
|
||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import wile.engineersdecor.blocks.*;
|
||||
import wile.engineersdecor.detail.ModAuxiliaries;
|
||||
|
@ -32,6 +33,8 @@ import net.minecraftforge.api.distmarker.Dist;
|
|||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import wile.engineersdecor.detail.ModTesrs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
@ -40,12 +43,11 @@ import javax.annotation.Nonnull;
|
|||
@SuppressWarnings("unused")
|
||||
public class ModContent
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
// Blocks
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
public static final BlockDecorFull CLINKER_BRICK_BLOCK = (BlockDecorFull)(new BlockDecorFull(
|
||||
public static final BlockDecor CLINKER_BRICK_BLOCK = (BlockDecor)(new BlockDecor(
|
||||
BlockDecor.CFG_DEFAULT,
|
||||
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
|
||||
)).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,
|
||||
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
|
||||
)).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,
|
||||
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(3f, 50f).sound(SoundType.STONE)
|
||||
)).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,
|
||||
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete"));
|
||||
|
@ -131,13 +133,13 @@ public class ModContent
|
|||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "rebar_concrete_wall"));
|
||||
|
||||
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)
|
||||
)).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,
|
||||
Block.Properties.create(Material.ROCK, MaterialColor.STONE).hardnessAndResistance(5f, 2000f).sound(SoundType.STONE)
|
||||
)).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,
|
||||
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
|
||||
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)
|
||||
)).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,
|
||||
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
|
||||
ModAuxiliaries.getPixeledAABB(2,0,2, 14,15.9,14)
|
||||
)).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,
|
||||
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
|
||||
ModAuxiliaries.getPixeledAABB(0.5,15,10.5, 15.5,16,16)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_windowsill"));
|
||||
|
||||
public static final BlockDecorDirected INSET_LIGHT_IRON = (BlockDecorDirected)(new BlockDecorDirected(
|
||||
public static final BlockDecorDirected.WaterLoggable INSET_LIGHT_IRON = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
|
||||
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
|
||||
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).lightValue(15),
|
||||
ModAuxiliaries.getPixeledAABB(5.2,5.2,15.7, 10.8,10.8,16.0)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "iron_inset_light"));
|
||||
|
||||
public static final 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,
|
||||
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
|
||||
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,
|
||||
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1000f).sound(SoundType.WOOD).lightValue(1),
|
||||
ModAuxiliaries.getPixeledAABB(0,0,15.6, 16,16,16.0)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_decor"));
|
||||
|
||||
public static final BlockDecorDirected SIGN_HOTWIRE = (BlockDecorDirected)(new BlockDecorDirected(
|
||||
public static final BlockDecorDirected.WaterLoggable SIGN_HOTWIRE = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
|
||||
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL,
|
||||
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
|
||||
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_hotwire"));
|
||||
|
||||
public static final BlockDecorDirected SIGN_DANGER = (BlockDecorDirected)(new BlockDecorDirected(
|
||||
public static final BlockDecorDirected.WaterLoggable SIGN_DANGER = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
|
||||
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL,
|
||||
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
|
||||
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_danger"));
|
||||
|
||||
public static final BlockDecorDirected SIGN_DEFENSE = (BlockDecorDirected)(new BlockDecorDirected(
|
||||
public static final BlockDecorDirected.WaterLoggable SIGN_DEFENSE = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
|
||||
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL,
|
||||
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
|
||||
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_defense"));
|
||||
|
||||
public static final BlockDecorDirected SIGN_FACTORY_AREA = (BlockDecorDirected)(new BlockDecorDirected(
|
||||
public static final BlockDecorDirected.WaterLoggable SIGN_FACTORY_AREA = (BlockDecorDirected.WaterLoggable)(new BlockDecorDirected.WaterLoggable(
|
||||
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_HORIZIONTAL,
|
||||
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
|
||||
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_factoryarea"));
|
||||
|
||||
public static final 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,
|
||||
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 1f).sound(SoundType.WOOD),
|
||||
ModAuxiliaries.getPixeledAABB(3,7,15.6, 13,13,16)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "sign_exit"));
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
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"));
|
||||
|
||||
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)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_treated_wood"));
|
||||
|
||||
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)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_iron"));
|
||||
|
||||
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)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_steel"));
|
||||
|
||||
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)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_copper"));
|
||||
|
||||
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)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_gold"));
|
||||
|
||||
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)
|
||||
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "halfslab_sheetmetal_aluminum"));
|
||||
|
||||
|
@ -701,4 +702,9 @@ public class ModContent
|
|||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
package wile.engineersdecor;
|
||||
|
||||
import wile.engineersdecor.detail.ModConfig;
|
||||
import wile.engineersdecor.detail.OptionalRecipeCondition;
|
||||
import wile.engineersdecor.detail.Networking;
|
||||
import wile.engineersdecor.blocks.*;
|
||||
import wile.engineersdecor.detail.OptionalRecipeCondition.Serializer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.container.ContainerType;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -33,7 +32,6 @@ import net.minecraftforge.api.distmarker.Dist;
|
|||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import wile.engineersdecor.detail.OptionalRecipeCondition.Serializer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -70,7 +68,7 @@ public class ModEngineersDecor
|
|||
}
|
||||
|
||||
private void onClientSetup(final FMLClientSetupEvent event)
|
||||
{ ModContent.registerContainerGuis(event); }
|
||||
{ ModContent.registerContainerGuis(event); ModContent.registerTileEntityRenderers(event); }
|
||||
|
||||
private void onSendImc(final InterModEnqueueEvent event)
|
||||
{}
|
||||
|
@ -78,12 +76,8 @@ public class ModEngineersDecor
|
|||
private void onRecvImc(final InterModProcessEvent event)
|
||||
{}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerStarting(FMLServerStartingEvent event)
|
||||
{}
|
||||
|
||||
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
|
||||
public static class RegistryEvents
|
||||
public static class ForgeEvents
|
||||
{
|
||||
@SubscribeEvent
|
||||
public static void onBlocksRegistry(final RegistryEvent.Register<Block> event)
|
||||
|
@ -104,6 +98,32 @@ public class ModEngineersDecor
|
|||
@SubscribeEvent
|
||||
public static void onRegisterContainerTypes(final RegistryEvent.Register<ContainerType<?>> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -12,10 +12,16 @@
|
|||
*/
|
||||
package wile.engineersdecor.blocks;
|
||||
|
||||
import net.minecraft.block.IWaterLoggable;
|
||||
import net.minecraft.state.StateContainer;
|
||||
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.player.PlayerEntity;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.World;
|
||||
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.material.PushReaction;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
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_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_WATERLOGGABLE = 0x4000000000000000L; // The derived block extends IWaterLoggable
|
||||
|
||||
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
|
||||
public final long config;
|
||||
public final VoxelShape vshape;
|
||||
|
||||
public BlockDecor(long config, Block.Properties properties)
|
||||
{ this(config, properties, ModAuxiliaries.getPixeledAABB(0, 0, 0, 16, 16,16 )); }
|
||||
public BlockDecor(long conf, Block.Properties properties)
|
||||
{ this(conf, properties, ModAuxiliaries.getPixeledAABB(0, 0, 0, 16, 16,16 )); }
|
||||
|
||||
public BlockDecor(long config, Block.Properties properties, AxisAlignedBB aabb)
|
||||
{ super(properties); this.config = config; this.vshape = VoxelShapes.create(aabb); }
|
||||
public BlockDecor(long conf, Block.Properties properties, AxisAlignedBB aabb)
|
||||
{ super(properties); config = conf; vshape = VoxelShapes.create(aabb); }
|
||||
|
||||
public BlockDecor(long config, Block.Properties properties, VoxelShape voxel_shape)
|
||||
{ super(properties); this.config = config; this.vshape = voxel_shape; }
|
||||
public BlockDecor(long conf, Block.Properties properties, VoxelShape voxel_shape)
|
||||
{ super(properties); config = conf; vshape = voxel_shape; }
|
||||
|
||||
@Override
|
||||
@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)
|
||||
{ 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
|
||||
public boolean canSpawnInBlock()
|
||||
{ return false; }
|
||||
|
@ -130,4 +151,52 @@ public class BlockDecor extends Block implements IDecorBlock
|
|||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder)
|
||||
{ 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); }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import java.util.List;
|
|||
import java.util.Random;
|
||||
|
||||
|
||||
public class BlockDecorChair extends BlockDecorDirected
|
||||
public class BlockDecorChair extends BlockDecorDirected.WaterLoggable
|
||||
{
|
||||
private static boolean sitting_enabled = true;
|
||||
private static double sitting_probability = 0.1;
|
||||
|
|
|
@ -11,16 +11,10 @@ package wile.engineersdecor.blocks;
|
|||
import wile.engineersdecor.ModContent;
|
||||
import wile.engineersdecor.ModEngineersDecor;
|
||||
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.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.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
|
||||
import net.minecraft.world.*;
|
||||
import net.minecraft.block.Block;
|
||||
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.PlayerInventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
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.inventory.*;
|
||||
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.MathHelper;
|
||||
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.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.common.util.FakePlayer;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
@ -51,9 +53,10 @@ import com.mojang.blaze3d.platform.GlStateManager;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import javax.annotation.Nullable;
|
||||
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_direct_history_refab = false;
|
||||
|
@ -68,7 +71,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
}
|
||||
|
||||
public BlockDecorCraftingTable(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
|
||||
{ super(config, builder, unrotatedAABB); }
|
||||
{ super(config|CFG_WATERLOGGABLE, builder, unrotatedAABB); }
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state)
|
||||
|
@ -168,20 +171,33 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
// TileEntity ------------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound)
|
||||
{ super.read(compound); readnbt(compound); }
|
||||
public void read(CompoundNBT nbt)
|
||||
{ super.read(nbt); readnbt(nbt); }
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound)
|
||||
{ super.write(compound); writenbt(compound); return compound; }
|
||||
public CompoundNBT write(CompoundNBT nbt)
|
||||
{ super.write(nbt); writenbt(nbt); return nbt; }
|
||||
|
||||
@Override
|
||||
public CompoundNBT getUpdateTag()
|
||||
{ CompoundNBT nbt = super.getUpdateTag(); writenbt(nbt); return nbt; }
|
||||
|
||||
@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 ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -251,7 +267,13 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
|
||||
@Override
|
||||
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
|
||||
public boolean isItemValidForSlot(int index, ItemStack stack)
|
||||
|
@ -356,6 +378,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
private final CraftingHistory history_;
|
||||
private final BInventoryCrafting matrix_;
|
||||
private final CraftResultInventory result_;
|
||||
private boolean has_recipe_collision_;
|
||||
|
||||
public BContainer(int cid, PlayerInventory pinv)
|
||||
{ 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_);
|
||||
ServerPlayerEntity player = (ServerPlayerEntity) player_;
|
||||
ItemStack stack = ItemStack.EMPTY;
|
||||
Optional<ICraftingRecipe> optional = world.getServer().getRecipeManager().getRecipe(IRecipeType.CRAFTING, matrix_, world);
|
||||
if(optional.isPresent()) {
|
||||
ICraftingRecipe icraftingrecipe = optional.get();
|
||||
if(result_.canUseRecipe(world, player, icraftingrecipe)) {
|
||||
stack = icraftingrecipe.getCraftingResult(matrix_);
|
||||
List<ICraftingRecipe> recipes = world.getServer().getRecipeManager().getRecipes(IRecipeType.CRAFTING, matrix_, world);
|
||||
has_recipe_collision_ = false;
|
||||
if(recipes.size() > 0) {
|
||||
ICraftingRecipe recipe = recipes.get(0);
|
||||
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);
|
||||
player.connection.sendPacket(new SSetSlotPacket(windowId, 0, stack));
|
||||
syncProperties(player);
|
||||
} catch(Throwable exc) {
|
||||
ModEngineersDecor.logger().error("Recipe failed:", exc);
|
||||
}
|
||||
|
@ -492,6 +522,39 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
|
||||
// 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
List<ItemStack> to_fill = crafting_slot_stacks_to_add();
|
||||
if(history_.current_recipe() != null) result_.setRecipeUsed(history_.current_recipe());
|
||||
boolean slots_changed = false;
|
||||
boolean missing_item = false;
|
||||
int num_slots_placed = 0;
|
||||
|
@ -719,6 +783,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
private EnumRefabPlacement distribute_stack(IInventory inventory, final int slotno)
|
||||
{
|
||||
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();
|
||||
if(to_distribute.isEmpty()) return EnumRefabPlacement.UNCHANGED;
|
||||
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)
|
||||
{
|
||||
if(nbt.contains("history")) {
|
||||
history_.read(nbt.getCompound("history"));
|
||||
}
|
||||
if(nbt.contains("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)
|
||||
|
@ -871,6 +935,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
if(stat != EnumRefabPlacement.UNCHANGED) { player_inventory_changed = true; changed = true; }
|
||||
}
|
||||
} break;
|
||||
case BGui.BUTTON_NEXT_COLLISION_RECIPE: {
|
||||
select_next_collision_recipe(inventory_);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
if(changed) inventory_.markDirty();
|
||||
|
@ -895,6 +962,14 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
}
|
||||
final CompoundNBT nbt = new CompoundNBT();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -913,6 +988,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
protected static final String BUTTON_TO_STORAGE = "to-storage";
|
||||
protected static final String BUTTON_FROM_PLAYER = "from-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_SHIFTCLICKED_STACK = "place-stack";
|
||||
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+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+132,y0+18, 20,10, 183,95, 12, BACKGROUND, (bt)->action(BUTTON_NEXT_COLLISION_RECIPE))));
|
||||
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+52, 9,17, 208,16, 17, BACKGROUND, (bt)->action(BUTTON_TO_STORAGE))));
|
||||
|
@ -948,6 +1025,11 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
|||
@Override
|
||||
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();
|
||||
super.render(mouseX, mouseY, partialTicks);
|
||||
renderHoveredToolTip(mouseX, mouseY);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
package wile.engineersdecor.blocks;
|
||||
|
||||
import net.minecraft.block.IWaterLoggable;
|
||||
import wile.engineersdecor.detail.ModAuxiliaries;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.state.StateContainer;
|
||||
|
@ -77,7 +78,7 @@ public class BlockDecorDirected extends BlockDecor
|
|||
|
||||
@Override
|
||||
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
|
||||
{ builder.add(FACING); }
|
||||
{ super.fillStateContainer(builder); builder.add(FACING); }
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
|
@ -98,7 +99,20 @@ public class BlockDecorDirected extends BlockDecor
|
|||
}
|
||||
if((config & CFG_OPPOSITE_PLACEMENT)!=0) facing = facing.getOpposite();
|
||||
if(((config & CFG_FLIP_PLACEMENT_SHIFTCLICK) != 0) && (context.getPlayer().isSneaking())) facing = facing.getOpposite();
|
||||
return getDefaultState().with(FACING, facing);
|
||||
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); }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
package wile.engineersdecor.blocks;
|
||||
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
import net.minecraft.block.IWaterLoggable;
|
||||
import net.minecraft.util.Mirror;
|
||||
import net.minecraft.util.Rotation;
|
||||
import net.minecraft.entity.EntityType;
|
||||
|
@ -80,7 +81,7 @@ public class BlockDecorDirectedHorizontal extends BlockDecor
|
|||
|
||||
@Override
|
||||
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
|
||||
{ builder.add(HORIZONTAL_FACING); }
|
||||
{ super.fillStateContainer(builder); builder.add(HORIZONTAL_FACING); }
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
|
@ -96,7 +97,7 @@ public class BlockDecorDirectedHorizontal extends BlockDecor
|
|||
}
|
||||
if((config & CFG_OPPOSITE_PLACEMENT)!=0) facing = facing.getOpposite();
|
||||
if(((config & CFG_FLIP_PLACEMENT_SHIFTCLICK) != 0) && (context.getPlayer().isSneaking())) facing = facing.getOpposite();
|
||||
return getDefaultState().with(HORIZONTAL_FACING, facing);
|
||||
return super.getStateForPlacement(context).with(HORIZONTAL_FACING, facing);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -109,4 +110,17 @@ public class BlockDecorDirectedHorizontal extends BlockDecor
|
|||
public BlockState mirror(BlockState state, Mirror mirrorIn)
|
||||
{ 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); }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ public class BlockDecorDropper extends BlockDecorDirected
|
|||
|
||||
@Override
|
||||
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
|
||||
{ builder.add(FACING, OPEN); }
|
||||
{ super.fillStateContainer(builder); builder.add(OPEN); }
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
|
|
|
@ -22,10 +22,10 @@ import net.minecraft.world.IBlockReader;
|
|||
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)
|
||||
{ super(config, builder); }
|
||||
{ super(config|CFG_WATERLOGGABLE, builder); }
|
||||
|
||||
@Override
|
||||
public boolean propagatesSkylightDown(BlockState state, IBlockReader reader, BlockPos pos)
|
||||
|
|
|
@ -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); }
|
||||
}
|
|
@ -84,7 +84,7 @@ public class BlockDecorFurnace extends BlockDecorDirected
|
|||
@Override
|
||||
@Nullable
|
||||
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
|
||||
@SuppressWarnings("deprecation")
|
||||
|
|
|
@ -38,7 +38,7 @@ import java.util.Collections;
|
|||
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);
|
||||
|
||||
|
@ -61,12 +61,10 @@ public class BlockDecorHalfSlab extends BlockDecor
|
|||
VoxelShapes.create(new AxisAlignedBB(0,0,0,1,1,1)) // <- with 4bit fill
|
||||
};
|
||||
|
||||
protected static final int num_slabs_contained_in_parts_[] = {
|
||||
1,2,3,4,5,6,7,8,7,6,5,4,3,2,1 ,0x1 // <- with 4bit fill
|
||||
};
|
||||
protected static final int num_slabs_contained_in_parts_[] = { 1,2,3,4,5,6,7,8,7,6,5,4,3,2,1 ,0x1 }; // <- with 4bit fill
|
||||
|
||||
public BlockDecorHalfSlab(long config, Block.Properties builder)
|
||||
{ super(config, builder); }
|
||||
{ super(config|CFG_WATERLOGGABLE, builder); }
|
||||
|
||||
protected boolean is_cube(BlockState state)
|
||||
{ return state.get(PARTS) == 0x07; }
|
||||
|
@ -105,7 +103,7 @@ public class BlockDecorHalfSlab extends BlockDecor
|
|||
|
||||
@Override
|
||||
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
|
||||
{ builder.add(PARTS); }
|
||||
{ super.fillStateContainer(builder); builder.add(PARTS, WATERLOGGED); }
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
|
@ -113,7 +111,7 @@ public class BlockDecorHalfSlab extends BlockDecor
|
|||
{
|
||||
final Direction facing = context.getFace();
|
||||
double y = context.getHitVec().getY();
|
||||
return getDefaultState().with(PARTS, ((facing==Direction.UP) || ((facing!=Direction.DOWN) && (y < 0.6))) ? 0 : 14);
|
||||
return super.getStateForPlacement(context).with(PARTS, ((facing==Direction.UP) || ((facing!=Direction.DOWN) && (y < 0.6))) ? 0 : 14);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
package wile.engineersdecor.blocks;
|
||||
|
||||
import net.minecraft.block.IWaterLoggable;
|
||||
import wile.engineersdecor.ModContent;
|
||||
import wile.engineersdecor.detail.ModAuxiliaries;
|
||||
import net.minecraft.entity.EntityType;
|
||||
|
@ -35,7 +36,7 @@ import java.util.ArrayList;
|
|||
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 LEFTBEAM = BooleanProperty.create("leftbeam");
|
||||
|
@ -45,7 +46,7 @@ public class BlockDecorHorizontalSupport extends BlockDecor
|
|||
|
||||
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(
|
||||
// Effective bounding box
|
||||
VoxelShapes.create(ModAuxiliaries.getRotatedAABB(unrotatedAABB.grow(2.0/16, 0, 0), Direction.NORTH, true)),
|
||||
|
@ -80,12 +81,12 @@ public class BlockDecorHorizontalSupport extends BlockDecor
|
|||
|
||||
@Override
|
||||
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
|
||||
@Nullable
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context)
|
||||
{ return temp_block_update_until_better(getDefaultState().with(EASTWEST, context.getPlacementHorizontalFacing().getAxis()==Direction.Axis.X), context.getWorld(), context.getPos()); }
|
||||
{ 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)
|
||||
{
|
||||
|
|
|
@ -70,7 +70,6 @@ public class BlockDecorMineralSmelter extends BlockDecorDirectedHorizontal
|
|||
public BlockState getStateForPlacement(BlockItemUseContext context)
|
||||
{ return super.getStateForPlacement(context).with(PHASE, 0); }
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean hasComparatorInputOverride(BlockState state)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
package wile.engineersdecor.blocks;
|
||||
|
||||
import net.minecraft.block.IWaterLoggable;
|
||||
import wile.engineersdecor.ModContent;
|
||||
import wile.engineersdecor.ModEngineersDecor;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
|
@ -36,7 +37,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
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_S = BooleanProperty.create("rs_s");
|
||||
|
@ -53,7 +54,7 @@ public class BlockDecorPipeValve extends BlockDecorDirected
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -88,7 +89,7 @@ public class BlockDecorPipeValve extends BlockDecorDirected
|
|||
|
||||
@Override
|
||||
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
|
||||
{ builder.add(FACING, RS_CN_N, RS_CN_S, RS_CN_E, RS_CN_W, RS_CN_U, RS_CN_D); }
|
||||
{ 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
|
||||
@Nullable
|
||||
|
|
|
@ -51,7 +51,7 @@ public class BlockDecorSlab extends BlockDecor
|
|||
{ return state.get(PARTS) >= 2; }
|
||||
|
||||
public BlockDecorSlab(long config, Block.Properties builder)
|
||||
{ super(config, builder); }
|
||||
{ super(config|CFG_WATERLOGGABLE, builder); }
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
|
@ -87,7 +87,7 @@ public class BlockDecorSlab extends BlockDecor
|
|||
|
||||
@Override
|
||||
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
|
||||
{ builder.add(PARTS, TEXTURE_VARIANT); }
|
||||
{ super.fillStateContainer(builder); builder.add(PARTS, TEXTURE_VARIANT, WATERLOGGED); }
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
|
@ -96,7 +96,7 @@ public class BlockDecorSlab extends BlockDecor
|
|||
final Direction facing = context.getFace();
|
||||
double y = context.getHitVec().getY();
|
||||
int rnd = MathHelper.clamp((int)(MathHelper.getPositionRandom(context.getPos()) % 4), 0, 3);
|
||||
return getDefaultState().with(PARTS, ((facing==Direction.UP) || ((facing!=Direction.DOWN) && (y < 0.6))) ? 0 : 1).with(TEXTURE_VARIANT, rnd);
|
||||
return super.getStateForPlacement(context).with(PARTS, ((facing==Direction.UP) || ((facing!=Direction.DOWN) && (y < 0.6))) ? 0 : 1).with(TEXTURE_VARIANT, rnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -46,7 +46,7 @@ public class BlockDecorSolarPanel extends BlockDecor
|
|||
@Override
|
||||
@Nullable
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context)
|
||||
{ return getDefaultState(); }
|
||||
{ return super.getStateForPlacement(context); }
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state)
|
||||
|
|
|
@ -10,7 +10,10 @@ package wile.engineersdecor.blocks;
|
|||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.IWaterLoggable;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.state.StateContainer;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
|
@ -18,22 +21,27 @@ import net.minecraft.util.math.BlockPos;
|
|||
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)
|
||||
{ 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
|
||||
@Nullable
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context)
|
||||
{
|
||||
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) {
|
||||
World world = context.getWorld();
|
||||
BlockPos pos = context.getPos();
|
||||
if(world.getBlockState(pos.offset(facing.getOpposite())).getBlock() instanceof BlockDecorStraightPole) {
|
||||
state = state.with(FACING, state.get(FACING).getOpposite());
|
||||
state = state.with(FACING, state.get(FACING).getOpposite()).with(WATERLOGGED, waterlogged);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
|
|
|
@ -71,7 +71,7 @@ public class BlockDecorWasteIncinerator extends BlockDecor
|
|||
|
||||
@Override
|
||||
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
|
||||
{ builder.add(LIT); }
|
||||
{ super.fillStateContainer(builder); builder.add(LIT); }
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
|
|
|
@ -10,15 +10,17 @@ package wile.engineersdecor.blocks;
|
|||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.IWaterLoggable;
|
||||
import net.minecraft.state.StateContainer;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public class BlockDecorWindow extends BlockDecorDirected
|
||||
public class BlockDecorWindow extends BlockDecorDirected implements IWaterLoggable
|
||||
{
|
||||
public BlockDecorWindow(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
|
||||
{ super(config, builder, unrotatedAABB); }
|
||||
{ super(config|CFG_WATERLOGGABLE, builder, unrotatedAABB); }
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
|
@ -29,4 +31,8 @@ public class BlockDecorWindow extends BlockDecorDirected
|
|||
@OnlyIn(Dist.CLIENT)
|
||||
public boolean canRenderInLayer(BlockState state, BlockRenderLayer layer)
|
||||
{ return (layer==BlockRenderLayer.CUTOUT) || (layer==BlockRenderLayer.TRANSLUCENT); }
|
||||
|
||||
@Override
|
||||
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
|
||||
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }
|
||||
}
|
||||
|
|
|
@ -11,13 +11,12 @@ package wile.engineersdecor.detail;
|
|||
|
||||
import wile.engineersdecor.ModContent;
|
||||
import wile.engineersdecor.ModEngineersDecor;
|
||||
import wile.engineersdecor.blocks.*;
|
||||
import wile.engineersdecor.blocks.BlockDecorSolarPanel.BTileEntity;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import wile.engineersdecor.blocks.*;
|
||||
import wile.engineersdecor.blocks.BlockDecorSolarPanel.BTileEntity;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
|
@ -45,14 +44,6 @@ public class ModConfig
|
|||
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
|
||||
|
@ -465,6 +456,9 @@ public class ModConfig
|
|||
return false;
|
||||
}
|
||||
|
||||
public static boolean withExperimental()
|
||||
{ return with_experimental_features_; }
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
// Cache
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -472,6 +466,7 @@ public class ModConfig
|
|||
private static final ArrayList<String> excludes_ = new ArrayList<String>();
|
||||
public static boolean without_crafting_table = false;
|
||||
public static boolean immersiveengineering_installed = false;
|
||||
private static boolean with_experimental_features_ = false;
|
||||
|
||||
public static final void apply()
|
||||
{
|
||||
|
@ -484,10 +479,14 @@ public class ModConfig
|
|||
BlockDecorSolarPanel.BTileEntity.on_config(COMMON.small_solar_panel_peak_production.get());
|
||||
without_crafting_table = isOptedOut(ModContent.TREATED_WOOD_CRAFTING_TABLE);
|
||||
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]", "");
|
||||
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(",");
|
||||
includes_.clear();
|
||||
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]", "");
|
||||
if(!exc.isEmpty()) ModEngineersDecor.logger().info("Pattern excludes: '" + exc + "'");
|
||||
if(!exc.isEmpty()) ModEngineersDecor.logger().info("Config pattern excludes: '" + exc + "'");
|
||||
String[] excl = exc.split(",");
|
||||
excludes_.clear();
|
||||
for(int i=0; i< excl.length; ++i) {
|
||||
|
@ -505,8 +504,5 @@ public class ModConfig
|
|||
if(!excl[i].isEmpty()) excludes_.add(excl[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
84
1.14/src/main/java/wile/engineersdecor/detail/ModTesrs.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -32,9 +32,10 @@ public class OptionalRecipeCondition implements ICondition
|
|||
private final List<ResourceLocation> all_required;
|
||||
private final List<ResourceLocation> any_missing;
|
||||
private final @Nullable ResourceLocation result;
|
||||
private final boolean experimental;
|
||||
|
||||
public OptionalRecipeCondition(ResourceLocation result, List<ResourceLocation> required, List<ResourceLocation> missing)
|
||||
{ all_required = required; any_missing = missing; this.result = result; }
|
||||
public OptionalRecipeCondition(ResourceLocation result, List<ResourceLocation> required, List<ResourceLocation> missing, boolean isexperimental)
|
||||
{ all_required = required; any_missing = missing; this.result = result; experimental=isexperimental; }
|
||||
|
||||
@Override
|
||||
public ResourceLocation getID()
|
||||
|
@ -49,12 +50,14 @@ public class OptionalRecipeCondition implements ICondition
|
|||
sb.delete(sb.length()-1, sb.length()).append("], any-missing: [");
|
||||
for(ResourceLocation e:any_missing) sb.append(e.toString()).append(",");
|
||||
sb.delete(sb.length()-1, sb.length()).append("]");
|
||||
if(experimental) sb.append(" EXPERIMENTAL");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test()
|
||||
{
|
||||
if((experimental) && (!ModConfig.withExperimental())) return false;
|
||||
final IForgeRegistry<Block> block_registry = ForgeRegistries.BLOCKS;
|
||||
final IForgeRegistry<Item> item_registry = ForgeRegistries.ITEMS;
|
||||
if(result != null) {
|
||||
|
@ -103,6 +106,7 @@ public class OptionalRecipeCondition implements ICondition
|
|||
List<ResourceLocation> required = new ArrayList<>();
|
||||
List<ResourceLocation> missing = new ArrayList<>();
|
||||
ResourceLocation result = null;
|
||||
boolean experimental = false;
|
||||
if(json.has("result")) result = new ResourceLocation(json.get("result").getAsString());
|
||||
if(json.has("required")) {
|
||||
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")) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 27 KiB |
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
BIN
documentation/engineers-decor-crafting-table-items.png
Normal file
After Width: | Height: | Size: 165 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 410 KiB After Width: | Height: | Size: 410 KiB |
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 222 KiB |
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 226 KiB |
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 242 KiB |
|
@ -3,6 +3,7 @@
|
|||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
@ -18,8 +19,8 @@
|
|||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
|
168
readme.md
|
@ -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
|
||||
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
|
||||
storage slots on the left side of the crafting grid. Crafted 2x2 with three
|
||||
treated wood planks and one vanilla crafting table.
|
||||
storage slots on the left side of the crafting grid. Crafting history for fast
|
||||
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
|
||||
hopper FiFos for input, output, and fuel (two stacks each). Two auxilliary slots
|
||||
(storage tray). Keeps inventory when relocated. Crafted with one cobblestone
|
||||
furnace, one hopper, and seven metal plates.
|
||||
(storage tray). Keeps inventory when relocated. Can be boosted with RF power when
|
||||
a IE heater is placed in the furnace.
|
||||
|
||||
- *Small electrical furnace*: Pass-through electrical furnace. Can pull items out
|
||||
input side inventories, inserts items into inventories at the output side. Internal
|
||||
fifo slots. Automatically bypasses items that cannot be cooked or smelted. Electrical
|
||||
RF/FE power can be applied on all sides. Items can be inserted or drawn from all
|
||||
sides (e.g. with filtered hopper or whatever). Fits ideally into a conveyor belt
|
||||
line/lane. Consumption and efficiency tunable via config.
|
||||
- *Small Electrical Furnace*: Pass-through electrical furnace. Can pull items out of
|
||||
inventories at the input side, inserts items into inventories at the output side.
|
||||
Internal fifo slots. Automatically bypasses items that cannot be cooked or smelted.
|
||||
Electrical RF/FE power can be applied on all sides. Items can be inserted or drawn
|
||||
from all sides (e.g. with filtered hopper or whatever). Fits ideally into a conveyor
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
ore dictionary says it's a "brick ingot"). Higher explosion resistance than the
|
||||
vanilla 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.
|
||||
ore dictionary says it's a "brick ingot" - useful for bigger industrial buildings
|
||||
where clay is a rare resource). Higher explosion resistance than the vanilla
|
||||
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
|
||||
explosion resistance than bricks. Also available as stairs and wall, also with
|
||||
reverse recipes.
|
||||
|
||||
- Rebar (steel) reinforced concrete: Expensive but creeper-proof. Crafted 3x3 from
|
||||
four concrete blocks and five steel rods. Texture design oriented at the IE concrete,
|
||||
slightly darker, eight (position dependent) random texture variations with rust
|
||||
traces. Also creaftable in form of *stairs* and *walls*. Like the IE contrete *tiles*,
|
||||
you can craft rebar concrete tiles with corresponding stairs. Reverse recipes
|
||||
available for all blocks crafted from rebar concrete.
|
||||
- *Rebar Concrete*: Steel reinforced concrete. Expensive, creeper-proof.
|
||||
Texture design oriented at the IE concrete, slightly darker, eight (position
|
||||
dependent) random texture variations with rust traces. Also creaftable in form
|
||||
of *stairs* and *walls*. Like the IE contrete *tiles*, you can craft rebar
|
||||
concrete tiles with corresponding stairs. Reverse recipes available for all
|
||||
blocks crafted from rebar concrete.
|
||||
|
||||
- Concrete wall: Solid concrete wall (not the vanilla wall design), crafted 3x3
|
||||
from six IE concrete blocks (normal wall recipe).
|
||||
- *Concrete Wall*: Solid concrete wall (not the vanilla wall design).
|
||||
|
||||
- *Treated wood ladder*: Crafted 3x3 with the known ladder pattern, items are
|
||||
treated wood sticks. Climbing is faster if looking up/down and not sneaking.
|
||||
- *Treated Wood Ladder*: Stylish ladder, climbing is faster if looking up/down and not
|
||||
sneaking (but not OP-fast).
|
||||
|
||||
- *Metal rung ladder*: Industrial wall-fixed ladder with horizontal bent rods.
|
||||
Crafted 3x3 with five iron or steel rods in a "U" pattern. Climbing is faster
|
||||
if looking up/down and not sneaking.
|
||||
- *Metal Rung Ladder*: Industrial wall-fixed ladder with horizontal bent rods. Climbing
|
||||
is faster if looking up/down and not sneaking.
|
||||
|
||||
- *Staggered metal steps*: Industrial wall-fixed sparse ladder with steps in a
|
||||
zip pattern. Crafted 3x3 with six iron or steel rods in a zip pattern. Climbing
|
||||
is faster when looking up/down and not sneaking.
|
||||
- *Staggered Metal Steps*: Industrial wall-fixed sparse ladder with steps in a zip pattern.
|
||||
Climbing is faster when looking up/down and not sneaking.
|
||||
|
||||
- *Panzer glass*: Reinforced, dark gray tinted glass block. Explosion-proof.
|
||||
Faint structural lines are visible, multiple texture variations for seemless
|
||||
look. Crafted 3x3 with four metal rods, four glass blocks, and one diamond.
|
||||
- *Panzer Glass*: Reinforced, dark gray tinted glass block. Explosion-proof. Faint
|
||||
structural lines are visible, multiple texture variations for seemless look.
|
||||
|
||||
- *Treated wood table*: Four leg table made out of treated wood. Crafted 3x3
|
||||
with three treated wood slabs and four treated wood poles. Guess the pattern.
|
||||
- *Treated Wood Table*: Four leg table made out of treated wood.
|
||||
|
||||
- *Treated wood stool*: Simple small stool fitting to the table. Crafted 3x3
|
||||
with three treated wood slabs and one treated wood pole.
|
||||
- *Treated Wood Stool*: Simple small stool fitting to the table. You can sit on it, and
|
||||
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
|
||||
does intentionally not connect to posts, fences, etc - just a straigt pole.
|
||||
Can be used e.g. for structural support or wire relay post, where the height
|
||||
of the IE wire posts does not match.
|
||||
- *Treated Wood Pole*: Pole fragment that can be placed in all directions. It does
|
||||
intentionally not connect to posts, fences, etc - just a straigt pole. Can be used e.g.
|
||||
for structural support or wire relay post, where the height of the IE wire posts does
|
||||
not match.
|
||||
|
||||
- *Thin and thick steel support poles*: Hollow steel pole fragments, can be
|
||||
placed in all directions. Also with head/food end components. Thin poles crafted
|
||||
3x3 from three steel ingots (output 12), thick poles crafted 3x3 from six thin
|
||||
steel poles.
|
||||
- *Thin and thick Steel Support Poles*: Hollow steel pole fragments, can be placed in all
|
||||
directions. Also with head/food end components.
|
||||
|
||||
- *Double-T steel support*: Horizontal top-aligned support beam, placed in the
|
||||
direction you look. Auto connects to adjacent beams if facing towards them. Auto
|
||||
connects to steel poles underneath. Crafted 3x3 from thin steel poles in a T-shape
|
||||
(output: 6 beams).
|
||||
- *Double-T Steel Support*: Horizontal top-aligned support beam, placed in the direction
|
||||
you look. Auto connects to adjacent beams if facing towards them. Auto connects to steel
|
||||
poles underneath. Note: When sneaking you can pass underneath it, not all mobs sneak.
|
||||
|
||||
- *Inset spot light*: Small metal framed glowstone based light source for ceiling,
|
||||
wall, or floor. Light level like a torch. Thin, hence not blocking the way.
|
||||
Allows illuminating places where electrical light installations are problematic.
|
||||
- *Inset Spot Light*: Small metal framed glowstone based light source for ceiling, wall,
|
||||
or floor. Light level like a torch. Thin, hence not blocking the way. Allows illuminating
|
||||
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,
|
||||
concretes, treated wood. Useful e.g. for roofs or ramps. Left-clicking with
|
||||
the same slab type in your hand while looking up/down removes slices again.
|
||||
Crafted 3x3 from four slabs.
|
||||
- *Slab Slices*: Decorative stackable thin slabs made of of IE metal sheets, concretes,
|
||||
treated wood. Useful e.g. for roofs or ramps. Left-clicking with the same slab type in
|
||||
your hand while looking up/down removes slices again.
|
||||
|
||||
- *Fluid pipe check valve*: Check valve: IE fluid pipe styled straight valve that
|
||||
conducts fluids only in one direction. Crafted from 3x3 from three fluid pipes.
|
||||
Supports IE pressurized fluid transfer.
|
||||
- *Fluid Pipe Check Valve*: IE fluid pipe styled straight valve that conducts fluids only
|
||||
in one direction. Crafted from 3x3 from three fluid pipes. Supports IE pressurized fluid
|
||||
transfer.
|
||||
|
||||
- *Redstone controlled valves*: Conduct only in one direction, on-off
|
||||
variant (open on redstone power) and analog variant (closed at power 0, linear
|
||||
flow slope, fully open at power 15). Support IE pressurized fluid transfer.
|
||||
- *Redstone Controlled Valves*: Conduct only in one direction, on-off variant (open on redstone
|
||||
power) and analog variant (closed at power 0, linear flow slope, fully open at power 15).
|
||||
Support IE pressurized fluid transfer.
|
||||
|
||||
- *Passive fluid accumulator*: Block with one output and five input sides, that
|
||||
draws fluids out of adjacent tanks when a pump drains fluid from the output port.
|
||||
Implicit round-robin balanced drain from adjacent blocks. Random initial fluid
|
||||
drip-in to allow pumps to detect that fluids can be drained. The accumulator
|
||||
has a vacuum suction delay.
|
||||
- *Passive Fluid Accumulator*: Block with one output and five input sides, that draws fluids
|
||||
out of adjacent tanks when a pump drains fluid from the output port. Implicit round-robin
|
||||
balanced drain from adjacent blocks. Random initial fluid drip-in to allow pumps to detect
|
||||
that fluids can be drained. The accumulator has a vacuum suction delay.
|
||||
|
||||
- *Small Solar Panel*: Produces a small amount of RF power, comparable to a
|
||||
IE thermal peltier generator over one day cycle. No power at night, reduced
|
||||
power when raining. The power curve during day time is non-linear. Useful
|
||||
for electrical lighting of remote places.
|
||||
- *Small Solar Panel*: Produces a small amount of RF power, comparable to a IE thermal
|
||||
peltier generator over one day cycle. No power at night, reduced power when raining. The
|
||||
power curve during day time is non-linear. Useful for electrical lighting of remote places.
|
||||
|
||||
- *Small Tree Cutter*: A slab sized device that chops a tree in front of it.
|
||||
Needs by default about one minute, with RF power less than 10 seconds. Useful
|
||||
to build a contraptive automated tree farm.
|
||||
- *Small Tree Cutter*: A slab sized device that chops a tree in front of it. Needs by default
|
||||
about one minute, with RF power less than 10 seconds. Useful to build a contraptive automated
|
||||
tree farm.
|
||||
|
||||
- *Small Mineral Smelter*: Device that slowly converts most stones or sands to
|
||||
magma blocks and finally to lava. Needs a lot of power. When the lava is cooled
|
||||
down in the smelter by removing the RF power, obsidian is generated.
|
||||
- *Small Mineral Smelter*: Device that slowly converts most stones or sands to magma blocks and
|
||||
finally to lava. Needs a lot of power. When the lava is cooled down in the smelter by removing
|
||||
the RF power, obsidian is generated.
|
||||
|
||||
More to come slowly but steadily.
|
||||
|
||||
|
|