Crafting table: History refab and JEI integration.
|
@ -4,4 +4,4 @@ org.gradle.jvmargs=-Xmx8G
|
||||||
version_minecraft=1.12.2
|
version_minecraft=1.12.2
|
||||||
version_forge=14.23.5.2768
|
version_forge=14.23.5.2768
|
||||||
version_jei=4.10.0.198
|
version_jei=4.10.0.198
|
||||||
version_engineersdecor=1.0.3
|
version_engineersdecor=1.0.4-b1
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
|
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
|
||||||
"1.12.2": {
|
"1.12.2": {
|
||||||
|
"1.0.4-b1": "[A] Crafting table: JEI integration for recipe placement added.\n[A] Crafting table: History re-fab added, allowing to quickly select and re-craft recent recipes. Selection with arrow buttons, ingredient placement by clicking the result slot. Automatic item distribution on shift-click. Quick-move buttons.\n[F] Crafting table textures modified to prevent optifine glitches on the edges of the legs.",
|
||||||
"1.0.3": "[R] Release based on v1.0.3-b5. Release-to-release changes: * Small laboratory furnace added. * Extensive config options for mod packing and tuning added. * Rendering issues fixes (window bleeding, optifine). * Steel framed window added. * Treated wood pole \"end pieces\" added (two support variants). * Sitting on treated wood stool added including mobs (but not villagers, as these are obviously very upright people). * Lang ru_ru added (github contribution from Yaroslavik). * Creative tab logo changed to mod logo. * Table/crafting table bounding boxes refined. * Standalone \"escape\" recipes added if IE is not installed.",
|
"1.0.3": "[R] Release based on v1.0.3-b5. Release-to-release changes: * Small laboratory furnace added. * Extensive config options for mod packing and tuning added. * Rendering issues fixes (window bleeding, optifine). * Steel framed window added. * Treated wood pole \"end pieces\" added (two support variants). * Sitting on treated wood stool added including mobs (but not villagers, as these are obviously very upright people). * Lang ru_ru added (github contribution from Yaroslavik). * Creative tab logo changed to mod logo. * Table/crafting table bounding boxes refined. * Standalone \"escape\" recipes added if IE is not installed.",
|
||||||
"1.0.3-b5": "[F] Fixed typo in en-en lang file.\n[F] Fixed IE concrete texture missing bailout in log if IE is not installed.\n[F] Using forge multi-layer models for windows to circumvent glitches.\n[M] Changed creative tab logo to the mod logo.\n[A] Added alternative recipes for crafting table and furnace if main IE ingredients are missing (for \"stand-alone\" mod usage).",
|
"1.0.3-b5": "[F] Fixed typo in en-en lang file.\n[F] Fixed IE concrete texture missing bailout in log if IE is not installed.\n[F] Using forge multi-layer models for windows to circumvent glitches.\n[M] Changed creative tab logo to the mod logo.\n[A] Added alternative recipes for crafting table and furnace if main IE ingredients are missing (for \"stand-alone\" mod usage).",
|
||||||
"1.0.3-b4": "[A] Lab furnace supports electrical speedup when a IE external is placed in one of the two auxiliary slots.\n[F] Fixed window rendering issue (issue #15, thanks to ILLOMIURGE).\n[M] Updated ru_ru lang file (Yaroslavik).",
|
"1.0.3-b4": "[A] Lab furnace supports electrical speedup when a IE external is placed in one of the two auxiliary slots.\n[F] Fixed window rendering issue (issue #15, thanks to ILLOMIURGE).\n[M] Updated ru_ru lang file (Yaroslavik).",
|
||||||
|
@ -24,6 +25,6 @@
|
||||||
},
|
},
|
||||||
"promos": {
|
"promos": {
|
||||||
"1.12.2-recommended": "1.0.3",
|
"1.12.2-recommended": "1.0.3",
|
||||||
"1.12.2-latest": "1.0.3"
|
"1.12.2-latest": "1.0.4-b1"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,6 +10,14 @@ Mod sources for Minecraft version 1.12.2.
|
||||||
----
|
----
|
||||||
## Revision history
|
## Revision history
|
||||||
|
|
||||||
|
- v1.0.4-b1 [A] Crafting table: JEI integration for recipe placement added.
|
||||||
|
[A] Crafting table: History re-fab added, allowing to quickly select
|
||||||
|
and re-craft recent recipes. Selection with arrow buttons,
|
||||||
|
ingredient placement by clicking the result slot. Automatic
|
||||||
|
item distribution on shift-click. Quick-move buttons.
|
||||||
|
[F] Crafting table textures modified to prevent optifine glitches
|
||||||
|
on the edges of the legs.
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
- v1.0.3 [R] Release based on v1.0.3-b5. Release-to-release changes:
|
- v1.0.3 [R] Release based on v1.0.3-b5. Release-to-release changes:
|
||||||
* Small laboratory furnace added.
|
* Small laboratory furnace added.
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
*/
|
*/
|
||||||
package wile.engineersdecor.blocks;
|
package wile.engineersdecor.blocks;
|
||||||
|
|
||||||
import net.minecraft.client.gui.GuiButtonImage;
|
|
||||||
import wile.engineersdecor.ModEngineersDecor;
|
import wile.engineersdecor.ModEngineersDecor;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.SoundType;
|
import net.minecraft.block.SoundType;
|
||||||
|
@ -25,6 +24,8 @@ import net.minecraft.inventory.*;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
|
import net.minecraft.item.crafting.Ingredient;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.*;
|
import net.minecraft.util.*;
|
||||||
|
@ -37,8 +38,11 @@ import net.minecraft.client.renderer.RenderHelper;
|
||||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
import net.minecraft.client.gui.GuiButton;
|
import net.minecraft.client.gui.GuiButton;
|
||||||
|
import net.minecraft.client.gui.GuiButtonImage;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||||
|
import net.minecraftforge.registries.IForgeRegistry;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import wile.engineersdecor.detail.Networking;
|
import wile.engineersdecor.detail.Networking;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
@ -51,10 +55,14 @@ import java.util.List;
|
||||||
public class BlockDecorCraftingTable extends BlockDecorDirected
|
public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
{
|
{
|
||||||
public static boolean with_assist = true;
|
public static boolean with_assist = true;
|
||||||
|
public static boolean with_assist_direct_history_refab = false;
|
||||||
|
public static boolean with_assist_quickmove_buttons = false;
|
||||||
|
|
||||||
public static final void on_config(boolean without_crafting_assist)
|
public static final void on_config(boolean without_crafting_assist, boolean with_assist_immediate_history_refab, boolean with_quickmove_buttons)
|
||||||
{
|
{
|
||||||
with_assist = !without_crafting_assist;
|
with_assist = !without_crafting_assist;
|
||||||
|
with_assist_direct_history_refab = with_assist_immediate_history_refab;
|
||||||
|
with_assist_quickmove_buttons = with_quickmove_buttons;
|
||||||
CraftingHistory.max_history_size(32);
|
CraftingHistory.max_history_size(32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,11 +165,15 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
|
|
||||||
private static class CraftingHistory
|
private static class CraftingHistory
|
||||||
{
|
{
|
||||||
|
public static final int RESULT_STACK_INDEX = 0;
|
||||||
|
public static final int INPUT_STACKS_BEGIN = 1;
|
||||||
public static final List<ItemStack> NOTHING = new ArrayList<ItemStack>();
|
public static final List<ItemStack> NOTHING = new ArrayList<ItemStack>();
|
||||||
|
private static int max_history_size_ = 5;
|
||||||
|
|
||||||
private List<String> history_ = new ArrayList<String>();
|
private List<String> history_ = new ArrayList<String>();
|
||||||
private int current_ = -1;
|
private int current_ = -1;
|
||||||
private static int max_history_size_ = 5;
|
private List<ItemStack> current_stacks_ = new ArrayList<ItemStack>();
|
||||||
|
private IRecipe current_recipe_ = null;
|
||||||
|
|
||||||
public CraftingHistory()
|
public CraftingHistory()
|
||||||
{}
|
{}
|
||||||
|
@ -186,6 +198,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current_ = (!subsect.hasKey("current")) ? (-1) : MathHelper.clamp(subsect.getInteger("current"), -1, history_.size()-1);
|
current_ = (!subsect.hasKey("current")) ? (-1) : MathHelper.clamp(subsect.getInteger("current"), -1, history_.size()-1);
|
||||||
|
update_current();
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
ModEngineersDecor.logger.error("Exception reading crafting table history NBT, resetting, exception is:" + ex.getMessage());
|
ModEngineersDecor.logger.error("Exception reading crafting table history NBT, resetting, exception is:" + ex.getMessage());
|
||||||
clear();
|
clear();
|
||||||
|
@ -201,27 +214,39 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear()
|
public void clear()
|
||||||
{ current_ = -1; history_.clear(); }
|
{ reset_current(); history_.clear(); }
|
||||||
|
|
||||||
public void reset_curent()
|
public void reset_current()
|
||||||
{ current_ = -1; }
|
{ current_ = -1; current_stacks_ = NOTHING; current_recipe_ = null; }
|
||||||
|
|
||||||
public void add(final List<ItemStack> grid_stacks)
|
void update_current()
|
||||||
{
|
{
|
||||||
if(!with_assist) { clear(); return; }
|
if((current_ < 0) || (current_ >= history_.size())) { reset_current(); return; }
|
||||||
String s = stacks2str(grid_stacks);
|
Tuple<IRecipe, List<ItemStack>> data = str2stacks(history_.get(current_));
|
||||||
if(s.isEmpty()) return;
|
if(data == null) { reset_current(); return; }
|
||||||
history_.removeIf(e->e.equals(s));
|
current_recipe_ = data.getFirst();
|
||||||
history_.add(s);
|
current_stacks_ = data.getSecond();
|
||||||
while(history_.size() > max_history_size()) history_.remove(0);
|
|
||||||
if(current_ >= history_.size()) current_ = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String stacks2str(final List<ItemStack> grid_stacks)
|
public void add(final List<ItemStack> grid_stacks, IRecipe recipe)
|
||||||
{
|
{
|
||||||
if((grid_stacks==null) || (grid_stacks.size() != 10)) return "";
|
if(!with_assist) { clear(); return; }
|
||||||
|
String s = stacks2str(grid_stacks, recipe);
|
||||||
|
String recipe_filter = recipe.getRegistryName().toString() + ";";
|
||||||
|
if(s.isEmpty()) return;
|
||||||
|
history_.removeIf(e->e.equals(s));
|
||||||
|
history_.removeIf(e->e.startsWith(recipe_filter));
|
||||||
|
history_.add(s);
|
||||||
|
while(history_.size() > max_history_size()) history_.remove(0);
|
||||||
|
if(current_ >= history_.size()) reset_current();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String stacks2str(final List<ItemStack> grid_stacks, IRecipe recipe)
|
||||||
|
{
|
||||||
|
if((grid_stacks==null) || (grid_stacks.size() != 10) || (recipe==null)) return "";
|
||||||
if(grid_stacks.get(0).isEmpty()) return "";
|
if(grid_stacks.get(0).isEmpty()) return "";
|
||||||
final ArrayList<String> items = new ArrayList<String>();
|
final ArrayList<String> items = new ArrayList<String>();
|
||||||
|
items.add(recipe.getRegistryName().toString().trim());
|
||||||
for(ItemStack st:grid_stacks) {
|
for(ItemStack st:grid_stacks) {
|
||||||
int meta = st.getMetadata();
|
int meta = st.getMetadata();
|
||||||
items.add( (st.isEmpty()) ? ("") : ((st.getItem().getRegistryName().toString().trim()) + ((meta==0)?(""):("/"+meta)) ));
|
items.add( (st.isEmpty()) ? ("") : ((st.getItem().getRegistryName().toString().trim()) + ((meta==0)?(""):("/"+meta)) ));
|
||||||
|
@ -229,13 +254,21 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
return String.join(";", items);
|
return String.join(";", items);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ItemStack> str2stacks(final String entry)
|
public @Nullable Tuple<IRecipe, List<ItemStack>> str2stacks(final String entry)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if((entry == null) || (entry.isEmpty())) return NOTHING;
|
if((entry == null) || (entry.isEmpty())) return null;
|
||||||
ArrayList<String> item_regnames = new ArrayList<String>(Arrays.asList(entry.split("[;]")));
|
ArrayList<String> item_regnames = new ArrayList<String>(Arrays.asList(entry.split("[;]")));
|
||||||
if((item_regnames == null) || (item_regnames.size() > 10)) return NOTHING;
|
if((item_regnames == null) || (item_regnames.size() < 2) || (item_regnames.size() > 11)) return null;
|
||||||
while(item_regnames.size() < 10) item_regnames.add("");
|
while(item_regnames.size() < 11) item_regnames.add("");
|
||||||
|
IRecipe recipe = null;
|
||||||
|
try {
|
||||||
|
final IForgeRegistry<IRecipe> recipe_registry = GameRegistry.findRegistry(IRecipe.class);
|
||||||
|
recipe = recipe_registry.getValue(new ResourceLocation(item_regnames.remove(0)));
|
||||||
|
} catch(Throwable e) {
|
||||||
|
ModEngineersDecor.logger.error("Recipe lookup failed: " + e.getMessage());
|
||||||
|
}
|
||||||
|
if(recipe==null) return null;
|
||||||
List<ItemStack> stacks = new ArrayList<ItemStack>();
|
List<ItemStack> stacks = new ArrayList<ItemStack>();
|
||||||
for(String regname : item_regnames) {
|
for(String regname : item_regnames) {
|
||||||
ItemStack stack = ItemStack.EMPTY;
|
ItemStack stack = ItemStack.EMPTY;
|
||||||
|
@ -244,42 +277,54 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
if(regname.indexOf('/') >= 0) {
|
if(regname.indexOf('/') >= 0) {
|
||||||
String[] itemdetails = regname.split("[/]");
|
String[] itemdetails = regname.split("[/]");
|
||||||
if(itemdetails.length>0) regname = itemdetails[0];
|
if(itemdetails.length>0) regname = itemdetails[0];
|
||||||
try { if(itemdetails.length>1) meta = Integer.parseInt(itemdetails[1]); } catch(Throwable e){meta=0;} // ignore exception here
|
if(itemdetails.length>1) try { meta=Integer.parseInt(itemdetails[1]); } catch(Throwable e){ meta=0; } // ignore exception here
|
||||||
}
|
}
|
||||||
final Item item = Item.REGISTRY.getObject(new ResourceLocation(regname));
|
final Item item = Item.REGISTRY.getObject(new ResourceLocation(regname));
|
||||||
stack = ((item == null) || (item == Items.AIR)) ? ItemStack.EMPTY : (new ItemStack(item, 1, meta));
|
stack = ((item == null) || (item == Items.AIR)) ? ItemStack.EMPTY : (new ItemStack(item, 1, meta));
|
||||||
}
|
}
|
||||||
stacks.add(stack);
|
stacks.add(stack);
|
||||||
}
|
}
|
||||||
if((stacks.size() != 10) || (stacks.get(0).isEmpty())) return NOTHING; // invalid size or no result
|
if((stacks.size() != 10) || (stacks.get(0).isEmpty())) return null; // invalid size or no result
|
||||||
return stacks;
|
return new Tuple<IRecipe, List<ItemStack>>(recipe, stacks);
|
||||||
} catch(Throwable ex) {
|
} catch(Throwable ex) {
|
||||||
ModEngineersDecor.logger.error("History stack building failed: " + ex.getMessage());
|
ModEngineersDecor.logger.error("History stack building failed: " + ex.getMessage());
|
||||||
return NOTHING;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ItemStack> current()
|
public List<ItemStack> current()
|
||||||
{
|
{ return current_stacks_; }
|
||||||
if((current_ < 0) || (current_ >= history_.size())) { current_ = -1; return NOTHING; }
|
|
||||||
return str2stacks(history_.get(current_));
|
public IRecipe current_recipe()
|
||||||
}
|
{ return current_recipe_; }
|
||||||
|
|
||||||
public void next()
|
public void next()
|
||||||
{
|
{
|
||||||
if(history_.isEmpty()) { current_ = -1; return; }
|
if(history_.isEmpty()) {
|
||||||
current_ = ((++current_) >= history_.size()) ? (-1) : (current_);
|
current_ = -1;
|
||||||
|
} else {
|
||||||
|
current_ = ((++current_) >= history_.size()) ? (-1) : (current_);
|
||||||
|
}
|
||||||
|
update_current();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prev()
|
public void prev()
|
||||||
{
|
{
|
||||||
if(history_.isEmpty()) { current_ = -1; return; }
|
if(history_.isEmpty()) {
|
||||||
current_ = ((--current_) < -1) ? (history_.size()-1) : (current_);
|
current_ = -1;
|
||||||
|
} else {
|
||||||
|
current_ = ((--current_) < -1) ? (history_.size()-1) : (current_);
|
||||||
|
}
|
||||||
|
update_current();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reset_selection()
|
||||||
|
{ current_ = -1; update_current(); }
|
||||||
|
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
StringBuilder s = new StringBuilder("{ current:" + current_ + ", elements:[ ");
|
String rec = (current_recipe_==null) ? "none" : (current_recipe_.getRegistryName().toString());
|
||||||
|
StringBuilder s = new StringBuilder("{ current:" + current_ + ", recipe:'" + rec + "', elements:[ ");
|
||||||
for(int i=0; i<history_.size(); ++i) s.append("{i:").append(i).append(", e:[").append(history_.get(i)).append("]} ");
|
for(int i=0; i<history_.size(); ++i) s.append("{i:").append(i).append(", e:[").append(history_.get(i)).append("]} ");
|
||||||
s.append("]}");
|
s.append("]}");
|
||||||
return s.toString();
|
return s.toString();
|
||||||
|
@ -296,16 +341,22 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
{
|
{
|
||||||
protected static final int BUTTON_NEXT = 0;
|
protected static final int BUTTON_NEXT = 0;
|
||||||
protected static final int BUTTON_PREV = 1;
|
protected static final int BUTTON_PREV = 1;
|
||||||
protected static final int BUTTON_FROM_STORAGE = 2;
|
protected static final int BUTTON_CLEAR_GRID = 2;
|
||||||
protected static final int BUTTON_TO_STORAGE = 3;
|
protected static final int BUTTON_FROM_STORAGE = 3;
|
||||||
protected static final int BUTTON_FROM_PLAYER = 4;
|
protected static final int BUTTON_TO_STORAGE = 4;
|
||||||
protected static final int BUTTON_TO_PLAYER = 5;
|
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 ResourceLocation BACKGROUND = new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/treated_wood_crafting_table.png");
|
protected static final ResourceLocation BACKGROUND = new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/treated_wood_crafting_table.png");
|
||||||
protected final BTileEntity te;
|
protected final BTileEntity te;
|
||||||
|
protected final EntityPlayer player;
|
||||||
protected final ArrayList<GuiButton> buttons = new ArrayList<GuiButton>();
|
protected final ArrayList<GuiButton> buttons = new ArrayList<GuiButton>();
|
||||||
|
protected final boolean history_slot_tooltip[] = {false,false,false,false,false,false,false,false,false,false};
|
||||||
|
|
||||||
public BGui(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te)
|
public BGui(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te)
|
||||||
{ super(new BContainer(playerInventory, world, pos, te)); this.te = te; }
|
{ super(new BContainer(playerInventory, world, pos, te)); this.te = te; this.player=playerInventory.player; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -315,12 +366,15 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
final int x0=((width - xSize)/2), y0=((height - ySize)/2);
|
final int x0=((width - xSize)/2), y0=((height - ySize)/2);
|
||||||
buttons.clear();
|
buttons.clear();
|
||||||
if(with_assist) {
|
if(with_assist) {
|
||||||
buttons.add(addButton(new GuiButtonImage(BUTTON_NEXT, x0+156,y0+44, 12,12, 194,44, 12, BACKGROUND)));
|
buttons.add(addButton(new GuiButtonImage(BUTTON_NEXT, x0+158,y0+44, 12,12, 194,44, 12, BACKGROUND)));
|
||||||
buttons.add(addButton(new GuiButtonImage(BUTTON_PREV, x0+156,y0+30, 12,12, 180,30, 12, BACKGROUND)));
|
buttons.add(addButton(new GuiButtonImage(BUTTON_PREV, x0+158,y0+30, 12,12, 180,30, 12, BACKGROUND)));
|
||||||
// buttons.add(addButton(new GuiButtonImage(BUTTON_FROM_STORAGE, x0+49,y0+34, 9,17, 219,34, 17, BACKGROUND)));
|
buttons.add(addButton(new GuiButtonImage(BUTTON_CLEAR_GRID, x0+158,y0+58, 12,12, 194,8, 12, BACKGROUND)));
|
||||||
// buttons.add(addButton(new GuiButtonImage(BUTTON_TO_STORAGE, x0+49,y0+52, 9,17, 208,16, 17, BACKGROUND)));
|
if(with_assist_quickmove_buttons) {
|
||||||
// buttons.add(addButton(new GuiButtonImage(BUTTON_FROM_PLAYER, x0+77,y0+71, 17,9, 198,71, 9, BACKGROUND)));
|
buttons.add(addButton(new GuiButtonImage(BUTTON_FROM_STORAGE, x0+49, y0+34, 9,17, 219,34, 17, BACKGROUND)));
|
||||||
// buttons.add(addButton(new GuiButtonImage(BUTTON_TO_PLAYER, x0+59,y0+71, 17,9, 180,71, 9, BACKGROUND)));
|
buttons.add(addButton(new GuiButtonImage(BUTTON_TO_STORAGE, x0+49, y0+52, 9,17, 208,16, 17, BACKGROUND)));
|
||||||
|
buttons.add(addButton(new GuiButtonImage(BUTTON_FROM_PLAYER, x0+77, y0+71, 17,9, 198,71, 9, BACKGROUND)));
|
||||||
|
buttons.add(addButton(new GuiButtonImage(BUTTON_TO_PLAYER, x0+59, y0+71, 17,9, 180,71, 9, BACKGROUND)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,6 +386,26 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
renderHoveredToolTip(mouseX, mouseY);
|
renderHoveredToolTip(mouseX, mouseY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderHoveredToolTip(int mouseX, int mouseY)
|
||||||
|
{
|
||||||
|
if((!player.inventory.getItemStack().isEmpty()) || (getSlotUnderMouse() == null)) return;
|
||||||
|
final Slot slot = getSlotUnderMouse();
|
||||||
|
if(!slot.getStack().isEmpty()) { renderToolTip(slot.getStack(), mouseX, mouseY); return; }
|
||||||
|
if(with_assist) {
|
||||||
|
int hist_index = -1;
|
||||||
|
if(slot instanceof BSlotCrafting) {
|
||||||
|
hist_index = 0;
|
||||||
|
} else if(slot.inventory instanceof BInventoryCrafting) {
|
||||||
|
hist_index = slot.getSlotIndex() + 1;
|
||||||
|
}
|
||||||
|
if((hist_index < 0) || (hist_index >= history_slot_tooltip.length)) return;
|
||||||
|
if(!history_slot_tooltip[hist_index]) return;
|
||||||
|
ItemStack hist_stack = te.history.current().get(hist_index);
|
||||||
|
if(!hist_stack.isEmpty()) renderToolTip(hist_stack, mouseX, mouseY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
|
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
|
||||||
{
|
{
|
||||||
|
@ -340,14 +414,15 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
final int x0=((width - xSize)/2), y0=((height - ySize)/2);
|
final int x0=((width - xSize)/2), y0=((height - ySize)/2);
|
||||||
drawTexturedModalRect(x0, y0, 0, 0, xSize, ySize);
|
drawTexturedModalRect(x0, y0, 0, 0, xSize, ySize);
|
||||||
if(with_assist) {
|
if(with_assist) {
|
||||||
|
for(int i=0; i<history_slot_tooltip.length; ++i) history_slot_tooltip[i] = false;
|
||||||
List<ItemStack> crafting_template = te.history.current();
|
List<ItemStack> crafting_template = te.history.current();
|
||||||
if((crafting_template == null) || (crafting_template.isEmpty())) return;
|
if((crafting_template == null) || (crafting_template.isEmpty())) return;
|
||||||
if(inventorySlots.getSlot(0).getHasStack()) return;
|
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(Tuple<Integer, Integer> e : ((BContainer) inventorySlots).CRAFTING_SLOT_POSITIONS) {
|
for(Tuple<Integer, Integer> e : ((BContainer) inventorySlots).CRAFTING_SLOT_POSITIONS) {
|
||||||
|
if(i==0) continue; // explicitly here, that is the result slot.
|
||||||
if((inventorySlots.getSlot(i).getHasStack())) {
|
if((inventorySlots.getSlot(i).getHasStack())) {
|
||||||
if(!inventorySlots.getSlot(i).getStack().getItem().equals(crafting_template.get(i).getItem())) {
|
if(!inventorySlots.getSlot(i).getStack().isItemEqual(crafting_template.get(i))) {
|
||||||
return; // user has placed another recipe
|
return; // user has placed another recipe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,7 +433,14 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(Tuple<Integer, Integer> e : ((BContainer) inventorySlots).CRAFTING_SLOT_POSITIONS) {
|
for(Tuple<Integer, Integer> e : ((BContainer) inventorySlots).CRAFTING_SLOT_POSITIONS) {
|
||||||
final ItemStack stack = crafting_template.get(i);
|
final ItemStack stack = crafting_template.get(i);
|
||||||
if(!stack.isEmpty()) drawTemplateItemAt(stack, x0, y0, e.getFirst(), e.getSecond());
|
if(!stack.isEmpty()) {
|
||||||
|
if(!inventorySlots.getSlot(i).getHasStack()) history_slot_tooltip[i] = true;
|
||||||
|
if((i==0) && inventorySlots.getSlot(i).getStack().isItemEqual(crafting_template.get(i))) {
|
||||||
|
continue; // don't shade the output slot if the result can be crafted.
|
||||||
|
} else {
|
||||||
|
drawTemplateItemAt(stack, x0, y0, e.getFirst(), e.getSecond());
|
||||||
|
}
|
||||||
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -367,9 +449,10 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
|
|
||||||
protected void drawTemplateItemAt(ItemStack stack, int x0, int y0, int x, int y)
|
protected void drawTemplateItemAt(ItemStack stack, int x0, int y0, int x, int y)
|
||||||
{
|
{
|
||||||
|
final float main_zl = zLevel;
|
||||||
RenderHelper.disableStandardItemLighting();
|
RenderHelper.disableStandardItemLighting();
|
||||||
RenderHelper.enableGUIStandardItemLighting();
|
RenderHelper.enableGUIStandardItemLighting();
|
||||||
float zl = itemRender.zLevel;
|
final float zl = itemRender.zLevel;
|
||||||
itemRender.zLevel = -50;
|
itemRender.zLevel = -50;
|
||||||
itemRender.renderItemIntoGUI(stack, x0+x, y0+y);
|
itemRender.renderItemIntoGUI(stack, x0+x, y0+y);
|
||||||
itemRender.zLevel = zl;
|
itemRender.zLevel = zl;
|
||||||
|
@ -377,7 +460,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
GlStateManager.color(0.7f, 0.7f, 0.7f, 0.8f);
|
GlStateManager.color(0.7f, 0.7f, 0.7f, 0.8f);
|
||||||
mc.getTextureManager().bindTexture(BACKGROUND);
|
mc.getTextureManager().bindTexture(BACKGROUND);
|
||||||
drawTexturedModalRect(x0+x, y0+y, x, y, 16, 16);
|
drawTexturedModalRect(x0+x, y0+y, x, y, 16, 16);
|
||||||
|
RenderHelper.enableGUIStandardItemLighting();
|
||||||
RenderHelper.enableStandardItemLighting();
|
RenderHelper.enableStandardItemLighting();
|
||||||
|
zLevel = main_zl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -386,17 +471,58 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
switch(button.id) {
|
switch(button.id) {
|
||||||
case BUTTON_NEXT:
|
case BUTTON_NEXT:
|
||||||
case BUTTON_PREV:
|
case BUTTON_PREV:
|
||||||
|
case BUTTON_CLEAR_GRID:
|
||||||
case BUTTON_FROM_STORAGE:
|
case BUTTON_FROM_STORAGE:
|
||||||
case BUTTON_TO_STORAGE:
|
case BUTTON_TO_STORAGE:
|
||||||
case BUTTON_FROM_PLAYER:
|
case BUTTON_FROM_PLAYER:
|
||||||
case BUTTON_TO_PLAYER: {
|
case BUTTON_TO_PLAYER:
|
||||||
|
case ACTION_PLACE_CURRENT_HISTORY_SEL: {
|
||||||
NBTTagCompound nbt = new NBTTagCompound();
|
NBTTagCompound nbt = new NBTTagCompound();
|
||||||
nbt.setInteger("button", button.id);
|
nbt.setInteger("action", button.id);
|
||||||
Networking.PacketTileNotify.sendToServer(te, nbt);
|
Networking.PacketTileNotify.sendToServer(te, nbt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleMouseClick(Slot slot, int slotId, int mouseButton, ClickType type)
|
||||||
|
{
|
||||||
|
if(type == ClickType.PICKUP) {
|
||||||
|
boolean place_refab = (slot instanceof BSlotCrafting) && (!slot.getHasStack());
|
||||||
|
if(place_refab && with_assist_direct_history_refab) onHistoryItemPlacement(); // place before crafting -> direct item pick
|
||||||
|
super.handleMouseClick(slot, slotId, mouseButton, type);
|
||||||
|
if(place_refab && (!with_assist_direct_history_refab)) onHistoryItemPlacement(); // place after crafting -> confirmation first
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if((type == ClickType.QUICK_MOVE) && (slotId > 9) && (slot.getHasStack())) { // container slots 0..9 are crafting output and grid
|
||||||
|
List<ItemStack> history = te.history.current();
|
||||||
|
boolean palce_in_crafting_grid = (!history.isEmpty());
|
||||||
|
if(!palce_in_crafting_grid) {
|
||||||
|
for(int i=0; i<9; ++i) {
|
||||||
|
if(!(te.getStackInSlot(i).isEmpty())) { palce_in_crafting_grid = true; break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(palce_in_crafting_grid) {
|
||||||
|
NBTTagCompound nbt = new NBTTagCompound();
|
||||||
|
nbt.setInteger("action", ACTION_PLACE_SHIFTCLICKED_STACK);
|
||||||
|
nbt.setInteger("containerslot", slotId);
|
||||||
|
Networking.PacketTileNotify.sendToServer(te, nbt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.handleMouseClick(slot, slotId, mouseButton, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onHistoryItemPlacement()
|
||||||
|
{
|
||||||
|
if(te.history.current().isEmpty()) return;
|
||||||
|
final Slot resultSlot = this.getSlotUnderMouse(); // double check
|
||||||
|
if(!(resultSlot instanceof BSlotCrafting)) return;
|
||||||
|
NBTTagCompound nbt = new NBTTagCompound();
|
||||||
|
nbt.setInteger("action", ACTION_PLACE_CURRENT_HISTORY_SEL);
|
||||||
|
Networking.PacketTileNotify.sendToServer(te, nbt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -415,11 +541,12 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
protected void onCrafting(ItemStack stack)
|
protected void onCrafting(ItemStack stack)
|
||||||
{
|
{
|
||||||
if((with_assist) && ((player.world!=null) && (!(player.world.isRemote))) && (!stack.isEmpty())) {
|
if((with_assist) && ((player.world!=null) && (!(player.world.isRemote))) && (!stack.isEmpty())) {
|
||||||
|
final IRecipe recipe = ((InventoryCraftResult)this.inventory).getRecipeUsed();
|
||||||
final ArrayList<ItemStack> grid = new ArrayList<ItemStack>();
|
final ArrayList<ItemStack> grid = new ArrayList<ItemStack>();
|
||||||
grid.add(stack);
|
grid.add(stack);
|
||||||
for(int i = 0; i < 9; ++i) grid.add(te.stacks.get(i));
|
for(int i = 0; i < 9; ++i) grid.add(te.stacks.get(i));
|
||||||
te.history.add(grid);
|
te.history.add(grid, recipe);
|
||||||
te.history.reset_curent();
|
te.history.reset_current();
|
||||||
te.syncHistory(player);
|
te.syncHistory(player);
|
||||||
}
|
}
|
||||||
super.onCrafting(stack);
|
super.onCrafting(stack);
|
||||||
|
@ -430,7 +557,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
// Crafting container
|
// Crafting container
|
||||||
//--------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
private static class BContainer extends Container
|
public static class BContainer extends Container
|
||||||
{
|
{
|
||||||
private final World world;
|
private final World world;
|
||||||
private final BlockPos pos;
|
private final BlockPos pos;
|
||||||
|
@ -449,28 +576,33 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
this.te = te;
|
this.te = te;
|
||||||
craftMatrix = new BInventoryCrafting(this, te);
|
craftMatrix = new BInventoryCrafting(this, te);
|
||||||
craftMatrix.openInventory(player);
|
craftMatrix.openInventory(player);
|
||||||
|
// container slotId 0 === crafting output
|
||||||
addSlotToContainer(new BSlotCrafting(te, playerInventory.player, craftMatrix, craftResult, 0, 134, 35));
|
addSlotToContainer(new BSlotCrafting(te, playerInventory.player, craftMatrix, craftResult, 0, 134, 35));
|
||||||
slotpositions.add(new Tuple<>(134, 35));
|
slotpositions.add(new Tuple<>(134, 35));
|
||||||
|
// container slotId 1..9 === TE slots 0..8
|
||||||
for(int y=0; y<3; ++y) {
|
for(int y=0; y<3; ++y) {
|
||||||
for(int x=0; x<3; ++x) {
|
for(int x=0; x<3; ++x) {
|
||||||
int xpos = 60+x*18;
|
int xpos = 60+x*18;
|
||||||
int ypos = 17+y*18;
|
int ypos = 17+y*18;
|
||||||
addSlotToContainer(new Slot(craftMatrix, x+y*3, xpos, ypos)); // block slots 0..8
|
addSlotToContainer(new Slot(craftMatrix, x+y*3, xpos, ypos));
|
||||||
slotpositions.add(new Tuple<>(xpos, ypos));
|
slotpositions.add(new Tuple<>(xpos, ypos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CRAFTING_SLOT_POSITIONS = ImmutableList.copyOf(slotpositions);
|
CRAFTING_SLOT_POSITIONS = ImmutableList.copyOf(slotpositions);
|
||||||
|
// container slotId 10..36 === player slots: 9..35
|
||||||
for(int y=0; y<3; ++y) {
|
for(int y=0; y<3; ++y) {
|
||||||
for (int x=0; x<9; ++x) {
|
for(int x=0; x<9; ++x) {
|
||||||
addSlotToContainer(new Slot(playerInventory, x+y*9+9, 8+x*18, 86+y*18)); // player slots: 9..35
|
addSlotToContainer(new Slot(playerInventory, x+y*9+9, 8+x*18, 86+y*18));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// container slotId 37..45 === player slots: 0..8
|
||||||
for(int x=0; x<9; ++x) {
|
for(int x=0; x<9; ++x) {
|
||||||
addSlotToContainer(new Slot(playerInventory, x, 8+x*18, 144)); // player slots: 0..8
|
addSlotToContainer(new Slot(playerInventory, x, 8+x*18, 144));
|
||||||
}
|
}
|
||||||
|
// container slotId 46..53 === TE slots 9..17 (storage)
|
||||||
for(int y=0; y<4; ++y) {
|
for(int y=0; y<4; ++y) {
|
||||||
for (int x=0; x<2; ++x) {
|
for(int x=0; x<2; ++x) {
|
||||||
addSlotToContainer(new Slot(craftMatrix, x+y*2+9, 8+x*18, 9+y*18)); // block slots 9..17
|
addSlotToContainer(new Slot(craftMatrix, x+y*2+9, 8+x*18, 9+y*18));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onCraftMatrixChanged(craftMatrix);
|
onCraftMatrixChanged(craftMatrix);
|
||||||
|
@ -541,6 +673,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
}
|
}
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCraftingMatrixSlot(int slot_index, ItemStack stack)
|
||||||
|
{ craftMatrix.setInventorySlotContents(slot_index, stack.copy()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -599,7 +734,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
//--------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------
|
||||||
public static class BTileEntity extends TileEntity implements IInventory, Networking.IPacketReceiver
|
public static class BTileEntity extends TileEntity implements IInventory, Networking.IPacketReceiver
|
||||||
{
|
{
|
||||||
|
public static final int CRAFTING_SLOTS_BEGIN = 0;
|
||||||
public static final int NUM_OF_CRAFTING_SLOTS = 9;
|
public static final int NUM_OF_CRAFTING_SLOTS = 9;
|
||||||
|
public static final int STORAGE_SLOTS_BEGIN = NUM_OF_CRAFTING_SLOTS;
|
||||||
public static final int NUM_OF_STORAGE_SLOTS = 8;
|
public static final int NUM_OF_STORAGE_SLOTS = 8;
|
||||||
public static final int NUM_OF_SLOTS = NUM_OF_CRAFTING_SLOTS+NUM_OF_STORAGE_SLOTS;
|
public static final int NUM_OF_SLOTS = NUM_OF_CRAFTING_SLOTS+NUM_OF_STORAGE_SLOTS;
|
||||||
protected NonNullList<ItemStack> stacks;
|
protected NonNullList<ItemStack> stacks;
|
||||||
|
@ -625,35 +762,384 @@ public class BlockDecorCraftingTable extends BlockDecorDirected
|
||||||
history.write(compound);
|
history.write(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private aux methods ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
private boolean itemstack_recipe_match(ItemStack grid_stack, ItemStack history_stack)
|
||||||
|
{
|
||||||
|
if(history.current_recipe()!=null) {
|
||||||
|
boolean grid_match, dist_match;
|
||||||
|
for(final Ingredient ingredient:history.current_recipe().getIngredients()) {
|
||||||
|
grid_match = false; dist_match = false;
|
||||||
|
for(final ItemStack match:ingredient.getMatchingStacks()) {
|
||||||
|
if(match.isItemEqualIgnoreDurability(grid_stack)) dist_match = true;
|
||||||
|
if(match.isItemEqualIgnoreDurability(history_stack)) grid_match = true;
|
||||||
|
if(dist_match && grid_match) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ItemStack> crafting_slot_stacks_to_add()
|
||||||
|
{
|
||||||
|
final ArrayList<ItemStack> slots = new ArrayList<ItemStack>();
|
||||||
|
final List<ItemStack> tocraft = history.current();
|
||||||
|
final int stack_sizes[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1};
|
||||||
|
if(tocraft.isEmpty()) return slots;
|
||||||
|
for(int i=0; i<9; ++i) {
|
||||||
|
if((i+CraftingHistory.INPUT_STACKS_BEGIN) >= tocraft.size()) break;
|
||||||
|
final ItemStack needed = tocraft.get(i+CraftingHistory.INPUT_STACKS_BEGIN);
|
||||||
|
final ItemStack palced = getStackInSlot(i+CRAFTING_SLOTS_BEGIN);
|
||||||
|
if(needed.isEmpty() && (!palced.isEmpty())) return slots; // history vs grid mismatch.
|
||||||
|
if((!palced.isEmpty()) && (!itemstack_recipe_match(needed, palced))) return slots; // also mismatch
|
||||||
|
if(!needed.isEmpty()) stack_sizes[i] = palced.getCount();
|
||||||
|
}
|
||||||
|
int min_placed = 64, max_placed=0;
|
||||||
|
for(int i=0; i<9; ++i) { // todo: check if java has something like std::accumulate<>()
|
||||||
|
if(stack_sizes[i] < 0) continue;
|
||||||
|
min_placed = Math.min(min_placed, stack_sizes[i]);
|
||||||
|
max_placed = Math.max(max_placed, stack_sizes[i]);
|
||||||
|
}
|
||||||
|
int fillup_size = (max_placed <= min_placed) ? (min_placed + 1) : max_placed;
|
||||||
|
for(int i=0; i<9; ++i) {
|
||||||
|
if(stack_sizes[i] < 0) continue;
|
||||||
|
if(fillup_size > getStackInSlot(i+CRAFTING_SLOTS_BEGIN).getMaxStackSize()) return slots; // can't fillup all
|
||||||
|
}
|
||||||
|
for(int i=0; i<9; ++i) {
|
||||||
|
if(stack_sizes[i] < 0) {
|
||||||
|
slots.add(ItemStack.EMPTY);
|
||||||
|
} else {
|
||||||
|
ItemStack st = getStackInSlot(i+CRAFTING_SLOTS_BEGIN).copy();
|
||||||
|
if(st.isEmpty()) {
|
||||||
|
st = tocraft.get(i+CraftingHistory.INPUT_STACKS_BEGIN).copy();
|
||||||
|
st.setCount(Math.min(st.getMaxStackSize(), fillup_size));
|
||||||
|
} else {
|
||||||
|
st.setCount(MathHelper.clamp(fillup_size-st.getCount(), 0, st.getMaxStackSize()));
|
||||||
|
}
|
||||||
|
slots.add(st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return slots;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves as much items from the stack to the slots in range [first_slot, last_slot] of the inventory,
|
||||||
|
* filling up existing stacks first, then (player inventory only) checks appropriate empty slots next
|
||||||
|
* to stacks that have that item already, and last uses any empty slot that can be found.
|
||||||
|
* Returns the stack that is still remaining in the referenced `stack`.
|
||||||
|
*/
|
||||||
|
private ItemStack move_stack_to_inventory(final ItemStack stack_to_move, IInventory inventory, final int slot_begin, final int slot_end, boolean only_fillup)
|
||||||
|
{
|
||||||
|
final ItemStack mvstack = stack_to_move.copy();
|
||||||
|
if((mvstack.isEmpty()) || (slot_begin < 0) || (slot_end > inventory.getSizeInventory())) return mvstack;
|
||||||
|
// first iteration: fillup existing stacks
|
||||||
|
for(int i = slot_begin; i < slot_end; ++i) {
|
||||||
|
final ItemStack stack = inventory.getStackInSlot(i);
|
||||||
|
if((stack.isEmpty()) || (!stack.isItemEqual(mvstack))) continue;
|
||||||
|
int nmax = stack.getMaxStackSize() - stack.getCount();
|
||||||
|
if(mvstack.getCount() <= nmax) {
|
||||||
|
stack.setCount(stack.getCount()+mvstack.getCount());
|
||||||
|
mvstack.setCount(0);
|
||||||
|
inventory.setInventorySlotContents(i, stack);
|
||||||
|
return mvstack;
|
||||||
|
} else {
|
||||||
|
stack.setCount(stack.getMaxStackSize());
|
||||||
|
mvstack.shrink(nmax);
|
||||||
|
inventory.setInventorySlotContents(i, stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(only_fillup) return mvstack;
|
||||||
|
if(inventory instanceof InventoryPlayer) {
|
||||||
|
// second iteration: use appropriate empty slots
|
||||||
|
for(int i = slot_begin+1; i < slot_end-1; ++i) {
|
||||||
|
final ItemStack stack = inventory.getStackInSlot(i);
|
||||||
|
if(!stack.isEmpty()) continue;
|
||||||
|
if((!inventory.getStackInSlot(i+1).isItemEqual(mvstack)) && (!inventory.getStackInSlot(i-1).isItemEqual(mvstack))) continue;
|
||||||
|
inventory.setInventorySlotContents(i, mvstack.copy());
|
||||||
|
mvstack.setCount(0);
|
||||||
|
return mvstack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// third iteration: use any empty slots
|
||||||
|
for(int i = slot_begin; i < slot_end; ++i) {
|
||||||
|
final ItemStack stack = inventory.getStackInSlot(i);
|
||||||
|
if(!stack.isEmpty()) continue;
|
||||||
|
inventory.setInventorySlotContents(i, mvstack.copy());
|
||||||
|
mvstack.setCount(0);
|
||||||
|
return mvstack;
|
||||||
|
}
|
||||||
|
return mvstack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves as much items from the slots in range [first_slot, last_slot] of the inventory into a new stack.
|
||||||
|
* Implicitly shrinks the inventory stacks and the `request_stack`.
|
||||||
|
*/
|
||||||
|
private ItemStack move_stack_from_inventory(IInventory inventory, final ItemStack request_stack, final int slot_begin, final int slot_end)
|
||||||
|
{
|
||||||
|
ItemStack fetched_stack = request_stack.copy();
|
||||||
|
fetched_stack.setCount(0);
|
||||||
|
int n_left = request_stack.getCount();
|
||||||
|
while(n_left > 0) {
|
||||||
|
int smallest_stack_size = 0;
|
||||||
|
int smallest_stack_index = -1;
|
||||||
|
for(int i = slot_begin; i < slot_end; ++i) {
|
||||||
|
final ItemStack stack = inventory.getStackInSlot(i);
|
||||||
|
if((!stack.isEmpty()) && (stack.isItemEqual(request_stack))) {
|
||||||
|
// Never automatically place stuff with nbt (except a few allowed like "Damage"),
|
||||||
|
// as this could be a full crate, a valuable tool item, etc. For these recipes
|
||||||
|
// the user has to place this item manually.
|
||||||
|
if(stack.hasTagCompound()) {
|
||||||
|
final NBTTagCompound nbt = stack.getTagCompound();
|
||||||
|
int n = stack.getTagCompound().getSize();
|
||||||
|
if((n > 0) && (stack.getTagCompound().hasKey("Damage"))) --n;
|
||||||
|
if(n > 0) continue;
|
||||||
|
}
|
||||||
|
fetched_stack = stack.copy(); // copy exact stack with nbt and tool damage, otherwise we have an automagical repair of items.
|
||||||
|
fetched_stack.setCount(0);
|
||||||
|
int n = stack.getCount();
|
||||||
|
if((n < smallest_stack_size) || (smallest_stack_size <= 0)) {
|
||||||
|
smallest_stack_size = n;
|
||||||
|
smallest_stack_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(smallest_stack_index < 0) {
|
||||||
|
break; // no more items available
|
||||||
|
} else {
|
||||||
|
int n = Math.min(n_left, smallest_stack_size);
|
||||||
|
n_left -= n;
|
||||||
|
fetched_stack.grow(n);
|
||||||
|
ItemStack st = inventory.getStackInSlot(smallest_stack_index);
|
||||||
|
st.shrink(n);
|
||||||
|
inventory.setInventorySlotContents(smallest_stack_index, st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fetched_stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean clear_grid_to_storage(EntityPlayer player)
|
||||||
|
{
|
||||||
|
boolean changed = false;
|
||||||
|
for(int grid_i = CRAFTING_SLOTS_BEGIN; grid_i < (CRAFTING_SLOTS_BEGIN + NUM_OF_CRAFTING_SLOTS); ++grid_i) {
|
||||||
|
ItemStack stack = getStackInSlot(grid_i);
|
||||||
|
if(stack.isEmpty()) continue;
|
||||||
|
ItemStack remaining = move_stack_to_inventory(stack, this, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS, false);
|
||||||
|
setInventorySlotContents(grid_i, remaining);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean clear_grid_to_player(EntityPlayer player)
|
||||||
|
{
|
||||||
|
boolean changed = false;
|
||||||
|
for(int grid_i = CRAFTING_SLOTS_BEGIN; grid_i < (CRAFTING_SLOTS_BEGIN + NUM_OF_CRAFTING_SLOTS); ++grid_i) {
|
||||||
|
ItemStack remaining = getStackInSlot(grid_i);
|
||||||
|
if(remaining.isEmpty()) continue;
|
||||||
|
remaining = move_stack_to_inventory(remaining, player.inventory,9, 36, true); // prefer filling up inventory stacks
|
||||||
|
remaining = move_stack_to_inventory(remaining, player.inventory,0, 9, true); // then fill up the hotbar stacks
|
||||||
|
remaining = move_stack_to_inventory(remaining, player.inventory,9, 36, false); // then allow empty stacks in inventory
|
||||||
|
remaining = move_stack_to_inventory(remaining, player.inventory,0, 9, false); // then new stacks in the hotbar
|
||||||
|
this.setInventorySlotContents(grid_i, remaining);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EnumRefabPlacement { UNCHANGED, INCOMPLETE, PLACED }
|
||||||
|
private EnumRefabPlacement place_refab_stacks(IInventory inventory, final int slot_begin, final int slot_end)
|
||||||
|
{
|
||||||
|
List<ItemStack> to_fill = crafting_slot_stacks_to_add();
|
||||||
|
boolean slots_changed = false;
|
||||||
|
boolean missing_item = false;
|
||||||
|
int num_slots_placed = 0;
|
||||||
|
if(!to_fill.isEmpty()) {
|
||||||
|
for(int it_guard=63; it_guard>=0; --it_guard) {
|
||||||
|
boolean slots_updated = false;
|
||||||
|
for(int i = 0; i < 9; ++i) {
|
||||||
|
final ItemStack req_stack = to_fill.get(i).copy();
|
||||||
|
if(req_stack.isEmpty()) continue;
|
||||||
|
req_stack.setCount(1);
|
||||||
|
to_fill.get(i).shrink(1);
|
||||||
|
final ItemStack mv_stack = move_stack_from_inventory(inventory, req_stack, slot_begin, slot_end);
|
||||||
|
if(mv_stack.isEmpty()) { missing_item=true; continue; }
|
||||||
|
// sizes already checked
|
||||||
|
ItemStack grid_stack = getStackInSlot(i + CRAFTING_SLOTS_BEGIN).copy();
|
||||||
|
if(grid_stack.isEmpty()) {
|
||||||
|
grid_stack = mv_stack.copy();
|
||||||
|
} else {
|
||||||
|
grid_stack.grow(mv_stack.getCount());
|
||||||
|
}
|
||||||
|
setInventorySlotContents(i + CRAFTING_SLOTS_BEGIN, grid_stack);
|
||||||
|
slots_changed = true;
|
||||||
|
slots_updated = true;
|
||||||
|
}
|
||||||
|
if(!slots_updated) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!slots_changed) {
|
||||||
|
return EnumRefabPlacement.UNCHANGED;
|
||||||
|
} else if(missing_item) {
|
||||||
|
return EnumRefabPlacement.INCOMPLETE;
|
||||||
|
} else {
|
||||||
|
return EnumRefabPlacement.PLACED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private EnumRefabPlacement distribute_stack(IInventory inventory, final int slotno)
|
||||||
|
{
|
||||||
|
List<ItemStack> to_refab = crafting_slot_stacks_to_add();
|
||||||
|
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};
|
||||||
|
int max_matching_stack_size = -1;
|
||||||
|
int min_matching_stack_size = 65;
|
||||||
|
int total_num_missing_stacks = 0;
|
||||||
|
for(int i=0; i<9; ++i) {
|
||||||
|
final ItemStack grid_stack = getStackInSlot(i + CRAFTING_SLOTS_BEGIN);
|
||||||
|
final ItemStack refab_stack = to_refab.isEmpty() ? ItemStack.EMPTY : to_refab.get(i).copy();
|
||||||
|
if((!grid_stack.isEmpty()) && (grid_stack.isItemEqual(to_distribute))) {
|
||||||
|
matching_grid_stack_sizes[i] = grid_stack.getCount();
|
||||||
|
total_num_missing_stacks += grid_stack.getMaxStackSize()-grid_stack.getCount();
|
||||||
|
if(max_matching_stack_size < matching_grid_stack_sizes[i]) max_matching_stack_size = matching_grid_stack_sizes[i];
|
||||||
|
if(min_matching_stack_size > matching_grid_stack_sizes[i]) min_matching_stack_size = matching_grid_stack_sizes[i];
|
||||||
|
} else if((!refab_stack.isEmpty()) && (refab_stack.isItemEqual(to_distribute))) {
|
||||||
|
matching_grid_stack_sizes[i] = 0;
|
||||||
|
total_num_missing_stacks += grid_stack.getMaxStackSize();
|
||||||
|
if(max_matching_stack_size < matching_grid_stack_sizes[i]) max_matching_stack_size = matching_grid_stack_sizes[i];
|
||||||
|
if(min_matching_stack_size > matching_grid_stack_sizes[i]) min_matching_stack_size = matching_grid_stack_sizes[i];
|
||||||
|
} else if(grid_stack.isEmpty() && (!refab_stack.isEmpty())) {
|
||||||
|
if(itemstack_recipe_match(to_distribute, refab_stack)) {
|
||||||
|
matching_grid_stack_sizes[i] = 0;
|
||||||
|
total_num_missing_stacks += grid_stack.getMaxStackSize();
|
||||||
|
if(max_matching_stack_size < matching_grid_stack_sizes[i]) max_matching_stack_size = matching_grid_stack_sizes[i];
|
||||||
|
if(min_matching_stack_size > matching_grid_stack_sizes[i]) min_matching_stack_size = matching_grid_stack_sizes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(min_matching_stack_size < 0) return EnumRefabPlacement.UNCHANGED;
|
||||||
|
final int stack_limit_size = Math.min(to_distribute.getMaxStackSize(), getInventoryStackLimit());
|
||||||
|
if(min_matching_stack_size >= stack_limit_size) return EnumRefabPlacement.UNCHANGED;
|
||||||
|
int n_to_distribute = to_distribute.getCount();
|
||||||
|
for(int it_guard=63; it_guard>=0; --it_guard) {
|
||||||
|
if(n_to_distribute <= 0) break;
|
||||||
|
for(int i=0; i<9; ++i) {
|
||||||
|
if(n_to_distribute <= 0) break;
|
||||||
|
if(matching_grid_stack_sizes[i] == min_matching_stack_size) {
|
||||||
|
++matching_grid_stack_sizes[i];
|
||||||
|
--n_to_distribute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(min_matching_stack_size < max_matching_stack_size) {
|
||||||
|
++min_matching_stack_size; // distribute short stacks
|
||||||
|
} else {
|
||||||
|
++min_matching_stack_size; // stacks even, increase all
|
||||||
|
max_matching_stack_size = min_matching_stack_size;
|
||||||
|
}
|
||||||
|
if(min_matching_stack_size >= stack_limit_size) break; // all full
|
||||||
|
}
|
||||||
|
if(n_to_distribute == to_distribute.getCount()) return EnumRefabPlacement.UNCHANGED; // was already full
|
||||||
|
if(n_to_distribute <= 0) {
|
||||||
|
inventory.setInventorySlotContents(slotno, ItemStack.EMPTY);
|
||||||
|
} else {
|
||||||
|
to_distribute.setCount(n_to_distribute);
|
||||||
|
inventory.setInventorySlotContents(slotno, to_distribute);
|
||||||
|
}
|
||||||
|
for(int i=0; i<9; ++i) {
|
||||||
|
if(matching_grid_stack_sizes[i] < 0) continue;
|
||||||
|
ItemStack grid_stack = getStackInSlot(i + CRAFTING_SLOTS_BEGIN).copy();
|
||||||
|
if(grid_stack.isEmpty()) grid_stack = to_distribute.copy();
|
||||||
|
grid_stack.setCount(matching_grid_stack_sizes[i]);
|
||||||
|
setInventorySlotContents(i + CRAFTING_SLOTS_BEGIN, grid_stack);
|
||||||
|
}
|
||||||
|
return EnumRefabPlacement.PLACED;
|
||||||
|
}
|
||||||
|
|
||||||
// Networking.IPacketReceiver --------------------------------------------------------------
|
// Networking.IPacketReceiver --------------------------------------------------------------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClientPacketReceived(EntityPlayer player, NBTTagCompound nbt)
|
public void onClientPacketReceived(EntityPlayer player, NBTTagCompound nbt)
|
||||||
{
|
{
|
||||||
if(with_assist && nbt.hasKey("button")) {
|
if((world.isRemote) || (!(player.openContainer instanceof BContainer))) return;
|
||||||
switch(nbt.getInteger("button")) {
|
final BContainer container = (BContainer)player.openContainer;
|
||||||
case BGui.BUTTON_NEXT:
|
if(container.te != this) return;
|
||||||
|
boolean te_changed = false;
|
||||||
|
boolean player_inventory_changed = false;
|
||||||
|
if(with_assist && nbt.hasKey("action")) {
|
||||||
|
switch(nbt.getInteger("action")) {
|
||||||
|
case BGui.BUTTON_NEXT: {
|
||||||
history.next();
|
history.next();
|
||||||
syncHistory(player);
|
syncHistory(player);
|
||||||
break;
|
// implicitly clear the grid, so that the player can see the refab, and that no recipe is active.
|
||||||
case BGui.BUTTON_PREV:
|
if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; }
|
||||||
|
if(clear_grid_to_storage(player)) te_changed = true;
|
||||||
|
} break;
|
||||||
|
case BGui.BUTTON_PREV: {
|
||||||
history.prev();
|
history.prev();
|
||||||
syncHistory(player);
|
syncHistory(player);
|
||||||
break;
|
if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; }
|
||||||
case BGui.BUTTON_FROM_STORAGE:
|
if(clear_grid_to_storage(player)) te_changed = true;
|
||||||
//System.out.println("BUTTON_FROM_STORAGE");
|
} break;
|
||||||
break;
|
case BGui.BUTTON_CLEAR_GRID: {
|
||||||
case BGui.BUTTON_TO_STORAGE:
|
history.reset_selection();
|
||||||
//System.out.println("BUTTON_TO_STORAGE");
|
syncHistory(player);
|
||||||
break;
|
if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; }
|
||||||
case BGui.BUTTON_FROM_PLAYER:
|
if(clear_grid_to_storage(player)) te_changed = true;
|
||||||
//System.out.println("BUTTON_FROM_PLAYER");
|
} break;
|
||||||
break;
|
case BGui.BUTTON_TO_STORAGE: {
|
||||||
case BGui.BUTTON_TO_PLAYER:
|
if(clear_grid_to_storage(player)) te_changed = true;
|
||||||
//System.out.println("BUTTON_TO_PLAYER");
|
} break;
|
||||||
break;
|
case BGui.BUTTON_TO_PLAYER: {
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
if(from_storage != EnumRefabPlacement.UNCHANGED) te_changed = true;
|
||||||
|
if(from_storage != EnumRefabPlacement.PLACED) {
|
||||||
|
EnumRefabPlacement from_player_inv = place_refab_stacks(player.inventory, 9, 36);
|
||||||
|
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);
|
||||||
|
if(from_hotbar != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case BGui.ACTION_PLACE_SHIFTCLICKED_STACK: {
|
||||||
|
final int container_slot_id = nbt.getInteger("containerslot");
|
||||||
|
if((container_slot_id < 10) || (container_slot_id > 53)) break; // out of range
|
||||||
|
if(container_slot_id >= 46) {
|
||||||
|
// from storage
|
||||||
|
final int storage_slot = container_slot_id - 46 + STORAGE_SLOTS_BEGIN;
|
||||||
|
EnumRefabPlacement stat = distribute_stack(this, storage_slot);
|
||||||
|
if(stat != EnumRefabPlacement.UNCHANGED) te_changed = true;
|
||||||
|
} else {
|
||||||
|
// from player
|
||||||
|
int player_slot = (container_slot_id >= 37) ? (container_slot_id-37) : (container_slot_id-10+9);
|
||||||
|
EnumRefabPlacement stat = distribute_stack(player.inventory, player_slot);
|
||||||
|
if(stat != EnumRefabPlacement.UNCHANGED) { player_inventory_changed = true; te_changed = true; }
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(te_changed) markDirty();
|
||||||
|
if(player_inventory_changed) player.inventory.markDirty();
|
||||||
|
if(te_changed || player_inventory_changed) {
|
||||||
|
container.onCraftMatrixChanged(this);
|
||||||
|
container.detectAndSendChanges();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -107,6 +107,9 @@ public class ModConfig
|
||||||
@Config.Name("Without ladder speed boost")
|
@Config.Name("Without ladder speed boost")
|
||||||
public boolean without_ladder_speed_boost = false;
|
public boolean without_ladder_speed_boost = false;
|
||||||
|
|
||||||
|
@Config.Comment({"Disable history refabrication feature of the treated wood crafting table."})
|
||||||
|
@Config.Name("Without crafting table history")
|
||||||
|
public boolean without_crafting_table_history = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Config.Comment({
|
@Config.Comment({
|
||||||
|
@ -192,6 +195,12 @@ public class ModConfig
|
||||||
@Config.Name("Chairs: Stand up chance %")
|
@Config.Name("Chairs: Stand up chance %")
|
||||||
@Config.RangeDouble(min=0.001, max=10)
|
@Config.RangeDouble(min=0.001, max=10)
|
||||||
public double chair_mob_standup_probability_percent = 1;
|
public double chair_mob_standup_probability_percent = 1;
|
||||||
|
|
||||||
|
@Config.Comment({"Enables small quick-move arrows from/to player/block storage. " +
|
||||||
|
"Makes the UI a bit too busy, therefore disabled by default."
|
||||||
|
})
|
||||||
|
@Config.Name("Crafting table: Move buttons")
|
||||||
|
public boolean with_crafting_quickmove_buttons = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -251,7 +260,7 @@ public class ModConfig
|
||||||
if(tweaks.furnace_smelts_nuggets) ModRecipes.furnaceRecipeOverrideSmeltsOresToNuggets();
|
if(tweaks.furnace_smelts_nuggets) ModRecipes.furnaceRecipeOverrideSmeltsOresToNuggets();
|
||||||
BlockDecorChair.on_config(optout.without_chair_sitting, optout.without_mob_chair_sitting, tweaks.chair_mob_sitting_probability_percent, tweaks.chair_mob_standup_probability_percent);
|
BlockDecorChair.on_config(optout.without_chair_sitting, optout.without_mob_chair_sitting, tweaks.chair_mob_sitting_probability_percent, tweaks.chair_mob_standup_probability_percent);
|
||||||
BlockDecorLadder.on_config(optout.without_ladder_speed_boost);
|
BlockDecorLadder.on_config(optout.without_ladder_speed_boost);
|
||||||
BlockDecorCraftingTable.on_config(!zmisc.with_experimental);
|
BlockDecorCraftingTable.on_config(optout.without_crafting_table_history, false, tweaks.with_crafting_quickmove_buttons);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,13 @@
|
||||||
*/
|
*/
|
||||||
package wile.engineersdecor.eapi.jei;
|
package wile.engineersdecor.eapi.jei;
|
||||||
|
|
||||||
|
import wile.engineersdecor.ModEngineersDecor;
|
||||||
|
import wile.engineersdecor.blocks.BlockDecorCraftingTable;
|
||||||
|
import wile.engineersdecor.blocks.ModBlocks;
|
||||||
|
import wile.engineersdecor.detail.ModConfig;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import wile.engineersdecor.ModEngineersDecor;
|
|
||||||
import wile.engineersdecor.blocks.ModBlocks;
|
|
||||||
import wile.engineersdecor.detail.ModConfig;
|
|
||||||
|
|
||||||
@mezz.jei.api.JEIPlugin
|
@mezz.jei.api.JEIPlugin
|
||||||
public class JEIPlugin implements mezz.jei.api.IModPlugin
|
public class JEIPlugin implements mezz.jei.api.IModPlugin
|
||||||
|
@ -22,6 +23,7 @@ public class JEIPlugin implements mezz.jei.api.IModPlugin
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public void register(mezz.jei.api.IModRegistry registry)
|
public void register(mezz.jei.api.IModRegistry registry)
|
||||||
{
|
{
|
||||||
|
// Block/item hiding
|
||||||
try {
|
try {
|
||||||
for(Block e:ModBlocks.getRegisteredBlocks()) {
|
for(Block e:ModBlocks.getRegisteredBlocks()) {
|
||||||
if(ModConfig.isOptedOut(e)) {
|
if(ModConfig.isOptedOut(e)) {
|
||||||
|
@ -37,7 +39,20 @@ public class JEIPlugin implements mezz.jei.api.IModPlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(Throwable e) {
|
} catch(Throwable e) {
|
||||||
ModEngineersDecor.logger.warn("Exception in JEI opt-out processing: '" + e.getMessage() + "', skipping further JEI processing.");
|
ModEngineersDecor.logger.warn("Exception in JEI opt-out processing: '" + e.getMessage() + "', skipping further JEI optout processing.");
|
||||||
|
}
|
||||||
|
// Crafting table registration
|
||||||
|
if(!ModConfig.optout.without_crafting_table) {
|
||||||
|
try {
|
||||||
|
mezz.jei.api.recipe.transfer.IRecipeTransferRegistry recipeTranferRegistry = registry.getRecipeTransferRegistry();
|
||||||
|
recipeTranferRegistry.addRecipeTransferHandler(
|
||||||
|
BlockDecorCraftingTable.BContainer.class,
|
||||||
|
mezz.jei.api.recipe.VanillaRecipeCategoryUid.CRAFTING,
|
||||||
|
1, 9, 10, 44
|
||||||
|
);
|
||||||
|
} catch(Throwable e) {
|
||||||
|
ModEngineersDecor.logger.warn("Exception in JEI crafting table handler registration: '" + e.getMessage() + "'.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 516 B After Width: | Height: | Size: 521 B |
Before Width: | Height: | Size: 483 B After Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 601 B After Width: | Height: | Size: 604 B |
Before Width: | Height: | Size: 529 B After Width: | Height: | Size: 532 B |
Before Width: | Height: | Size: 574 B After Width: | Height: | Size: 550 B |
Before Width: | Height: | Size: 504 B After Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 534 B After Width: | Height: | Size: 518 B |
Before Width: | Height: | Size: 537 B After Width: | Height: | Size: 184 B |
Before Width: | Height: | Size: 667 B After Width: | Height: | Size: 693 B |
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 399 B |
Before Width: | Height: | Size: 557 B After Width: | Height: | Size: 533 B |
Before Width: | Height: | Size: 550 B After Width: | Height: | Size: 539 B |
Before Width: | Height: | Size: 515 B After Width: | Height: | Size: 503 B |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 26 KiB |
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
|
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
|
||||||
"1.12.2": {
|
"1.12.2": {
|
||||||
|
"1.0.4-b1": "[A] Crafting table: JEI integration for recipe placement added.\n[A] Crafting table: History re-fab added, allowing to quickly select and re-craft recent recipes. Selection with arrow buttons, ingredient placement by clicking the result slot. Automatic item distribution on shift-click. Quick-move buttons.\n[F] Crafting table textures modified to prevent optifine glitches on the edges of the legs.",
|
||||||
"1.0.3": "[R] Release based on v1.0.3-b5. Release-to-release changes: * Small laboratory furnace added. * Extensive config options for mod packing and tuning added. * Rendering issues fixes (window bleeding, optifine). * Steel framed window added. * Treated wood pole \"end pieces\" added (two support variants). * Sitting on treated wood stool added including mobs (but not villagers, as these are obviously very upright people). * Lang ru_ru added (github contribution from Yaroslavik). * Creative tab logo changed to mod logo. * Table/crafting table bounding boxes refined. * Standalone \"escape\" recipes added if IE is not installed.",
|
"1.0.3": "[R] Release based on v1.0.3-b5. Release-to-release changes: * Small laboratory furnace added. * Extensive config options for mod packing and tuning added. * Rendering issues fixes (window bleeding, optifine). * Steel framed window added. * Treated wood pole \"end pieces\" added (two support variants). * Sitting on treated wood stool added including mobs (but not villagers, as these are obviously very upright people). * Lang ru_ru added (github contribution from Yaroslavik). * Creative tab logo changed to mod logo. * Table/crafting table bounding boxes refined. * Standalone \"escape\" recipes added if IE is not installed.",
|
||||||
"1.0.3-b5": "[F] Fixed typo in en-en lang file.\n[F] Fixed IE concrete texture missing bailout in log if IE is not installed.\n[F] Using forge multi-layer models for windows to circumvent glitches.\n[M] Changed creative tab logo to the mod logo.\n[A] Added alternative recipes for crafting table and furnace if main IE ingredients are missing (for \"stand-alone\" mod usage).",
|
"1.0.3-b5": "[F] Fixed typo in en-en lang file.\n[F] Fixed IE concrete texture missing bailout in log if IE is not installed.\n[F] Using forge multi-layer models for windows to circumvent glitches.\n[M] Changed creative tab logo to the mod logo.\n[A] Added alternative recipes for crafting table and furnace if main IE ingredients are missing (for \"stand-alone\" mod usage).",
|
||||||
"1.0.3-b4": "[A] Lab furnace supports electrical speedup when a IE external is placed in one of the two auxiliary slots.\n[F] Fixed window rendering issue (issue #15, thanks to ILLOMIURGE).\n[M] Updated ru_ru lang file (Yaroslavik).",
|
"1.0.3-b4": "[A] Lab furnace supports electrical speedup when a IE external is placed in one of the two auxiliary slots.\n[F] Fixed window rendering issue (issue #15, thanks to ILLOMIURGE).\n[M] Updated ru_ru lang file (Yaroslavik).",
|
||||||
|
@ -32,7 +33,7 @@
|
||||||
},
|
},
|
||||||
"promos": {
|
"promos": {
|
||||||
"1.12.2-recommended": "1.0.3",
|
"1.12.2-recommended": "1.0.3",
|
||||||
"1.12.2-latest": "1.0.3",
|
"1.12.2-latest": "1.0.4-b1",
|
||||||
"1.13.2-recommended": "",
|
"1.13.2-recommended": "",
|
||||||
"1.13.2-latest": "1.0.2-b3"
|
"1.13.2-latest": "1.0.2-b3"
|
||||||
}
|
}
|
||||||
|
|