1.14: Labeled Crate added. 1.15: labeled crate WIP.
This commit is contained in:
parent
41b48208a0
commit
732442a799
11 changed files with 339 additions and 188 deletions
|
@ -4,4 +4,4 @@ org.gradle.jvmargs=-Xmx8G
|
|||
version_minecraft=1.12.2
|
||||
version_forge=14.23.5.2768
|
||||
version_jei=4.10.0.198
|
||||
version_engineersdecor=1.0.20-b2
|
||||
version_engineersdecor=1.0.20-b3
|
||||
|
|
|
@ -10,6 +10,8 @@ Mod sources for Minecraft version 1.12.2.
|
|||
----
|
||||
## Version history
|
||||
|
||||
~ v1.0.20-b3 [F]
|
||||
|
||||
- v1.0.20-b2 [A] Backported Electrical Furnace GUI speed selection switch.
|
||||
[A] Backported Labeled Crate (storage crate with built-in item frame).
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
|
||||
"1.14.4": {
|
||||
"1.0.20-b2": "[U] Forge version requirement set to >= 28.2.3.\n[A] Added Labeled Crate (storage crate with built-in item frame).",
|
||||
"1.0.20-b1": "[A] Electrical Furnace: Added four-position speed switch (off, 100%, 150%, 200%), power consumption increases at higher rate (off, 100%, 200%, 400%).\n[A] Added Steel Mesh Fence Gate (single or double height gate fitting to the Steel Mesh Fence).\n[M] Waste Incinerator processing speed tweaked.",
|
||||
"1.0.19-b5": "[A] Added right-click display of power and progress information for Block Breaker, Solar Panel, and Tree Cutter.\n[A] Solar Panel power curve tuned.\n[A] Mod manual 1st edition release recipe added.\n[A] Factory Hopper: Resetting NBT when breaking with empty inventory (for stacking), enabled item cap for all sides.\n[M] Electrical Furnace model polished.",
|
||||
"1.0.19-b4": "[A] Ported primary Immersive Engineering dependent recipes (alternative recipes will still work if IE is not installed).\n[M] Furni comparator output overrides reflect input slots and empty fuel state/power-cutoff.\n[M] Solar Panel config: Default value for internal battery capacity increased.\n[F] Block Placer: Shifted GUI player slots 1px to the right.\n[A] Added mod block tags for slabs, stairs, and walls (PR#89, thanks CrudeAustin for the data).\n[A] Added experimental Patchouli manual (creative only).\n[!] Skipped blacklisting Treated Wood Crafting Table slots for the inventorysorter mod due to potential startup crashes for single player games (issue #88 fix deferred).",
|
||||
|
@ -50,6 +51,6 @@
|
|||
},
|
||||
"promos": {
|
||||
"1.14.4-recommended": "",
|
||||
"1.14.4-latest": "1.0.20-b1"
|
||||
"1.14.4-latest": "1.0.20-b2"
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ Mod sources for Minecraft version 1.14.4.
|
|||
|
||||
## Version history
|
||||
|
||||
~ v1.0.20-b2 [U] Forge version requirement set to >= 28.2.3.
|
||||
- v1.0.20-b2 [U] Forge version requirement set to >= 28.2.3.
|
||||
[A] Added Labeled Crate (storage crate with built-in item frame).
|
||||
|
||||
- v1.0.20-b1 [A] Electrical Furnace: Added four-position speed switch (off, 100%, 150%, 200%), power consumption
|
||||
|
|
|
@ -885,7 +885,7 @@ public class ModContent
|
|||
public static final ContainerType<BlockDecorFurnace.BContainer> CT_SMALL_LAB_FURNACE;
|
||||
public static final ContainerType<BlockDecorFurnaceElectrical.BContainer> CT_SMALL_ELECTRICAL_FURNACE;
|
||||
public static final ContainerType<BlockDecorWasteIncinerator.BContainer> CT_WASTE_INCINERATOR;
|
||||
public static final ContainerType<BlockDecorLabeledCrate.BContainer> CT_LABELED_CRATE;
|
||||
public static final ContainerType<BlockDecorLabeledCrate.LabeledCrateContainer> CT_LABELED_CRATE;
|
||||
|
||||
static {
|
||||
CT_TREATED_WOOD_CRAFTING_TABLE = (new ContainerType<BlockDecorCraftingTable.CraftingTableContainer>(BlockDecorCraftingTable.CraftingTableContainer::new));
|
||||
|
@ -902,7 +902,7 @@ public class ModContent
|
|||
CT_SMALL_ELECTRICAL_FURNACE.setRegistryName(ModEngineersDecor.MODID,"ct_small_electrical_furnace");
|
||||
CT_WASTE_INCINERATOR = (new ContainerType<BlockDecorWasteIncinerator.BContainer>(BlockDecorWasteIncinerator.BContainer::new));
|
||||
CT_WASTE_INCINERATOR.setRegistryName(ModEngineersDecor.MODID,"ct_small_waste_incinerator");
|
||||
CT_LABELED_CRATE = (new ContainerType<BlockDecorLabeledCrate.BContainer>(BlockDecorLabeledCrate.BContainer::new));
|
||||
CT_LABELED_CRATE = (new ContainerType<BlockDecorLabeledCrate.LabeledCrateContainer>(BlockDecorLabeledCrate.LabeledCrateContainer::new));
|
||||
CT_LABELED_CRATE.setRegistryName(ModEngineersDecor.MODID,"ct_labeled_crate");
|
||||
}
|
||||
|
||||
|
@ -993,7 +993,7 @@ public class ModContent
|
|||
public static final void registerContainerGuis(final FMLClientSetupEvent event)
|
||||
{
|
||||
ScreenManager.registerFactory(CT_TREATED_WOOD_CRAFTING_TABLE, BlockDecorCraftingTable.CraftingTableGui::new);
|
||||
ScreenManager.registerFactory(CT_LABELED_CRATE, BlockDecorLabeledCrate.BGui::new);
|
||||
ScreenManager.registerFactory(CT_LABELED_CRATE, BlockDecorLabeledCrate.LabeledCrateGui::new);
|
||||
ScreenManager.registerFactory(CT_FACTORY_DROPPER, BlockDecorDropper.BGui::new);
|
||||
ScreenManager.registerFactory(CT_FACTORY_PLACER, BlockDecorPlacer.BGui::new);
|
||||
ScreenManager.registerFactory(CT_FACTORY_HOPPER, BlockDecorHopper.BGui::new);
|
||||
|
|
|
@ -20,6 +20,7 @@ import wile.engineersdecor.ModEngineersDecor;
|
|||
import wile.engineersdecor.libmc.blocks.StandardBlocks;
|
||||
import wile.engineersdecor.libmc.detail.Auxiliaries;
|
||||
import wile.engineersdecor.libmc.detail.Inventories;
|
||||
import wile.engineersdecor.libmc.detail.Inventories.SlotRange;
|
||||
import wile.engineersdecor.libmc.detail.Networking;
|
||||
import net.minecraft.inventory.container.*;
|
||||
import net.minecraft.network.play.server.SSetSlotPacket;
|
||||
|
@ -478,7 +479,7 @@ public class BlockDecorCraftingTable
|
|||
final ItemStack stack = super.slotClick(slotId, button, clickType, player);
|
||||
if((with_outslot_defined_refab) && (slotId == 0) && (clickType == ClickType.PICKUP)) {
|
||||
if((!crafting_matrix_changed_now_) && (!player.world.isRemote()) && (crafting_grid_empty())) {
|
||||
final ItemStack dragged = player.inventory.getItemStack(); // @todo: check, as far as seen this is actually `stack`.
|
||||
final ItemStack dragged = player.inventory.getItemStack();
|
||||
if((dragged != null) && (!dragged.isEmpty())) {
|
||||
try_result_stack_refab(dragged, player.world);
|
||||
} else if(!history().current().isEmpty()) {
|
||||
|
@ -498,12 +499,14 @@ public class BlockDecorCraftingTable
|
|||
Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerPacketReceived(int windowId, CompoundNBT nbt)
|
||||
{
|
||||
if(nbt.contains("history")) history_.read(nbt.getCompound("history"));
|
||||
if(nbt.contains("hascollision")) has_recipe_collision_ = nbt.getBoolean("hascollision");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt)
|
||||
{
|
||||
boolean changed = false;
|
||||
|
@ -619,7 +622,7 @@ public class BlockDecorCraftingTable
|
|||
if(Inventories.areItemStacksDifferent(reference_stack, stack)) continue;
|
||||
ItemStack remaining = from_inventory.getStackInSlot(i);
|
||||
for(SlotRange range:to_ranges) {
|
||||
remaining = move_stack_to_inventory(remaining, range, false, 0);
|
||||
remaining = range.insert(remaining, false, 0);
|
||||
if(!remaining.isEmpty()) {
|
||||
abort = true; // no space left
|
||||
break;
|
||||
|
@ -909,112 +912,6 @@ public class BlockDecorCraftingTable
|
|||
return stacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, SlotRange range, boolean only_fillup, int limit)
|
||||
{
|
||||
final IInventory inventory = range.inventory;
|
||||
final int slot_begin = range.start_slot;
|
||||
final int slot_end = range.end_slot;
|
||||
final ItemStack mvstack = stack_to_move.copy();
|
||||
if((mvstack.isEmpty()) || (slot_begin < 0) || (slot_end > inventory.getSizeInventory())) return mvstack;
|
||||
int limit_left = (limit>0) ? (Math.min(limit, mvstack.getMaxStackSize())) : (mvstack.getMaxStackSize());
|
||||
// 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 = Math.min(limit_left, 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.grow(nmax);
|
||||
mvstack.shrink(nmax);
|
||||
inventory.setInventorySlotContents(i, stack);
|
||||
limit_left -= nmax;
|
||||
}
|
||||
}
|
||||
if(only_fillup) return mvstack;
|
||||
if(inventory instanceof PlayerInventory) {
|
||||
// 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((Inventories.areItemStacksDifferent(inventory.getStackInSlot(i+1), mvstack)) && (Inventories.areItemStacksDifferent(inventory.getStackInSlot(i-1), mvstack))) continue;
|
||||
int nmax = Math.min(limit_left, mvstack.getCount());
|
||||
ItemStack placed = mvstack.copy();
|
||||
placed.setCount(nmax);
|
||||
mvstack.shrink(nmax);
|
||||
inventory.setInventorySlotContents(i, placed);
|
||||
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;
|
||||
int nmax = Math.min(limit_left, mvstack.getCount());
|
||||
ItemStack placed = mvstack.copy();
|
||||
placed.setCount(nmax);
|
||||
mvstack.shrink(nmax);
|
||||
inventory.setInventorySlotContents(i, placed);
|
||||
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(SlotRange range, final ItemStack request_stack)
|
||||
{
|
||||
final IInventory inventory = range.inventory;
|
||||
final int slot_begin = range.start_slot;
|
||||
final int slot_end = range.end_slot;
|
||||
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()) && (Inventories.areItemStacksIdentical(stack, request_stack))) {
|
||||
if(stack.hasTag()) {
|
||||
final CompoundNBT nbt = stack.getTag();
|
||||
int n = nbt.size();
|
||||
if((n > 0) && (nbt.contains("Damage"))) --n;
|
||||
if(n > 0) continue;
|
||||
}
|
||||
fetched_stack = stack.copy();
|
||||
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(PlayerEntity player)
|
||||
{
|
||||
|
@ -1022,7 +919,8 @@ public class BlockDecorCraftingTable
|
|||
for(int grid_i = CRAFTING_SLOTS_BEGIN; grid_i < (CRAFTING_SLOTS_BEGIN+NUM_OF_CRAFTING_SLOTS); ++grid_i) {
|
||||
ItemStack stack = inventory_.getStackInSlot(grid_i);
|
||||
if(stack.isEmpty()) continue;
|
||||
ItemStack remaining = move_stack_to_inventory(stack, new SlotRange(inventory_, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS), false, 0);
|
||||
//ItemStack remaining = move_stack_to_inventory(stack, new SlotRange(inventory_, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS), false, 0);
|
||||
ItemStack remaining = (new SlotRange(inventory_, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS)).insert(stack, false, 0);
|
||||
inventory_.setInventorySlotContents(grid_i, remaining);
|
||||
changed = true;
|
||||
}
|
||||
|
@ -1035,10 +933,14 @@ public class BlockDecorCraftingTable
|
|||
for(int grid_i = CRAFTING_SLOTS_BEGIN; grid_i < (CRAFTING_SLOTS_BEGIN+NUM_OF_CRAFTING_SLOTS); ++grid_i) {
|
||||
ItemStack remaining = inventory_.getStackInSlot(grid_i);
|
||||
if(remaining.isEmpty()) continue;
|
||||
remaining = move_stack_to_inventory(remaining, new SlotRange(player.inventory,9, 36), true, 0); // prefer filling up inventory stacks
|
||||
remaining = move_stack_to_inventory(remaining, new SlotRange(player.inventory,0, 9), true, 0); // then fill up the hotbar stacks
|
||||
remaining = move_stack_to_inventory(remaining, new SlotRange(player.inventory,9, 36), false, 0); // then allow empty stacks in inventory
|
||||
remaining = move_stack_to_inventory(remaining, new SlotRange(player.inventory,0, 9), false, 0); // then new stacks in the hotbar
|
||||
//remaining = move_stack_to_inventory(remaining, new SlotRange(player.inventory,9, 36), true, 0); // prefer filling up inventory stacks
|
||||
//remaining = move_stack_to_inventory(remaining, new SlotRange(player.inventory,0, 9), true, 0); // then fill up the hotbar stacks
|
||||
//remaining = move_stack_to_inventory(remaining, new SlotRange(player.inventory,9, 36), false, 0); // then allow empty stacks in inventory
|
||||
//remaining = move_stack_to_inventory(remaining, new SlotRange(player.inventory,0, 9), false, 0); // then new stacks in the hotbar
|
||||
remaining = (new SlotRange(player.inventory,9, 36)).insert(remaining,true, 0); // prefer filling up inventory stacks
|
||||
remaining = (new SlotRange(player.inventory,0, 9)).insert(remaining, true, 0); // then fill up the hotbar stacks
|
||||
remaining = (new SlotRange(player.inventory,9, 36)).insert(remaining, false, 0); // then allow empty stacks in inventory
|
||||
remaining = (new SlotRange(player.inventory,0, 9)).insert(remaining, false, 0); // then new stacks in the hotbar
|
||||
inventory_.setInventorySlotContents(grid_i, remaining);
|
||||
changed = true;
|
||||
}
|
||||
|
@ -1059,7 +961,7 @@ public class BlockDecorCraftingTable
|
|||
if(grid_stack.getCount() >= grid_stack.getMaxStackSize()) continue;
|
||||
final ItemStack req_stack = to_fill.get(i).copy();
|
||||
req_stack.setCount(1);
|
||||
final ItemStack mv_stack = move_stack_from_inventory(slot_range, req_stack);
|
||||
final ItemStack mv_stack = slot_range.extract(req_stack);
|
||||
if(mv_stack.isEmpty()) continue;
|
||||
to_fill.get(i).shrink(1);
|
||||
if(grid_stack.isEmpty()) {
|
||||
|
@ -1164,7 +1066,7 @@ public class BlockDecorCraftingTable
|
|||
ItemStack stack = inventory_.getStackInSlot(i+CRAFTING_SLOTS_BEGIN).copy();
|
||||
if(stack.isEmpty()) continue;
|
||||
for(SlotRange range:ranges) {
|
||||
ItemStack remaining = move_stack_to_inventory(stack, range, false, limit);
|
||||
ItemStack remaining = range.insert(stack, false, limit);
|
||||
if(remaining.getCount() < stack.getCount()) changed = true;
|
||||
boolean stop = (remaining.getCount() <= Math.max(0, (stack.getCount()-limit)));
|
||||
stack = remaining;
|
||||
|
@ -1714,11 +1616,4 @@ public class BlockDecorCraftingTable
|
|||
}
|
||||
}
|
||||
|
||||
private static class SlotRange
|
||||
{
|
||||
public final IInventory inventory;
|
||||
public int start_slot, end_slot;
|
||||
public SlotRange(IInventory inv, int start, int end) { inventory=inv; start_slot=start; end_slot=end; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,9 +8,13 @@
|
|||
*/
|
||||
package wile.engineersdecor.blocks;
|
||||
|
||||
import wile.engineersdecor.libmc.detail.Auxiliaries;
|
||||
import wile.engineersdecor.libmc.detail.Inventories.SlotRange;
|
||||
import wile.engineersdecor.libmc.detail.Networking;
|
||||
import wile.engineersdecor.ModContent;
|
||||
import wile.engineersdecor.ModEngineersDecor;
|
||||
import wile.engineersdecor.libmc.blocks.StandardBlocks;
|
||||
import net.minecraft.inventory.container.ClickType;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -47,6 +51,7 @@ import net.minecraftforge.items.CapabilityItemHandler;
|
|||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
|
@ -55,8 +60,11 @@ import java.util.List;
|
|||
|
||||
public class BlockDecorLabeledCrate
|
||||
{
|
||||
public static void on_config(int stack_limit)
|
||||
private static boolean with_gui_mouse_handling = true;
|
||||
|
||||
public static void on_config(boolean without_gui_mouse_handling)
|
||||
{
|
||||
with_gui_mouse_handling = !without_gui_mouse_handling;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -220,11 +228,15 @@ public class BlockDecorLabeledCrate
|
|||
public void handleUpdateTag(CompoundNBT tag) // on client
|
||||
{ read(tag); }
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public double getMaxRenderDistanceSquared()
|
||||
{ return 400; }
|
||||
|
||||
// INameable ---------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public ITextComponent getName()
|
||||
{ final Block block=getBlockState().getBlock(); return new StringTextComponent((block!=null) ? block.getTranslationKey() : "Small Waste Incinerator"); }
|
||||
{ final Block block=getBlockState().getBlock(); return new StringTextComponent((block!=null) ? block.getTranslationKey() : "Labeled Crate"); }
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName()
|
||||
|
@ -242,7 +254,7 @@ public class BlockDecorLabeledCrate
|
|||
|
||||
@Override
|
||||
public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player )
|
||||
{ return new BContainer(id, inventory, this, IWorldPosCallable.of(world, pos), fields); }
|
||||
{ return new LabeledCrateContainer(id, inventory, this, IWorldPosCallable.of(world, pos), fields); }
|
||||
|
||||
// IInventory ------------------------------------------------------------------------------
|
||||
|
||||
|
@ -451,50 +463,11 @@ public class BlockDecorLabeledCrate
|
|||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
// GUI
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class BGui extends ContainerScreen<BContainer>
|
||||
{
|
||||
protected final PlayerEntity player_;
|
||||
|
||||
public BGui(BContainer container, PlayerInventory player_inventory, ITextComponent title)
|
||||
{
|
||||
super(container, player_inventory, title);
|
||||
player_ = player_inventory.player;
|
||||
xSize = 213;
|
||||
ySize = 206;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{ super.init(); }
|
||||
|
||||
@Override
|
||||
public void render(int mouseX, int mouseY, float partialTicks)
|
||||
{
|
||||
renderBackground();
|
||||
super.render(mouseX, mouseY, partialTicks);
|
||||
renderHoveredToolTip(mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
|
||||
{
|
||||
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
this.minecraft.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/labeled_crate_gui.png"));
|
||||
final int x0=guiLeft, y0=this.guiTop, w=xSize, h=ySize;
|
||||
blit(x0, y0, 0, 0, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
// Container
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
public static class BContainer extends Container
|
||||
public static class LabeledCrateContainer extends Container implements Networking.INetworkSynchronisableContainer
|
||||
{
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
protected static class StorageSlot extends Slot
|
||||
|
@ -509,11 +482,13 @@ public class BlockDecorLabeledCrate
|
|||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
private static final int PLAYER_INV_START_SLOTNO = LabeledCrateTileEntity.NUM_OF_SLOTS;
|
||||
private static final int NUM_OF_CONTAINER_SLOTS = LabeledCrateTileEntity.NUM_OF_SLOTS + 36;
|
||||
protected final PlayerEntity player_;
|
||||
protected final IInventory inventory_;
|
||||
protected final IWorldPosCallable wpc_;
|
||||
private final IIntArray fields_;
|
||||
private int proc_time_needed_;
|
||||
private final SlotRange player_inventory_slot_range;
|
||||
private final SlotRange crate_slot_range;
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
public int field(int index) { return fields_.get(index); }
|
||||
public PlayerEntity player() { return player_ ; }
|
||||
|
@ -521,16 +496,18 @@ public class BlockDecorLabeledCrate
|
|||
public World world() { return player_.world; }
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
public BContainer(int cid, PlayerInventory player_inventory)
|
||||
public LabeledCrateContainer(int cid, PlayerInventory player_inventory)
|
||||
{ this(cid, player_inventory, new Inventory(LabeledCrateTileEntity.NUM_OF_SLOTS), IWorldPosCallable.DUMMY, new IntArray(LabeledCrateTileEntity.NUM_OF_FIELDS)); }
|
||||
|
||||
private BContainer(int cid, PlayerInventory player_inventory, IInventory block_inventory, IWorldPosCallable wpc, IIntArray fields)
|
||||
private LabeledCrateContainer(int cid, PlayerInventory player_inventory, IInventory block_inventory, IWorldPosCallable wpc, IIntArray fields)
|
||||
{
|
||||
super(ModContent.CT_LABELED_CRATE, cid);
|
||||
player_ = player_inventory.player;
|
||||
inventory_ = block_inventory;
|
||||
wpc_ = wpc;
|
||||
fields_ = fields;
|
||||
crate_slot_range = new SlotRange(inventory_, 0, LabeledCrateTileEntity.ITEMFRAME_SLOTNO);
|
||||
player_inventory_slot_range = new SlotRange(player_inventory, 0, 36);
|
||||
int i=-1;
|
||||
// storage slots (stacks 0 to 53)
|
||||
for(int y=0; y<6; ++y) {
|
||||
|
@ -580,7 +557,7 @@ public class BlockDecorLabeledCrate
|
|||
// Player slot
|
||||
if(!mergeItemStack(slot_stack, 0, PLAYER_INV_START_SLOTNO-1, false)) return ItemStack.EMPTY;
|
||||
} else {
|
||||
// invalid slot
|
||||
// Invalid slot
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
if(slot_stack.isEmpty()) {
|
||||
|
@ -592,5 +569,168 @@ public class BlockDecorLabeledCrate
|
|||
slot.onTake(player, slot_stack);
|
||||
return transferred;
|
||||
}
|
||||
|
||||
// Container client/server synchronisation --------------------------------------------------
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void onGuiAction(String message, CompoundNBT nbt)
|
||||
{
|
||||
nbt.putString("action", message);
|
||||
Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerPacketReceived(int windowId, CompoundNBT nbt)
|
||||
{}
|
||||
|
||||
protected static final int STORAGE_SLOT_BEGIN = 0;
|
||||
protected static final int STORAGE_SLOT_END = LabeledCrateTileEntity.ITEMFRAME_SLOTNO;
|
||||
protected static final int PLAYER_SLOT_BEGIN = LabeledCrateTileEntity.NUM_OF_SLOTS;
|
||||
protected static final int PLAYER_SLOT_END = LabeledCrateTileEntity.NUM_OF_SLOTS+36;
|
||||
|
||||
@Override
|
||||
public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt)
|
||||
{
|
||||
boolean changed = false;
|
||||
if(!nbt.contains("action")) return;
|
||||
final int slotId = nbt.contains("slot") ? nbt.getInt("slot") : -1;
|
||||
switch(nbt.getString("action")) {
|
||||
case LabeledCrateGui.QUICK_MOVE_ALL: {
|
||||
if((slotId >= STORAGE_SLOT_BEGIN) && (slotId < STORAGE_SLOT_END) && (getSlot(slotId).getHasStack())) {
|
||||
final Slot slot = getSlot(slotId);
|
||||
ItemStack remaining = slot.getStack();
|
||||
slot.putStack(ItemStack.EMPTY);
|
||||
final ItemStack ref_stack = remaining.copy();
|
||||
ref_stack.setCount(ref_stack.getMaxStackSize());
|
||||
for(int i=crate_slot_range.end_slot-crate_slot_range.start_slot; (i>0) && (!remaining.isEmpty()); --i) {
|
||||
remaining = player_inventory_slot_range.insert(remaining, false, 0, true, true);
|
||||
if(!remaining.isEmpty()) break;
|
||||
remaining = crate_slot_range.extract(ref_stack);
|
||||
}
|
||||
if(!remaining.isEmpty()) {
|
||||
slot.putStack(remaining); // put back
|
||||
}
|
||||
} else if((slotId >= PLAYER_SLOT_BEGIN) && (slotId < PLAYER_SLOT_END) && (getSlot(slotId).getHasStack())) {
|
||||
final Slot slot = getSlot(slotId);
|
||||
ItemStack remaining = slot.getStack();
|
||||
slot.putStack(ItemStack.EMPTY);
|
||||
final ItemStack ref_stack = remaining.copy();
|
||||
ref_stack.setCount(ref_stack.getMaxStackSize());
|
||||
for(int i=player_inventory_slot_range.end_slot-player_inventory_slot_range.start_slot; (i>0) && (!remaining.isEmpty()); --i) {
|
||||
remaining = crate_slot_range.insert(remaining, false, 0, false, true);
|
||||
if(!remaining.isEmpty()) break;
|
||||
remaining = player_inventory_slot_range.extract(ref_stack);
|
||||
}
|
||||
if(!remaining.isEmpty()) {
|
||||
slot.putStack(remaining); // put back
|
||||
}
|
||||
}
|
||||
changed = true;
|
||||
} break;
|
||||
case LabeledCrateGui.INCREASE_STACK: {
|
||||
} break;
|
||||
case LabeledCrateGui.DECREASE_STACK: {
|
||||
} break;
|
||||
}
|
||||
if(changed) {
|
||||
inventory_.markDirty();
|
||||
player.inventory.markDirty();
|
||||
detectAndSendChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
// GUI
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static class LabeledCrateGui extends ContainerScreen<LabeledCrateContainer>
|
||||
{
|
||||
protected static final String QUICK_MOVE_ALL = "quick-move-all";
|
||||
protected static final String INCREASE_STACK = "increase-stack";
|
||||
protected static final String DECREASE_STACK = "decrease-stack";
|
||||
|
||||
protected final PlayerEntity player_;
|
||||
|
||||
public LabeledCrateGui(LabeledCrateContainer container, PlayerInventory player_inventory, ITextComponent title)
|
||||
{
|
||||
super(container, player_inventory, title);
|
||||
player_ = player_inventory.player;
|
||||
xSize = 213;
|
||||
ySize = 206;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{ super.init(); }
|
||||
|
||||
@Override
|
||||
public void render(int mouseX, int mouseY, float partialTicks)
|
||||
{
|
||||
renderBackground();
|
||||
super.render(mouseX, mouseY, partialTicks);
|
||||
renderHoveredToolTip(mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
|
||||
{
|
||||
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
this.minecraft.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/labeled_crate_gui.png"));
|
||||
final int x0=guiLeft, y0=this.guiTop, w=xSize, h=ySize;
|
||||
blit(x0, y0, 0, 0, w, h);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
protected void action(String message)
|
||||
{ action(message, new CompoundNBT()); }
|
||||
|
||||
protected void action(String message, CompoundNBT nbt)
|
||||
{ getContainer().onGuiAction(message, nbt); }
|
||||
|
||||
@Override
|
||||
protected void handleMouseClick(Slot slot, int slotId, int button, ClickType type)
|
||||
{
|
||||
if(!with_gui_mouse_handling) {
|
||||
super.handleMouseClick(slot, slotId, button, type);
|
||||
} else if((type == ClickType.QUICK_MOVE) && slot.getHasStack() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
|
||||
CompoundNBT nbt = new CompoundNBT();
|
||||
nbt.putInt("slot", slotId);
|
||||
action(QUICK_MOVE_ALL, nbt);
|
||||
} else {
|
||||
super.handleMouseClick(slot, slotId, button, type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouseX, double mouseY, double wheel_inc)
|
||||
{
|
||||
if(!with_gui_mouse_handling) return super.mouseScrolled(mouseX, mouseY, wheel_inc);
|
||||
final Slot slot = getSlotUnderMouse();
|
||||
if(!slot.getHasStack()) return true;
|
||||
final int count = slot.getStack().getCount();
|
||||
int limit = (Auxiliaries.isShiftDown() ? 2 : 1) * (Auxiliaries.isCtrlDown() ? 4 : 1);
|
||||
if(wheel_inc > 0.1) {
|
||||
if(count > 0) {
|
||||
if((count < slot.getStack().getMaxStackSize()) && (count < slot.getSlotStackLimit())) {
|
||||
CompoundNBT nbt = new CompoundNBT();
|
||||
nbt.putInt("slot", slot.slotNumber);
|
||||
if(limit > 1) nbt.putInt("limit", limit);
|
||||
action(INCREASE_STACK, nbt);
|
||||
}
|
||||
}
|
||||
} else if(wheel_inc < -0.1) {
|
||||
if(count > 0) {
|
||||
CompoundNBT nbt = new CompoundNBT();
|
||||
nbt.putInt("slot", slot.slotNumber);
|
||||
if(limit > 1) nbt.putInt("limit", limit);
|
||||
action(DECREASE_STACK, nbt);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -608,7 +608,12 @@ public class ModConfig
|
|||
|
||||
public static final void apply()
|
||||
{
|
||||
OptionalRecipeCondition.on_config(with_experimental_features_, without_recipes_, (block)->isOptedOut(block), (item)->isOptedOut(item));
|
||||
without_crafting_table = isOptedOut(ModContent.TREATED_WOOD_CRAFTING_TABLE);
|
||||
immersiveengineering_installed = Auxiliaries.isModLoaded("immersiveengineering");
|
||||
with_experimental_features_ = COMMON.with_experimental.get();
|
||||
without_recipes_ = COMMON.without_recipes.get();
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
OptionalRecipeCondition.on_config(with_experimental_features_, without_recipes_, ModConfig::isOptedOut, ModConfig::isOptedOut);
|
||||
BlockDecorFurnace.BTileEntity.on_config(COMMON.furnace_smelting_speed_percent.get(), COMMON.furnace_fuel_efficiency_percent.get(), COMMON.furnace_boost_energy_consumption.get());
|
||||
BlockDecorChair.on_config(COMMON.without_chair_sitting.get(), COMMON.without_mob_chair_sitting.get(), COMMON.chair_mob_sitting_probability_percent.get(), COMMON.chair_mob_standup_probability_percent.get());
|
||||
BlockDecorLadder.on_config(COMMON.without_ladder_speed_boost.get());
|
||||
|
@ -621,10 +626,8 @@ public class ModConfig
|
|||
BlockDecorMilker.BTileEntity.on_config(COMMON.milking_machine_energy_consumption.get(), COMMON.milking_machine_milking_delay.get());
|
||||
BlockDecorSlab.on_config(!COMMON.without_direct_slab_pickup.get());
|
||||
BlockDecorHalfSlab.on_config(!COMMON.without_direct_slab_pickup.get());
|
||||
without_crafting_table = isOptedOut(ModContent.TREATED_WOOD_CRAFTING_TABLE);
|
||||
immersiveengineering_installed = Auxiliaries.isModLoaded("immersiveengineering");
|
||||
with_experimental_features_ = COMMON.with_experimental.get();
|
||||
without_recipes_ = COMMON.without_recipes.get();
|
||||
BlockDecorLabeledCrate.on_config(false);
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
if(with_experimental_features_) {
|
||||
ModEngineersDecor.logger().info("Config: EXPERIMENTAL FEATURES ENABLED.");
|
||||
}
|
||||
|
|
|
@ -58,13 +58,13 @@ public class LootTableGen extends LootTableProvider
|
|||
final List<Block> blocks = block_listing.get();
|
||||
blocks.forEach((block)->{
|
||||
if((!(block instanceof StandardBlocks.IStandardBlock)) || (!(((StandardBlocks.IStandardBlock)block).hasDynamicDropList()))) {
|
||||
System.out.println("Generating loot table for " + block.getRegistryName());
|
||||
LOGGER.info("Generating loot table for " + block.getRegistryName());
|
||||
tables.put(
|
||||
block.getLootTable(),
|
||||
defaultBlockDrops(block.getRegistryName().getPath() + "_dlt", block)
|
||||
.setParameterSet(LootParameterSets.BLOCK).build());
|
||||
} else {
|
||||
System.out.println("Dynamic drop list, skipping loot table for " + block.getRegistryName());
|
||||
LOGGER.info("Dynamic drop list, skipping loot table for " + block.getRegistryName());
|
||||
}
|
||||
});
|
||||
return tables;
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
*/
|
||||
package wile.engineersdecor.libmc.detail;
|
||||
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -21,6 +23,8 @@ import net.minecraftforge.items.ItemHandlerHelper;
|
|||
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||
import net.minecraftforge.items.wrapper.SidedInvWrapper;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class Inventories
|
||||
|
@ -32,8 +36,6 @@ public class Inventories
|
|||
public static boolean areItemStacksDifferent(ItemStack a, ItemStack b)
|
||||
{ return (a.getItem()!=b.getItem()) || (!ItemStack.areItemStackTagsEqual(a, b)); }
|
||||
|
||||
|
||||
|
||||
public static IItemHandler itemhandler(World world, BlockPos pos, @Nullable Direction side)
|
||||
{
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
|
@ -71,9 +73,9 @@ public class Inventories
|
|||
final ItemStack stack = inventory.getStackInSlot(i);
|
||||
if(stack.isEmpty()) continue;
|
||||
if(out_stack.isEmpty()) {
|
||||
if((match!=null) && Inventories.areItemStacksDifferent(stack, match)) continue;
|
||||
if((match!=null) && areItemStacksDifferent(stack, match)) continue;
|
||||
out_stack = inventory.extractItem(i, amount, simulate);
|
||||
} else if(Inventories.areItemStacksIdentical(stack, out_stack)) {
|
||||
} else if(areItemStacksIdentical(stack, out_stack)) {
|
||||
ItemStack es = inventory.extractItem(i, (amount-out_stack.getCount()), simulate);
|
||||
out_stack.grow(es.getCount());
|
||||
}
|
||||
|
@ -82,4 +84,111 @@ public class Inventories
|
|||
return out_stack;
|
||||
}
|
||||
|
||||
}
|
||||
private static ItemStack checked(ItemStack stack)
|
||||
{ return stack.isEmpty() ? ItemStack.EMPTY : stack; } // explicit EMPTY return
|
||||
|
||||
public static class SlotRange
|
||||
{
|
||||
public final IInventory inventory;
|
||||
public final int start_slot, end_slot;
|
||||
|
||||
public SlotRange(IInventory inv, int start, int end)
|
||||
{ inventory=inv; start_slot=start; end_slot=end; }
|
||||
|
||||
/**
|
||||
* Moves as much items from the stack to the slots in range [start_slot, end_slot] of the inventory,
|
||||
* filling up existing stacks first, then (player inventory only) checks appropriate empty slots next
|
||||
* to stacks that have that item already, and last uses any empty slot that can be found.
|
||||
* Returns the stack that is still remaining in the referenced `stack`.
|
||||
*/
|
||||
public ItemStack insert(final ItemStack stack_to_move, boolean only_fillup, int limit)
|
||||
{ return insert(stack_to_move, only_fillup, limit, false, false); }
|
||||
|
||||
public ItemStack insert(final ItemStack stack_to_move, boolean only_fillup, int limit, boolean reverse, boolean force_group_stacks)
|
||||
{
|
||||
final ItemStack mvstack = stack_to_move.copy();
|
||||
if((mvstack.isEmpty()) || (start_slot < 0) || (end_slot > inventory.getSizeInventory())) return checked(mvstack);
|
||||
int limit_left = (limit>0) ? (Math.min(limit, mvstack.getMaxStackSize())) : (mvstack.getMaxStackSize());
|
||||
// first iteration: fillup existing stacks
|
||||
for(int i = start_slot; i < end_slot; ++i) {
|
||||
final int sno = reverse ? (end_slot-1-i) : (i);
|
||||
final ItemStack stack = inventory.getStackInSlot(sno);
|
||||
if((stack.isEmpty()) || (areItemStacksDifferent(stack, mvstack))) continue;
|
||||
int nmax = Math.min(limit_left, stack.getMaxStackSize() - stack.getCount());
|
||||
if(mvstack.getCount() <= nmax) {
|
||||
stack.setCount(stack.getCount()+mvstack.getCount());
|
||||
inventory.setInventorySlotContents(sno, stack);
|
||||
return ItemStack.EMPTY;
|
||||
} else {
|
||||
stack.grow(nmax);
|
||||
mvstack.shrink(nmax);
|
||||
inventory.setInventorySlotContents(sno, stack);
|
||||
limit_left -= nmax;
|
||||
}
|
||||
}
|
||||
if(only_fillup) return checked(mvstack);
|
||||
if((force_group_stacks) || (inventory instanceof PlayerInventory)) {
|
||||
// second iteration: use appropriate empty slots
|
||||
for(int i = start_slot+1; i < end_slot-1; ++i) {
|
||||
final int sno = reverse ? (end_slot-1-i) : (i);
|
||||
final ItemStack stack = inventory.getStackInSlot(sno);
|
||||
if(!stack.isEmpty()) continue;
|
||||
if((areItemStacksDifferent(inventory.getStackInSlot(sno+1), mvstack)) && (areItemStacksDifferent(inventory.getStackInSlot(sno-1), mvstack))) continue;
|
||||
int nmax = Math.min(limit_left, mvstack.getCount());
|
||||
ItemStack moved = mvstack.copy();
|
||||
moved.setCount(nmax);
|
||||
mvstack.shrink(nmax);
|
||||
inventory.setInventorySlotContents(sno, moved);
|
||||
return checked(mvstack);
|
||||
}
|
||||
}
|
||||
// third iteration: use any empty slots
|
||||
for(int i = start_slot; i < end_slot; ++i) {
|
||||
final int sno = reverse ? (end_slot-1-i) : (i);
|
||||
final ItemStack stack = inventory.getStackInSlot(sno);
|
||||
if(!stack.isEmpty()) continue;
|
||||
int nmax = Math.min(limit_left, mvstack.getCount());
|
||||
ItemStack placed = mvstack.copy();
|
||||
placed.setCount(nmax);
|
||||
mvstack.shrink(nmax);
|
||||
inventory.setInventorySlotContents(sno, placed);
|
||||
return checked(mvstack);
|
||||
}
|
||||
return checked(mvstack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves as much items from the slots in range [start_slot, end_slot] of the inventory into a new stack.
|
||||
* Implicitly shrinks the inventory stacks and the `request_stack`.
|
||||
*/
|
||||
public ItemStack extract(final ItemStack request_stack)
|
||||
{
|
||||
if(request_stack.isEmpty()) return ItemStack.EMPTY;
|
||||
final IInventory inventory = this.inventory;
|
||||
List<ItemStack> matches = new ArrayList<>();
|
||||
for(int i = start_slot; i < end_slot; ++i) {
|
||||
final ItemStack stack = inventory.getStackInSlot(i);
|
||||
if((!stack.isEmpty()) && (areItemStacksIdentical(stack, request_stack))) {
|
||||
if(stack.hasTag()) {
|
||||
final CompoundNBT nbt = stack.getTag();
|
||||
int n = nbt.size();
|
||||
if((n > 0) && (nbt.contains("Damage"))) --n;
|
||||
if(n > 0) continue;
|
||||
}
|
||||
matches.add(stack);
|
||||
}
|
||||
}
|
||||
matches.sort((a,b) -> Integer.compare(a.getCount(), b.getCount()));
|
||||
if(matches.isEmpty()) return ItemStack.EMPTY;
|
||||
int n_left = request_stack.getCount();
|
||||
ItemStack fetched_stack = matches.get(0).split(n_left);
|
||||
n_left -= fetched_stack.getCount();
|
||||
for(int i=1; (i<matches.size()) && (n_left>0); ++i) {
|
||||
ItemStack stack = matches.get(i).split(n_left);
|
||||
n_left -= stack.getCount();
|
||||
fetched_stack.grow(stack.getCount());
|
||||
}
|
||||
return checked(fetched_stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"1.12.2-recommended": "1.0.19",
|
||||
"1.12.2-latest": "1.0.20-b2",
|
||||
"1.14.4-recommended": "",
|
||||
"1.14.4-latest": "1.0.20-b1",
|
||||
"1.14.4-latest": "1.0.20-b2",
|
||||
"1.15.2-recommended": "",
|
||||
"1.15.2-latest": "1.0.20-b1"
|
||||
},
|
||||
|
@ -91,6 +91,7 @@
|
|||
"1.0.0-b1": "[A] Initial structure.\n[A] Added clinker bricks and clinker brick stairs.\n[A] Added slag bricks and slag brick stairs.\n[A] Added metal rung ladder.\n[A] Added staggered metal steps ladder.\n[A] Added treated wood ladder.\n[A] Added treated wood pole.\n[A] Added treated wood table."
|
||||
},
|
||||
"1.14.4": {
|
||||
"1.0.20-b2": "[U] Forge version requirement set to >= 28.2.3.\n[A] Added Labeled Crate (storage crate with built-in item frame).",
|
||||
"1.0.20-b1": "[A] Electrical Furnace: Added four-position speed switch (off, 100%, 150%, 200%), power consumption increases at higher rate (off, 100%, 200%, 400%).\n[A] Added Steel Mesh Fence Gate (single or double height gate fitting to the Steel Mesh Fence).\n[M] Waste Incinerator processing speed tweaked.",
|
||||
"1.0.19-b5": "[A] Added right-click display of power and progress information for Block Breaker, Solar Panel, and Tree Cutter.\n[A] Solar Panel power curve tuned.\n[A] Mod manual 1st edition release recipe added.\n[A] Factory Hopper: Resetting NBT when breaking with empty inventory (for stacking), enabled item cap for all sides.\n[M] Electrical Furnace model polished.",
|
||||
"1.0.19-b4": "[A] Ported primary Immersive Engineering dependent recipes (alternative recipes will still work if IE is not installed).\n[M] Furni comparator output overrides reflect input slots and empty fuel state/power-cutoff.\n[M] Solar Panel config: Default value for internal battery capacity increased.\n[F] Block Placer: Shifted GUI player slots 1px to the right.\n[A] Added mod block tags for slabs, stairs, and walls (PR#89, thanks CrudeAustin for the data).\n[A] Added experimental Patchouli manual (creative only).\n[!] Skipped blacklisting Treated Wood Crafting Table slots for the inventorysorter mod due to potential startup crashes for single player games (issue #88 fix deferred).",
|
||||
|
|
Loading…
Reference in a new issue