From 06233d25ad9c55abaec276360db3b018c7cc2368 Mon Sep 17 00:00:00 2001 From: stfwi Date: Wed, 6 Mar 2019 20:59:25 +0100 Subject: [PATCH] Crafting table keeps inventory and has 8 storage slots. Inset light harvest tool and strength adapted. Crafting table recipe changed. --- 1.12/gradle.properties | 2 +- 1.12/meta/update.json | 3 +- 1.12/readme.md | 4 + .../engineersdecor/ModEngineersDecor.java | 6 +- .../engineersdecor/blocks/BlockDecor.java | 5 +- .../blocks/BlockDecorCraftingTable.java | 405 ++++++++++++++++-- .../engineersdecor/blocks/BlockDecorWall.java | 5 + .../wile/engineersdecor/blocks/ModBlocks.java | 4 +- .../engineersdecor/recipes/_constants.json | 9 + .../treated_wood_crafting_table_recipe.json | 8 +- .../gui/treated_wood_crafting_table.png | Bin 9322 -> 9902 bytes meta/update.json | 3 +- readme.md | 5 +- 13 files changed, 403 insertions(+), 56 deletions(-) diff --git a/1.12/gradle.properties b/1.12/gradle.properties index c5a9039..46ec143 100644 --- a/1.12/gradle.properties +++ b/1.12/gradle.properties @@ -3,7 +3,7 @@ org.gradle.daemon=false org.gradle.jvmargs=-Xmx8G version_minecraft=1.12.2 version_forge=14.23.5.2768 -version_engineersdecor=1.0.1-b3 +version_engineersdecor=1.0.1-b4 # # jar signing data loaded from signing.properties in the project root. # diff --git a/1.12/meta/update.json b/1.12/meta/update.json index 83e4333..707db83 100644 --- a/1.12/meta/update.json +++ b/1.12/meta/update.json @@ -1,6 +1,7 @@ { "homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/", "1.12.2": { + "1.0.1-b4": "[M] Crafting table keeps inventory and has eight storage slots.\n[M] Adapted inset light strength and harvest tool.\n[M] Crafting table recipe adapted.", "1.0.1-b3": "[A] Added inset light (glowstone-metal, light level like torch, can be used as floor/ceiling/wall light).\n[M] Crafting table model updated (issue #7, thanks majijn).\n[M] Logo image updated.", "1.0.1-b2": "[A] Added treated wood crafting table.\n[A] Added treated wood stool.\n[F] Fixed ladder bounding boxes to allow climbing connected trap doors (issue #6, thanks to Forgilageord).\n[M] Improved wall-block connections (wall elements only connect to other walls or gates, as well as to solid blocks if these blocks are in a straight line with at least two wall elements).\n[M] Decor walls are defined \"solid\" on top, so that e.g. torches and redstone tracks can be placed on them.", "1.0.1-b1": "[F] Fixed missing condition for ie:stone_deco in recipe constants.\n[A] Added clinker brick wall.", @@ -12,6 +13,6 @@ }, "promos": { "1.12.2-recommended": "1.0.0", - "1.12.2-latest": "1.0.1-b3" + "1.12.2-latest": "1.0.1-b4" } } \ No newline at end of file diff --git a/1.12/readme.md b/1.12/readme.md index fb99220..bd756b8 100644 --- a/1.12/readme.md +++ b/1.12/readme.md @@ -10,6 +10,10 @@ Mod sources for Minecraft version 1.12.2. ---- ## Revision history + - v1.0.1-b4 [M] Crafting table keeps inventory and has eight storage slots. + [M] Adapted inset light strength and harvest tool. + [M] Crafting table recipe adapted. + - v1.0.1-b3 [A] Added inset light (glowstone-metal, light level like torch, can be used as floor/ceiling/wall light). [M] Crafting table model updated (issue #7, thanks majijn). diff --git a/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java b/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java index 297108f..2f57c24 100644 --- a/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java +++ b/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java @@ -126,8 +126,7 @@ public class ModEngineersDecor final BlockPos pos = new BlockPos(x,y,z); final TileEntity te = world.getTileEntity(pos); switch(guiid) { - case GUIID_CRAFTING_TABLE: - return (te instanceof BlockDecorCraftingTable.BEntity) ? (new BlockDecorCraftingTable.BContainer(player.inventory, world, pos)) : null; + case GUIID_CRAFTING_TABLE: return BlockDecorCraftingTable.getServerGuiElement(player, world, pos, te); } return null; } @@ -139,8 +138,7 @@ public class ModEngineersDecor final BlockPos pos = new BlockPos(x,y,z); final TileEntity te = (world instanceof WorldClient) ? world.getTileEntity(pos) : null; switch(guiid) { - case GUIID_CRAFTING_TABLE: - return (te instanceof BlockDecorCraftingTable.BEntity) ? (new BlockDecorCraftingTable.BGuiCrafting(player.inventory, world, pos)) : null; + case GUIID_CRAFTING_TABLE: return BlockDecorCraftingTable.getClientGuiElement(player, world, pos, te); } return null; } diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecor.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecor.java index 2a991a9..9166e91 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecor.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecor.java @@ -165,7 +165,6 @@ public class BlockDecor extends Block { return super.getStateForPlacement(world, pos, facing, hitX, hitY, hitZ, meta, placer, hand); } @Override - public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) - { return super.removedByPlayer(state, world, pos, player, willHarvest); } - + public boolean canHarvestBlock(IBlockAccess world, BlockPos pos, EntityPlayer player) + { return true; } } diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java index 3f402a2..07b2af5 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java @@ -8,25 +8,33 @@ */ package wile.engineersdecor.blocks; +import wile.engineersdecor.ModEngineersDecor; +import net.minecraft.block.Block; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; +import net.minecraft.world.Explosion; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.*; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import wile.engineersdecor.ModEngineersDecor; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -34,6 +42,7 @@ import javax.annotation.Nullable; public class BlockDecorCraftingTable extends BlockDecorDirected { + public BlockDecorCraftingTable(@Nonnull String registryName, long config, @Nullable Material material, float hardness, float resistance, @Nullable SoundType sound, @Nonnull AxisAlignedBB unrotatedAABB) { super(registryName, config, material, hardness, resistance, sound, unrotatedAABB); @@ -51,7 +60,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected @Nullable public TileEntity createTileEntity(World world, IBlockState state) - { return new BlockDecorCraftingTable.BEntity(); } + { return new BlockDecorCraftingTable.BTileEntity(); } @Override public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) @@ -61,45 +70,71 @@ public class BlockDecorCraftingTable extends BlockDecorDirected return true; } - //-------------------------------------------------------------------------------------------------------------------- - // TE - //-------------------------------------------------------------------------------------------------------------------- - public static class BEntity extends TileEntity + @Override + public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { + if(world.isRemote) return; + if((!stack.hasTagCompound()) || (!stack.getTagCompound().hasKey("inventory"))) return; + NBTTagCompound inventory_nbt = stack.getTagCompound().getCompoundTag("inventory"); + if(inventory_nbt.isEmpty()) return; + final TileEntity te = world.getTileEntity(pos); + if(!(te instanceof BTileEntity)) return; + ((BTileEntity)te).readnbt(inventory_nbt); + ((BTileEntity)te).markDirty(); + } + + private ItemStack itemize_with_inventory(World world, BlockPos pos) + { + TileEntity te = world.getTileEntity(pos); + if(!(te instanceof BTileEntity)) return ItemStack.EMPTY; + ItemStack stack = new ItemStack(this, 1); + NBTTagCompound inventory_nbt = new NBTTagCompound(); + ItemStackHelper.saveAllItems(inventory_nbt, ((BTileEntity)te).stacks, false); + if(!inventory_nbt.isEmpty()) { + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setTag("inventory", inventory_nbt); + stack.setTagCompound(nbt); + } + return stack; + } + + @Override + public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) + { + if(world.isRemote) return true; + final ItemStack stack = itemize_with_inventory(world, pos); + if(stack != ItemStack.EMPTY) { + world.spawnEntity(new EntityItem(world, pos.getX()+0.5, pos.getY()+0.5, pos.getZ()+0.5, stack)); + world.setBlockToAir(pos); + world.removeTileEntity(pos); + return false; + } else { + return super.removedByPlayer(state, world, pos, player, willHarvest); + } + } + + @Override + public void onBlockExploded(World world, BlockPos pos, Explosion explosion) + { + if(world.isRemote) return; + TileEntity te = world.getTileEntity(pos); + if(!(te instanceof BTileEntity)) return; + for(ItemStack stack: ((BTileEntity)te).stacks) { + if(!stack.isEmpty()) world.spawnEntity(new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), stack)); + } + ((BTileEntity)te).reset(); + super.onBlockExploded(world, pos, explosion); } //-------------------------------------------------------------------------------------------------------------------- - // Container + // ModEngineersDecor.GuiHandler connectors //-------------------------------------------------------------------------------------------------------------------- - public static class BContainer extends ContainerWorkbench - { - private World world; - private BlockPos pos; - private EntityPlayer player; + public static Object getServerGuiElement(final EntityPlayer player, final World world, final BlockPos pos, final TileEntity te) + { return (te instanceof BTileEntity) ? (new BContainer(player.inventory, world, pos, (BTileEntity)te)) : null; } - public BContainer(InventoryPlayer inv, World world, BlockPos pos) - { - super(inv, world, pos); - this.world = world; - this.pos = pos; - this.player = inv.player; - } - - @Override - public boolean canInteractWith(EntityPlayer playerIn) - { return (world.getBlockState(this.pos).getBlock() instanceof BlockDecorCraftingTable) && (playerIn.getDistanceSq(this.pos) <= 8*8); } - - @Override - public void onCraftMatrixChanged(IInventory inv) - { - try { - slotChangedCraftingGrid(this.world, player, this.craftMatrix, this.craftResult); - } catch(Throwable exc) { - ModEngineersDecor.logger.error("Recipe failed:", exc); - } - } - } + public static Object getClientGuiElement(final EntityPlayer player, final World world, final BlockPos pos, final TileEntity te) + { return (te instanceof BTileEntity) ? (new BGuiCrafting(player.inventory, world, pos, (BTileEntity)te)) : null; } //-------------------------------------------------------------------------------------------------------------------- // GUI @@ -108,8 +143,8 @@ public class BlockDecorCraftingTable extends BlockDecorDirected @SideOnly(Side.CLIENT) public static class BGuiCrafting extends GuiContainer { - public BGuiCrafting(InventoryPlayer playerInventory, World world, BlockPos pos) - { super(new BContainer(playerInventory, world, pos)); } + public BGuiCrafting(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te) + { super(new BContainer(playerInventory, world, pos, te)); } @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) @@ -128,4 +163,302 @@ public class BlockDecorCraftingTable extends BlockDecorDirected } } + //-------------------------------------------------------------------------------------------------------------------- + // Crafting container + //-------------------------------------------------------------------------------------------------------------------- + + public static class BContainer extends Container + { + private final World world; + private final BlockPos pos; + private final EntityPlayer player; + private final BTileEntity te; + public BInventoryCrafting craftMatrix; + public InventoryCraftResult craftResult = new InventoryCraftResult(); + + + public BContainer(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te) + { + this.player = playerInventory.player; + this.world = world; + this.pos = pos; + this.te = te; + this.craftMatrix = new BInventoryCrafting(this, te); + this.craftMatrix.openInventory(player); + this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 124+14, 35)); + for(int y=0; y<3; ++y) { + for(int x=0; x<3; ++x) { + addSlotToContainer(new Slot(this.craftMatrix, x+y*3, 28+30+x*18, 17+y*18)); // block slots 0..8 + } + } + for(int y=0; y<3; ++y) { + for (int x=0; x<9; ++x) { + this.addSlotToContainer(new Slot(playerInventory, x+y*9+9, 8+x*18, 86+y*18)); // player slots: 9..35 + } + } + for (int x=0; x<9; ++x) { + this.addSlotToContainer(new Slot(playerInventory, x, 8+x*18, 144)); // player slots: 0..8 + } + for(int y=0; y<4; ++y) { + for (int x=0; x<2; ++x) { + this.addSlotToContainer(new Slot(this.craftMatrix, x+y*2+9, 8+x*18, 9+y*18)); // block slots 9..17 + } + } + this.onCraftMatrixChanged(this.craftMatrix); + } + + @Override + public boolean canInteractWith(EntityPlayer player) + { return (world.getBlockState(pos).getBlock() instanceof BlockDecorCraftingTable) && (player.getDistanceSq(pos) <= 64); } + + @Override + public void onCraftMatrixChanged(IInventory inv) + { + try { + slotChangedCraftingGrid(this.world, this.player, this.craftMatrix, this.craftResult); + } catch(Throwable exc) { + ModEngineersDecor.logger.error("Recipe failed:", exc); + } + } + + @Override + public void onContainerClosed(EntityPlayer player) + { + craftMatrix.closeInventory(player); + craftResult.clear(); + craftResult.closeInventory(player); + if(player!=null) { + for(Slot e:player.inventoryContainer.inventorySlots) { + if(e instanceof SlotCrafting) { + ((SlotCrafting)e).putStack(ItemStack.EMPTY); + } + } + } + } + + @Override + public boolean canMergeSlot(ItemStack stack, Slot slot) + { return (slot.inventory != this.craftResult) && (super.canMergeSlot(stack, slot)); } + + @Override + public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) + { + ItemStack stack = ItemStack.EMPTY; + Slot slot = this.inventorySlots.get(index); + if((slot == null) || (!slot.getHasStack())) return stack; + ItemStack slotstack = slot.getStack(); + stack = slotstack.copy(); + if(index == 0) { + slotstack.getItem().onCreated(slotstack, this.world, playerIn); + if(!this.mergeItemStack(slotstack, 10, 46, true)) return ItemStack.EMPTY; + slot.onSlotChange(slotstack, stack); + } else if (index >= 10 && (index < 37)) { + if(!this.mergeItemStack(slotstack, 37, 46, false)) return ItemStack.EMPTY; + } else if((index >= 37) && (index < 46)) { + if(!this.mergeItemStack(slotstack, 10, 37, false)) return ItemStack.EMPTY; + } else if(!this.mergeItemStack(slotstack, 10, 46, false)) { + return ItemStack.EMPTY; + } + if(slotstack.isEmpty()) { + slot.putStack(ItemStack.EMPTY); + } else { + slot.onSlotChanged(); + } + if(slotstack.getCount() == stack.getCount()) { + return ItemStack.EMPTY; + } + ItemStack itemstack2 = slot.onTake(playerIn, slotstack); + if(index == 0) { + playerIn.dropItem(itemstack2, false); + } + return stack; + } + } + + //-------------------------------------------------------------------------------------------------------------------- + // Crafting inventory (needed to allow SlotCrafting to have a InventoryCrafting) + //-------------------------------------------------------------------------------------------------------------------- + + public static class BInventoryCrafting extends InventoryCrafting + { + protected final Container container; + protected final IInventory inventory; + + public BInventoryCrafting(Container container_, IInventory inventory_te) { + super(container_, 3, 3); + container = container_; + inventory = inventory_te; + } + + @Override + public int getSizeInventory() + { return 9; } + + @Override + public void openInventory(EntityPlayer player) + { inventory.openInventory(player); } + + @Override + public void closeInventory(EntityPlayer player) + { inventory.closeInventory(player); } + + @Override + public void markDirty() + { inventory.markDirty(); } + + @Override + public void setInventorySlotContents(int index, ItemStack stack) + { + inventory.setInventorySlotContents(index, stack); + container.onCraftMatrixChanged(this); + } + + @Override + public ItemStack getStackInSlot(int index) + { return inventory.getStackInSlot(index); } + + @Override + public ItemStack decrStackSize(int index, int count) + { + final ItemStack stack = inventory.decrStackSize(index, count); + if(!stack.isEmpty()) container.onCraftMatrixChanged(this); + return stack; + } + } + + //-------------------------------------------------------------------------------------------------------------------- + // Tile entity + //-------------------------------------------------------------------------------------------------------------------- + public static class BTileEntity extends TileEntity implements IInventory + { + public static final int NUM_OF_CRAFTING_SLOTS = 9; + public static final int NUM_OF_STORAGE_SLOTS = 9; + public static final int NUM_OF_SLOTS = NUM_OF_CRAFTING_SLOTS+NUM_OF_STORAGE_SLOTS; + protected NonNullList stacks; + + public BTileEntity() + { stacks = NonNullList.withSize(NUM_OF_SLOTS, ItemStack.EMPTY); } + + public void reset() + { stacks = NonNullList.withSize(NUM_OF_SLOTS, ItemStack.EMPTY); } + + public void readnbt(NBTTagCompound compound) + { + reset(); + ItemStackHelper.loadAllItems(compound, this.stacks); + while(this.stacks.size() < NUM_OF_SLOTS) this.stacks.add(ItemStack.EMPTY); + } + + private void writenbt(NBTTagCompound compound) + { ItemStackHelper.saveAllItems(compound, this.stacks); } + + // TileEntity ------------------------------------------------------------------------------ + + @Override + public boolean shouldRefresh(World world, BlockPos pos, IBlockState os, IBlockState ns) + { return (os.getBlock() != ns.getBlock()) || (!(ns.getBlock() instanceof BlockDecorCraftingTable)); } + + @Override + public void readFromNBT(NBTTagCompound compound) + { super.readFromNBT(compound); readnbt(compound); } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound compound) + { super.writeToNBT(compound); writenbt(compound); return compound; } + + //@Override + //public NBTTagCompound getUpdateTag() + //{ return writeToNBT(new NBTTagCompound()); } + + //@Override + //public SPacketUpdateTileEntity getUpdatePacket() + //{ return new SPacketUpdateTileEntity(getPos(), 0x1, getUpdateTag()); } + // + //@Override + //public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) + //{ readFromNBT(pkt.getNbtCompound()); super.onDataPacket(net, pkt); } + + // IWorldNamable --------------------------------------------------------------------------- + + @Override + public String getName() + { final Block block=getBlockType(); return (block!=null) ? (block.getTranslationKey() + ".name") : (""); } + + @Override + public boolean hasCustomName() + { return false; } + + @Override + public ITextComponent getDisplayName() + { return new TextComponentTranslation(getName(), new Object[0]); } + + // IInventory ------------------------------------------------------------------------------ + // @see net.minecraft.inventory.InventoryCrafting + + @Override + public int getSizeInventory() + { return stacks.size(); } + + @Override + public boolean isEmpty() + { for(ItemStack stack: stacks) { if(!stack.isEmpty()) return false; } return true; } + + @Override + public ItemStack getStackInSlot(int index) + { return (index < getSizeInventory()) ? stacks.get(index) : ItemStack.EMPTY; } + + @Override + public ItemStack decrStackSize(int index, int count) + { return ItemStackHelper.getAndSplit(stacks, index, count); } + + @Override + public ItemStack removeStackFromSlot(int index) + { return ItemStackHelper.getAndRemove(stacks, index); } + + @Override + public void setInventorySlotContents(int index, ItemStack stack) + { stacks.set(index, stack); } + + @Override + public int getInventoryStackLimit() + { return 64; } + + @Override + public void markDirty() + { super.markDirty(); } + + @Override + public boolean isUsableByPlayer(EntityPlayer player) + { return true; } + + @Override + public void openInventory(EntityPlayer player) + {} + + @Override + public void closeInventory(EntityPlayer player) + { this.markDirty(); } + + @Override + public boolean isItemValidForSlot(int index, ItemStack stack) + { return true; } + + @Override + public int getField(int id) + { return 0; } + + @Override + public void setField(int id, int value) + {} + + @Override + public int getFieldCount() + { return 0; } + + @Override + public void clear() + { stacks.clear(); } + + } + } diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWall.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWall.java index ab90b07..d63d694 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWall.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWall.java @@ -175,4 +175,9 @@ public class BlockDecorWall extends BlockDecor private boolean canWallConnectTo(IBlockAccess world, BlockPos pos, EnumFacing facing) { return canConnectTo(world, pos, pos.offset(facing), facing.getOpposite()); } + + @Override + public boolean canPlaceTorchOnTop(IBlockState state, IBlockAccess world, BlockPos pos) + { return true; } + } diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java b/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java index ed37653..84bf152 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java @@ -84,7 +84,7 @@ public class ModBlocks public static final BlockDecorDirected INSET_LIGHT_IRON = new BlockDecorDirected( "iron_inset_light", BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT|(14<`S(U z>|>p>4#HT5-x+;A-|y%9{GRK%uIK;fa+z~x&U@yZ^LoGT*L~lw_j!8R@H{7*02=@R zoO%~@t^fc8+=T#pS;38^TZTQjVZEh)UI*A={H1(Oj{-m0hrVEr0RZ-cjDHA_n8XJF zB7mOG*=t_?bFT+5@TQpIs_e|l)Up6p0g-)76OI?2$rx+5IXh<`fh}B!_`$2zlQjfg z2&~y&o}~uT^JUC!t7dB)dp#Y`k5QG^61u-WFQq=xwVp{%@N1ktu6aP@DMo;Fnc~y= z_}%g)lk1*uq?hBYrGe7HyB3lF4;9H}o;oVU!cMYacRG=BNIH3QA+s_B(Rw+@BsDyM zNo3`UKYYb{A?%Qj^A(p9!6s5ER(WL0EZC$J$-)e{DD}8GaOLnDEp14K4~ossm;_w* z>Ilv6c|a1F;YhnVoiHODcHmuo3hy0iOttB$z4=o4`DV`73chF9R^B{I-o!J7DR4t|8&2&-S3t5)oSsdaJkB$Hoi7J6c@{#&ab13Jy5}6st5Pr_M=&9V^5rVYUaorG zletH0I?ZotMQ!}hnvX*Cl^;LPpW1sFikFdD_AD^2!>QwYcqWIS*#X7#YT1%(w17ww zvvl$!Xb@a;$n?T#zz#6`5Vv9XVc{Hq<;*!p6=~Y+s3t39dE0YGLk<|0$TYvt<{=8Kx_(u+u{`*K2NOdA z;#6D}PUZ3sKCzzyp#{Yq0v(qx06IW0QTLi7-|lJitR25Ucao{HnU)|KnGAe7*duSv znSx|-;!xh)XEK1nD?NDE%C-mN5q~V?(Wc+kWUab2+fg#(_IDj~{OXY`p3Qn79LqcU+(?dU&DEnlv2n`~fQU{;q+;{^aGv{9yg?C=Qs7DvPHWKPK zTQ61VeN6w+J5_wOnQX{m*&gP#agMAmm!e4JhpwsWA+{DG*&Eborb9O2KKI#~gzL@t z?8sQQKe7WAfdA^~NQ8`xEVPX&An*s(S(LV7h@(&W~rCF|SV=_6VD?^Gpo?ybox*EgI zL4w43FDx-76kKo%lx*4Wz#^R-@=h`(ybeI3?wW|Gu-e(}zY!X4%fud3(@&UUVa@+} zhxon9b|tcbUv?r=W1Uk|FjTVFEW=dcB1ZGquQS;TK9f439x_VJM-wE!{+<%NpMooS zKO?i|mX~u52-3}YbT+Aw7RJszA<#2*`C_W^z7C^Pw}ZY&%E+6tCp&3GYaO5%^}a~k z4*!tHg3=wo=J(}0B*i#Kr0GOv<;h;#;_|+80h#F?nJn_+dG{emeh0I=CZke8(!hP+ z+wyynC1FpN)P|#XcKqI$AU1BzNZc{lSui1u09XUg{#xkVDSl#xteg zjb>!nI)Y-Ysj{koUBFkfcR}Y)P+v?4@MvD)yM_xoEypdv@5Ub1#o?NGw3U6Lz8Yxc z>`;oWJKysq&CkX68s8{@7zW(z_VcpFTzh*x?-sX1KEV1RSef;%Ejdo#{amW?inaaCVCz`dk+h6B*)NtXKjtDkIVjI#1`N7G`>hR64i8Pg<>9an)h-}2t}Ru9_Y7@_-XOPv?TAbsJr=x4e4;oiV_l`d^9;RXXy@yH zNK`R->yfGn#Kb~LwkIoB(Obx5ipdO65iWIEJDd1+-iL~0VF`U^efH)={^X2Bs#4g( z7You=q2Rj_CQ1NMQU0y^b&l1?_Q^>)T+<=9%;AVCt}LP=oem;E?S^~u=#tx$at@Sf zoYvOr_Car-wj%5G4eO$a?K5i&r+b(m{JN|I2Uc@yPKI3HGl_OCO2{2C{rs{~TEclr zHiUw0WWPE;Ax)WKXRl)V&Lo^r-0lh-BAk{XZwiGiHPa{dwY9fj>U|+xnL;Oa<`*|( z;7rX`#OAB`E0S(=$Kf$dMJF`QP~jn@QAIz9wd)~5cyFoS>&cEF)Dl<_R;nRzD3px7 zz<%{)(+9V#_m7$|Kbl&yuFT7MC;U7xA&}6S;e`_DCb)YSB9Lp-Xs`k#kHf&a`D%HMu-a;I**Vdhn!-4LQY6#kOFF~G` zT_Qj`!ffqYV15v$i2x#0@#=7r{Fn70qBf+Udja^V*|8DPj+dFf4y-QLl&xrs-Gp8zR!gRvQC^i)h+%d^~;Lj8p!} z6*G3(?}1CpU1e2TG57fUIKD?iz1Z%qZ}%ahqd{He3atG@2+Bm7c}W$V&C^l$nOWxZ_Op0gW^IQ$PlsDWv@- z3_m6c$D;v73Lq<+U?y0r8p`#Q*=7ukXW85My7LHN6tHiDpt+ssI)$|72;ev@pys?{ z@jnjq_A3qcr)*wU1z@nzgRF#oP|cP7;Jo7#FaW&PqSs95QA90-irx!H?eoIfH$iZV zx1YGAmmiIc9ov##(fI79i@obVNQbW^7J$RG9@f^J(_!)ISFEAaWXmP2uMnKVT`evMk?xwY zASAiSJ*=x0JK0^lKue|jRa1@M*aP_sX-`$hET;)$zpq+HA!xMc!Z)jDtVJ4xM?&p z{nhzMvRxbNq{QIamE?V^uh~J^NKF8M_puItk~eC#%jAtg zrq{aH5%{aE5P5DVD?9AoGfYrY-O+rpb-YyS&%JQcyB;Q5)yN!qV||r>hjO|>< z#t}1}NfP6>!0f5*f6Sb+aTx)ICZHx=CCm($JPDwNf7BIsucprYbd4pphr6|nw%K#_ zn(z|J{oxp8xhxeh)6#7jiH;966TFRls#$~tHdJz2m~AfXIfb0VDsz#{)&hI_TcwZ! zb@(e?Uv%ffMtvqNnPszG^M+Kae8XfMcvgorVuzySJ{Ylw+eYgNk@UELkV(kk@brtP z#cRDGz|&{);kEt6o}4NRUA`CKz`+potAJ257bP>=GY3_C>oDKKYZu}C2w2$t zfXEWvuGEJg;k4oYmuR3GQW4Kg7U?N7a2S2DTV}+Ypa%QSwOj6#JI(cu0bvEDewCb8 z+d6j%3A1}5`HSYb3=pRbwj2dAQ0JSNf3!fhygWup9$ursHl7tdz;)xK?0-%!+T*V~ zA>;X2^mStRk2Rd*_y!B$Xg8R0y)CpB8=y-TZD#Xglgs0Uktd*kO~~2$sJ%K(%w#gR zXM>c{vFD?A+Y7NkUO8bqe{(IJH+IN+;qK>?62lcs-9jC#)aJ8yEx15u)shev*Q+l? zlHvnkEzGouPP{?((9g%TS=&g4s}WM=A{U0JFJ-TS1lca!i4B&S;|3YC3FWlBVp_Q! zN06b?v*M6=yHSAeKmZB6h8AY>C`fjLXOKe_NjS-PVdQQ$c%fzpV1wT?;@^{)uJ+6v zClG_Shm+P)ZzAw^WJX>!5rJ#Mf7JrV_p9(pOZ?m6sxC7*I7tBw_|x0^E9nz?pJD!< zLa9uCh$>yAu+TeikWEBcPu}|6Z8Ivv;6vf*AZ7$BjO?;-zv9ZVj?gE?Er5v@cz(t zSylXk_GdI;z)Z3QX|lF|xDcY(r1cmH#2$>$MOx}yqlz&d5$7T|V%gI3Z!Q6RrVv;& zb7`@jM9;9*-O=G1RA0zTD0SWLOgkE@TFbkui3f-J(@H4Lo5jmOgf}S2KTrI1eoh+@ ziWDX^gXW{?v}=D9rz(_GAcy0o{0FO3HY+2*0IlH}c()V+hW-Emj!OKX&PX(Q3=D5) zO)Fkj8uZp&!&02RCOmF~F9ovp4!-GnTgX@hG`*yPOx0SZsoMN^9;ZG z6mbHKNRl^ikVtfJshr zJ`#w)jJddjgfl3v3`V|WK6RJW12k@ z+Nz^G&>whVHmogp4fFd0hGsQ5CH&H%Y=s}Q5@z??Aw48MMXL~{bK8Swa)T0c$1i^V zE^JB{Y3&Sm!&P)gC1^GS=nq{*`r*=3f-%4RW?f$r`ArR0?F1#;W!CIuzFtTE*6j?~ zB!aCK2dkYFHBDzEZrw|S8Mp&@IVlwNwzV#_FniHG2I+r|sZx(9P&Ys?f63(l_F#Qf z@o%9>Bmzpyn@%i_6E8g;hAhz_UW-@rv>b|AK_tB#h2wh zcZ`Nt#dv?v__Xm_tVX_#+NYhs9M2D>YH0MGag#-m$0~NZR+P4S%Z(aQ{;qSfek)Dd zAKOO;OYu8?6jUEY!_vB8r*soPyKK6UJ-#sC>AOAFkVWfGzrlf`P_v9mnov92{n9sf z_QS~Uz#52H$SsgXSp?QeKqA}aDNipwL<$Z;pHa$?BM$ettifS6!OWyo3X^;-_K(rF zS^UK*%0tju9wcPs%c4ZzQVXN(0WAv!#Z@GXLd_k3uhF*RgkyN z9Ido*Y>)ALq9#~=n^3%dW*%Mpnish^^IDfQhH;g;jh*M^q5Rm0oPZ>8L-Xa@)MN&; zUcD00)R5vf7m<;0J%MM^gq2*Ck$dRGNg9u`X9;bO|5Y}4MtP{=)DYo*?rQWaOa>~6 zejb76uY|y3p``s3^(Pn}f~&3Bu6al|-e-nGzMo0VS}aQEbx5Daa*A=;eA=x?iAQ-V z2#!1iTYEFyY0_AfWAbW}RdR^mDY4C3)pp;AcwDfQ_09_<{@@sZ7^}zw1um8_U)aM& z-LLHfl2+_Y*^lf|6%JIEZA_ZF3=<;Io}Q^)W@0kL|KLQRcU35@E`*rSAN!d57!%=QU{US_*|uPllcx#qB> zYOs=k^!N6mZM6TeXn<%Qg>dhKqATE<-7@0|E&JXeTSl=$OV!Bm;va<~)GK(UN!aENIFQ?Bpg=aNs3?VqN>4tT!R6a-hPPUE*5ZC zb)Y)umKWGSa_y@j1tXsWHBm_i(?EMecdZ_aQnWJFXu~F}*)j5&AGT{&27ic4lnwrT zT)JYj+m9Vn*7nIQ(%zbSC9w-u{jp0Hd^`k0QJY0#>7kFvHTF=9GyObhL7p(%=($6T zj$KYXEQ_+M=}HbiYVNh|mliXDo61Ts+dSBCMdH)v8FGX6T&l|dDw z-Ztn}G9ABbB-duxy?g*>^J(cgTrzO*QAt zl0}{5!p~!J&F^66L3ma}zT#kHG6sS;U{zMXB)0DOUQ8Hl+$6ljaCpsg9cuT$R_@$`gy+kO`anNdGpOKs4Lr}8nOny@!{u@}t9Cm*3@(dY2dxvgs z??1(r^86_N&S7#25Xs47S6TqHVe5Q@-ZMqqn1njUQN0?zFM=tPhy}3bn0zN zGqNZd+n_oJ-_*7q@LG0RLMIL)8)}reC^j6%Y2>3EjMV!JObtt7$NArH%EC!{ZU9G< zd?3PMkzY}q;(i`P{o4ciG_*KVYqwW_S7_nYl?t$Hw+Nukgn;vJS{R1g00CsSGj_xb zp6b0eVIG-{XktKi`k=x(cr1cJDH8P%@Ydl_%{4|3r2$kC!VO@vgz-T_61(OK_-T!Y z!aCSYc>@R3JL|w+p&lwxstJljX}_O<|2-BQb{;H!k!V1omXX~C43Y95FCx~aSkT%y z)c&qGPGNfP%eM&*E{yt@%o1QTyM1@w-r3ex-=c-j%CO?^b&imxvfPko6g^Ox-0+oa zE)YzoO*dVLWs-DZfMaXP&ihKMf2AvAXR^)rW4pDLb`|A6&H;>Xad`O+aE7dJszqA+Y5CvO@OR*>vMJ52+G@gn+6_l7BwwryFR{PzH9Hs* z3R8#gAQ6m7i@X0PV!s_|3^}@dd0^x{szAi!gx!?|FdG@&uXN*4J#tfgu2XJ(SMqRj zA;hQ#1kLV1ow(h#0e&N`7pz8Om#U-VzdukWFN8IsT-z`N(c=W$=H9;xTjwNL*o;2? zWFUla>feR!fg&wC_L$?}_}G;$8q38U zqDbEn!Y@wnel1`_Ult;@LVxSTJv6l_EiBewC04-4P6oDjr*T((-g!KntaxM)d-~X> zfg$w$Mv_yHInJb-Ewp_@>vhf!*q$?>0LgAZkgHkdb+-3|giDv)`SA@BtzHLQ>J55} z6(;nS3Jlg9US+9w?Yvt@uM%#?ing*%)Y~}A-U8J$$gyH&yCiG(ej@2J9H?`UgQ5iv z1gyG&4foGrOU3IZXa&Teq~|}s8J!Mommk-Y{6^NR(2GA1)!)jxB_aCJC~0|+@}$Wj zerW|{Wy5D+8_FGA$hk%+Ho+V5_ZJS|%eU;Uv*#?~$C=bf>-(5Yd4X`p;!F~7{|QVH ziGLKbu~hR-d(W;E=Er1#0kFUeyCh_o1hPF`TH?xN5*Pg9yWr`*aO%2 z+$$=!aPr!J!#DO49N75)cisxu0q)cS5D$a$dC~r=&|WL{k;zRR+6Z z*dsYvS%YM8UOkrNqGEI69k`yGQfmLl!A64yM`Cq7q-@gY5R{xEB0Gs7D&v4BUj(@Bsfjxf9=O(ojDu5%F2&ZlL|eeYu^f5z8mErEz@y?@y1-Ped+ zw%Ql^FGca82~-px>npk?f>lG*Np5T_#DhC65>^2><^0m2J4TEf4Z12dd#7rk%lUgV_SC1ry( za|AwW0^qx11$Av3Q#{ELYV`0>A?>s@D4OcstuRW-tG~x)uc^y{-UGR-_Q834%q)^l zjfDfMR(uA(suR=I|JD-$pyau!EEKxdL#h!Wzjti%*-0VwwNHtivjc^o11cfNZGtLI3r8t9#cJ zMluYRfqK0ud&^NzCw{vWWZqz8j=bq&hu}HKU`!+18ufcJ5&}L@V&1Fq6UHsbWsQn8 z(EJ8adu}<#Fy*=@BD%8AVuz!dsf=eFZkEDc-6)CNoRJW%7}{ssqTbJ_S;qhDWE?s` z9T+NL!k6Fhb>@$(#vwJaB7eFa=;W%hk`a6E#`OADVD_1m@H(a3m{nl(uLHVVE zZ_)stpvf-g;pNqKpSt%_Uv4G+qn|_4n4etm6*fWo1zjK)e731gd4>n5_C6dM-h4XF zYKEzDp=J$F!hATvf=^6;p7?U{@xbb@VVUM$#D_TV_Zzk*q^p|I#I&lMv$7g~^AMX2 zW%-eOnbt)8`%-cCicZ{Kenh(#-?#h*%$AmDyY;Hl@4R3r`o8;1HUvD?Irid$*n$7s i{4YcBGrW5T`XF)tRc18u68N|opm)wtCs)hn(fxDL8_AZkCMlCGQ3xSRmO)u- z#uBoR$1<4g`#QffdY$)1f)A?7X6h_kHtgOI)uYvy{9ZDQ&dZ6Qu*X z?niaR7K=s>ab7kQ)z(PU(|N&iz4ydoTB`MAQ20X~6P_1i`4=xZhR1ubtxkVWsZ8}> z31k626s`+$12CsTBNIjoNhCl}Mv{S?&d!4n7cG8g>x=={Ml)6hY~V^<81-vuG@UTx z`k*dRl0l~8L}hVjL^q2E8ynV`MKxz!B>atnAux#2uosjv16Vd0nLj;O@#yovxYEWq zJ@)EOYvETRNp{I_qB3)o@O=-n*>fd>&bLZN&;pmSbOj}6`mzS@;*Z7D(Pe3$dVJfA zyyTSj*I&0`pPfUe^ts}+j`syz1Fu95$rWreVI-oC?vYFB$IR!e#uoIHnY9BUuChME zz3Xbv2d|mg0Xdn#j5f5L*!)%sBDkG8u$^k|e6$b?3!~>tQSo4#Oj7qfD0Png9LB9H zIgAiXqt_6}QclFU<@9{HtrBsT&1VrxXjHCe%YV;eBp}>}z9j7=@eCMD&~O0ESn&x4 z2PI1|ozO8jr;IQE*7s}<@zD6wcn!tI2Sw32rdEqh$iR&|k57C_O9-qFDNhG+h@F_0`zUCZjOtF#b)gcp~nv-nqqxkpkQ_Y zH2esf&en=wG&wZDG&;^~Au62rW-|J}Z#&*fIh@k`DOjSk5u}8f<1Oi{YTGT%h^f=}6FCv80v^ol3J@zx%I99|6Zs>& zQb=z9Dqji8vk0hdVW=@nq1h$LaBWC49Y5BSP1ogInHYHQ33wvsXXjXA`ik}$CwRt3 zHcBm{>EKxa*6XrR*i~k1*2yo|{lbLj85EVE-Xe=*c-F{gAnq4*?|v-p=1uN1+|8bR zXj?eGsNqw~aVbiibDD8+pRm026Ve$8-O0=0-4=ROi7s$@S#~AzRoHvIDeIKP{)*Gc-Gc9|i%FAt$zvGQ4PC;?tv@s}*c)z5~oa zh0@i49pIrDHs2+vV$k_^Ne|W=eJb|scNWcri17Mk`@-;U{&};ei8}{DU`(_ZGK;|g({R4NWoW0tm>Mno#<>soBZtAZYDSO0@ ze80^F{bB;VsNkd}HKEAU-SN?nyMY^z0)UGFKr_l!rmVQzZKt8=kMq^bndD-Zk?A_` z;n7v^;ZsW?KAVzq^1f#Y(rYg{%8apeY3u1>o&pUPFc;Y}(@v>}VNFQ+lAm|~8aUTf z?%lCPS{60S&65$ZDkg*n@BZA03#9s1v>Xp<$mGHwc>i3t=JHe(w6rs_fcD?TbD!3; z-zzA<1f{Dqef_#Hs=SbWgQNnRY|i3vo=k?!g?J~MVvX~3p)R#X^v#g<^0>AIoznH$C?VzM&^2t zSw>6)?*wztK7h7ta|unIN;e#+O}YCt{PCW-=bJrvH!|`V3(gdZ(~`-$ZeprQ{`0kZ z8MXC>(^n3$p0s*WCv!%RtB|zd%Y=8tTTd5%y&v>tbK&?px2;?N)wS!2<$k^^DEjrl zd$?))T48bL#gt=v4(cc5!?z3;wWY0QE0$a! zxbN22H662uCY9BKfHjCfxVxaCS!9hDxZaQ5TOqyDFRyb=No){%AevUhu=WIRJ!YJZ+OBdZ#hm?Bzg7o2JtOJ;&9Z=k=)cMeP>Ts@CKJn z%_i-?+IY;+dvN*#^?M`Nk>oS&SIbTvE#%=A;5UNW|Jm4^9-4f%I6?jV4_&*o6f>u0 z09*L=lM;n~ZZest%baq?Ak-gl^n#PN7QKmtkyq8P#{~_Qg(P*4IlW1~Y+)kt^pcy* z6>!)|Cv2D>8y0{44Z@^4bN`(s6rIflLc zO-4oKp_OU@zO-*Cu0kHob;8gz3@IW(^U|ON>HB<^>s0}@AGE|H3iWOt;~Whs`a?#* zWS`)uhBd^c!i7vCX{bV&q+fanw@n-W%Xl*!jJ$B(vM}|?r#viMrHk*+VONr^9c>6# zrd2{VtdGZ-N#9AnXupqA=|d;-9Kal8Gk|%AlYuriY#!xsA*&XaadWcYNPH zuw&UbOme0DWHj}LlAOTqD(FXVg8()iqxk{1Q-z(K{NbMKsh`8W84X!H_n|IMLejeD zUL8F~xr;zo#%@9$QPQ*!*e|jzy>6@M1H!qMGKDorS}(JZtdwYiR?VW?{alV)Y00|_ zb}D%~G%u+>YU_&(nhjcL+9E)%&R2fwQIW{OYL&_{A1!;vSf*he!h8N%geSV_IK1@-lVt zu%$V2rTi#ajEY$b@gfTo`jr_zeUc^yI}_cNUlt8}l>vV}=;{lEa5gXG-Yo4^CW(m4B6|L|14i1s~)6)S{cMRjBby+xcHHM)y!v-#7_nGh^8Z4 z<;HF3`q}}H-Ely@rsl!iLeJIV=ky*zHbXD`!7#2FRQ~W~u&gKQGUg3u=(G>p!Dxzs zr(Nyt(=E2~3IWGbQpXn0Z*RCCD_wH_`xDTK7ko)4;~x4S`79zJ%n$=jut zv3+%W&$AVIt2we;V;-!IsC&OjPCqu>u$PrL1I>VwdI_GVIsHDYS^8Z;JC^oyI}>XH zfhL_J6m0H<na;mb=MX)vG6ID(9H!#W5mdVkjBPE{Y{Q^!}HHtk!8M(1gpLNco zPow4R<1Bng;4;(L=VFYg8hdcZ@|ik@87Q)Y3*R;gc~o>Q=p^VgL?~0gvJ6~ES~_se zsb*8&Np%d5T2$%OZRksH#5PXout=1XUm4nmYwzZ?Tp7A#b<+}AL#>~Fo((nRJzdr( zA#K?|m0xc!6`2>x=catJnJ68mV|o@&D$obS6JSgEW9qEduiWm*joaX-yzGL8QepVeceUfLVuz7UlRGT#BCC9nF zl<@pG!By?1<1ojO8(S3%^S4X(SG>0z-W30E6ZlvWS~M^e755A3m&i>6kfpoiN=}y^ z{ZqVMl8-n;*#Zt4s~>QUZ{r@;C=~Z)p5yf_2(o;Zf7ExqzA`zyoY8PcdM}?6bm5rj z8id`k2gd&K{Kz7dscV2XD1U<)9)lGEg?p0Oo@^zI7Ek@$m4|@8hpnTx>*TJi1&UA^}h- z-7GZwr`~5Dx4tSAoLApdx})pk*}QwUQ`WRIuB*KMoQfVG<+Or zAm%>>`LzkDsT*#zO%q5pKmeY ziwZav1oJ&^Tf5A4jg$Bq%IC4_O&Me;*}&SeDbnC=1L|_mV^O-B$g$T~sn>Fq57tyD zV^LJf?v7a?z?Xt5T06MZV(=$*WZtvcX32aFqAj}gZI15I-0vZu>Sk@-KzcO|ngA_8 zS6=?Z^G5$J=oGh}s=JSdu(6U~r#JPv*yik^^rT4*LJeQ1*wUcexlgEzHfjyYQ*OAM zB;s=V6K~fwOSN5FBFwfcih`*1wpoSoSwM>soc3zKL!KxR1x@& zt?W1WO}P&Q8b%&c*U+&G{GN137d0UI(B{Fy8Kna*kITsC`WP}mXGjJ=5KZ@V*2EMT z2I$+}1hY=m^;u}VHmU8Ofaj;snKa*4YD@SrF8RJrUtpH0nO}2|I{9>+FWIoDsOO`G zcx*g3Pg!FoNaP4hC-LRwb(ZtxC4=`eA6`mGS#R&3{~UL3j`djefhheG2F(7cpPz|A zng=lO$Jpm=9=)HNF1{q=`*MqPv65i?IdljPYe1dYCzPxsw(&xeC9kHp_GUq%D{ONZ z=Lh>EB+I*&G52byLVKSqt<4iGy(6a}+GCN_PphdgkBA_Ev*Je}2s!#EKz>=d%3U`P zE{q=@&g6i03`;}x=OsJWo zizi;dsv{8qd+^ooyFjDQ`G9K)8(`|gBNRa1e|&~75J);weezeS_fJ8}86QG=lZG%f z9#38oPhR$&vq_-(RQ!;FiC$)gJ}p~OTGpL#&*llg=seF_@nd5b(7+rHv8B}3TsX;f z7og|#Q?S#-B(_J-{Cks3W|HU%Aj;`?KjJzEuHhV4SL%(E!1g!ji(N^)CmAvvTzMi5 z?>)b#pf;cr=JR+E#{S+rbFA5O^!J7ceS$3w!wk*U@woq&5=yI&vvK@UFBS3}e_bFR zfBjfw%}0rX%eQ1cc4tV)N|8efN~?iPROv?KoPZ-W!2p3j4yJ$cB@BN_l>Sv04%`9@ zae0=Oi&}jk8eD!3;OGMq=}PelTS1yYLdF<|d@TP zc7?bY_4cd3L{F-rs4xpfp1un7F$hs*R?PX( zPISoVYTD=3K<*tlNpl5g6-Rsn*ME5G-)~58)8{P43h%!(`*m((!OozxQM~x}eZ-K4 z^Ubjq)0y+<7?UP*HmlmiLq_)kR8GAyohTI_hBCbbtSx7&Uh(nTv_k#Xy@&Z0y^{h~7>IdF)ZLwI66lRWIev8ZTbjJ`dIy1l-- zH9#IG`q^y_c)X0Bd8R@9 zL+@(prW`U@i}xpPy7frBdHQG?53j%ZGM~T>gNNZsd}N$fgMI0k6=i&4{$ep2L}_W`*MWsxF*8=?^U*b%9nv>TmYXhMs}>*^)Fby7 z4|gSwq={L{;_OPbNZlAlIEtWHziVqcTIQ(|E^4;0tgkY$y_L8nRZqU19FYS@yU`)@ z8{lw;-w|P&R zMzcUugTX!nCi4GvpjSx(dV1 zTzFd>>ES%1&I{V}{bItpCfj`+K@D1zop(9>=Wtt%ejiDz2=))ISv z9B%IJXJ8zql4PYR{!Xap^|*39!6N7g%OYy?iB__b8;0D;k0C-vxqKmYYbLDfJ}heTGcV5Ed;AF(2ku+znt`!0 z2QIpEm%ldvXh1!jh*ZNW>jUOS!uP(+d^s!SVl+uy1@qKRt#G}+zAu=(RZUISA?SFe zYG#asNlP;Pwabg=3X3;A_RLuGoMTOYxgXJr^#^Wq;V=3FzM%Tyx;YBQVbYZ_TU@@2 zYM|6%90q!X{EkC7J*WFh`(sgZfzNFYoOHfw!e+34j`VpD($1(0nDL=SyBHKu{zf2} zgum_}4@OdunFj;U@5UwR@FohV7qA`z-=pK{F!m3MJi3Hsf6$@SKw*4^RW*gCO~3=W zWSR}ghnU3~E!XrdYUT-R>LU?o>X%n~5@%=kc0|7Qcoyqhw6A%Kyip`fHG^>Vd%LEl zy;v(2A}Fr1U;GR*R8x3SB1E5@u||1%%pqrR#n@xy*6cCo!!h83H&ua}GBp+U*E1il zkFB!lue=-c@koS&XsXes%&V}kXvr2i_iZ%9FJQ8n_(ORSiq&8g%7l~rz_LZO++p$J zzlMv%aw3d9OOfM&4S4+Gzs7-qyhybAh+^tw8cs(JEbJ(>DIcP#-d$_f&}1G0jT{ zSz4AFc1bhE{3fUr-Whrk3gpmv;DC45p?}%S0DiHT0V%r}qlV>L2gyeDzoA8&=!-pj zfeEgKtzrZUCW3(Rd7Vd?8aUd41~0VarkMg}tQub>D@PaM<|2kc#e7g{c++gbfH`C* z{|pb)uWEx%ysfdn-1k_ezOz|3H*_8aCne2uxTV?Pvpr+i!%c$_Lm4A?8-4^Z{^<-b zoTJQ~A9utcA-gN)#f0>b%?rUB=6(UeYdieGa-Fa1w-%K5)=FC%P$BDA_?D@`t3oxZ{e=V5c zt;9H-kl!^ix|wADw>jSe_yp8JrZ_=QOLm33pBtj(+&`=@Q38k$eLjGbI&{DX`OT%6 zF}0(80~W3^qN9^O58Uzy7UH~JRUZer{1;PhRNtP6^asQzq3k-CP(2YtYZDRFb?Khh zyLPFfh=1(brUBX&q*@n2h-v&LA$u9~7Ifv`DJ@=yB>Cud{!pSbQAk$5cQ*@eTi2Fv)GJ=G2najUCxx&O=>`p=kiHgnfOo)}3V*OeveH z*pz;Tcx}u;iN07{3)AUsw3egHvot&59(6+nVotVpo~qYGqz_~o2@!Y(YK0jEeJ>8& z7Y$9vGy0ksg;PE1I#Ze$F^xqRlQ9OSzJ$ZQ9XpA(Fwy?VsbhXCF=Oe;TZqM8KT{`LrKksK`Ky4GK1Ad& z1pPMM{IWVMPq6w?8{CQsAfC(EkAg5%8}dfbPHY z(f@oa-YIT)3xvH#;I*UWe(R7!G4l7&K>V|x1{O@UMc|cf1sj$xA@F+{V83zXZqd_T zH&z~j$2DszpFBLuEjui(yVp2Lj zF0zo6aoR5@7w4>QR@VEW8YnJ;l{>D_Y3)g{UMwt53PzyqDLYHL4Hl6#1=benBjmrN z4_iqf2eP31?;hc1AYfQ${c}{=HOMOanN6fK16abTto)U9zfGK4xs_eh2(}1S;v&)* zG{pX=JNO|8$Ws|=RGuPw<%7*ZRrSbl4dx6%$vceYxE@+(@IS@C+OtA|0d!ThsnE`<{O7zs73)k5jiAMnD=6G{Jc=yHN|ywi{0GtwxTc)DK3*M(b7$ z(PX;Ox>CV{)qW+Vug!3f&P{?P0H2W(g?ISo);FULhji{89!yQp)2mjf$Bzb2DbX0k zMFiUEJ%#2Ihh^@6++@kSmsSG;$->KR;Gqvl>w^IAG@v_6gVXs-a6Q9QX;ZaBbux?H&5`8%2IsM{$^V&NAIrJt>mcK$*q#Ui`Tr$C{vmhMr4TD_rp#B2xTop zAT*b;28^s{$WmHps70V3fc z1$s|m0-1tvl7b4)1G$h`!4DIUb{s9=tLlsWVeUoao@9A!3YatSPXToERb`zV{vW`4+&{G$$LEIag3wH-&Cbb#`r(-#eeWZq+ z02An&>V^M{!PBeut0B;I?=7SN0D3@s7T}P8&u>ELXPIIVpyES9?pzKp= zkTUa!-4igq^p?l#M2_Iv%fw3+-c{(hX<{O-r=A-#o~ep(mRucW0EsyE<+RU9fL%GJ zptzM{!K8^l%s#l5Y?4X8QvZXk$u1!?@|*=cou!Pt;{`_yj~ynT325k#Au9=0-@;Q# zEP?jr;wz)_MHtW>S7~bzFyTXs^!of4t2peG{0nV&KZ4NK$AC0Kp#9$GgFl$EzzUGzp2IFh67tTivMuu_muBb zyrZ8_9HyN9|FoRs@2Z+(wsf|4=Aq$0Bnr$t@N@Z!vvIP^>A~N}!Is)Kn3M?eq%LI3 zjz)f6+`Ue>a@#r8FtC+F_cCFFqU8u;!p|*(2+5NM3d6xjk``Fm_+MJ^w+cs8BFq1* z@@2~}(>V2*lwpetFFYhBAgWc3VHR?wtE}$x&BuxHsywZ|fOR(A61=gsJJ@F- zQApYS$ubhrY@3)dM#;+CBflC<5l5?SuTGB*9TzU=PglJqX4^@>bodyCl?`RWs-7Wd zU8&V)QI+T;4)*Cu?grOg;}mHH9A+V4$M^Gf2A~4Lw(RjtA?5Ynbs}{{qT%!AeXx+Y zMfYO=mdm?|H1Eof-Axu1U#%Xj7@VdKoNF1m2!_T2oQnV$gAb;pEmjBuYlGJcF#G{k zznV>=vX~MWZ_j%VNddBj@s?YbCw*9+P(S3UPqd2LM5)V3IWdTatM3FLb+;!{UIQC- zjJzst*<&kJ_sW&?J$OrE=TwG*pE`t+`z;EGRynqYl~&r);Z$6J%HA>;{YCcw|N6ZH dAsJip&DY=UoY0;|fsYCSI+yh|KWNxK{68xBg(v_3 diff --git a/meta/update.json b/meta/update.json index 0276de9..91577d8 100644 --- a/meta/update.json +++ b/meta/update.json @@ -1,6 +1,7 @@ { "homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/", "1.12.2": { + "1.0.1-b4": "[M] Crafting table keeps inventory and has eight storage slots.\n[M] Adapted inset light strength and harvest tool.\n[M] Crafting table recipe adapted.", "1.0.1-b3": "[A] Added inset light (glowstone-metal, light level like torch, can be used as floor/ceiling/wall light).\n[M] Crafting table model updated (issue #7, thanks majijn).\n[M] Logo image updated.", "1.0.1-b2": "[A] Added treated wood crafting table.\n[A] Added treated wood stool.\n[F] Fixed ladder bounding boxes to allow climbing connected trap doors (issue #6, thanks to Forgilageord).\n[M] Improved wall-block connections (wall elements only connect to other walls or gates, as well as to solid blocks if these blocks are in a straight line with at least two wall elements).\n[M] Decor walls are defined \"solid\" on top, so that e.g. torches and redstone tracks can be placed on them.", "1.0.1-b1": "[F] Fixed missing condition for ie:stone_deco in recipe constants.\n[A] Added clinker brick wall.", @@ -15,7 +16,7 @@ }, "promos": { "1.12.2-recommended": "1.0.0", - "1.12.2-latest": "1.0.1-b3", + "1.12.2-latest": "1.0.1-b4", "1.13.2-recommended": "", "1.13.2-latest": "1.0.0-a1" } diff --git a/readme.md b/readme.md index c880b2e..90baf15 100644 --- a/readme.md +++ b/readme.md @@ -42,8 +42,9 @@ no tile entities or user interactions are used. Current feature set: with reverse recipe. - *Treated wood crafting table*: 3x3 crafting table with IE style GUI and a model - fitting better in the engineer's workshop. Crafted 2x2 with two treated wood - slabs, one crate, and one treated wood plank. + fitting better in the engineer's workshop. Keeps its inventory, has eight additional + storage slots on the left side of the crafting grid. Crafted 2x2 with three + treated wood planks and one vanilla crafting table. - *Treated wood ladder*: Crafted 3x3 with the known ladder pattern, items are treated wood sticks.