Jump to content

IntentScarab

Members
  • Posts

    18
  • Joined

  • Last visited

Everything posted by IntentScarab

  1. For future reference, this is the code I added to make it work: BlockState state = world.getBlockState(this.pos); world.notifyBlockUpdate(this.pos, state, state, 2); I added this to the end of my tick() method and it works.
  2. That worked!! One simple line and it worked. The update to the block state is in MBE, but I didn't think it pertained to me cause it was dealing with the faces of the block with fuel burning. Omg thank you so much. Here, since I have you could I have some help on the same sort of problem? The item I have uses the durability bar to show how full it is, when it is getting the exp taken out of it the bar doesn't update. How would I update the durability bar of the item to go down as the amount decreases? Right now I have to right click on it and it tells me it is empty.
  3. Are you using the new mappings? If you are then it's prob under a different name.
  4. Ingredient#fromItems or Ingredient#fromStacks I think is what you're looking for?
  5. Ahh okay, so it's server side usually but when the gui is opened it's client side, I'm guessing? I'm sorry, but I still don't understand how changing the data on the TE by the TE doesn't result in any change with the data. I'm reading through the code from MBE and there isn't something super obvious that I'm missing... The only big change is that I pass my tile to the container, and they don't markDirty after modifying their furnaceStateData; they only do it on items being moved from one slot to the other from what I can see. This is the MBE topic I'm using as reference btw.
  6. Is the TileEntity on the Server or Client side? Cause that's what I'm using here. I am making changes to an object that holds the data I need, kinda like how MBE does it. But I'm doing this through the tick method of the Tile. I look at the debugger and it says that the object has the amount of exp from the book, book has none, then when I try to get the exp out of the block using the buttons then it tells me I haven't got any exp in the block. Am I missing something here?
  7. TIL, and that's on me for being thoughtless on that part. Though I think I fixed that. If I'm making changes on the server only then why doesn't it "save" the changes?
  8. Hello, The title is a bit confusing, I know, but I'll explain more here. I've been following MinecraftByExample's tutorial on a Furnace type block, since that is how my block kind of works. It has an object that holds the information about the block such as time, and what I have been using it for, experience points. Now I have this block that holds exp and has two inputs, an output, and four buttons. The buttons are working and doing what I want; when I click a button, the Container deals with the logic then sends the updated data to the TileEntity for it to be changed. I originally had everything the button does on the Container, but it wasn't saving the data when I closed the gui so I hope this is the way things are supposed to be. Now that was all working, I got my recipe serializer working for the block, but before I worked on the recipe i/o, I wanted to work on the other input which is for my exp book, and it takes the exp from the book and transfers it to the actual block. I have worked through the logic for this specific area and it seems good, however it doesn't actually save the updated exp amount to the block. I have stepped through with a debugger and I can see the exp being removed, and the block exp is increasing, but when I continue the program then the exp bar I have for the block hasn't increased and there isn't anything in the block afterall. Buttons work however. TLDR: Input slot for custom item gets it's exp amount removed and passed over to the exp block, exp block doesn't save the amount. Buttons work however, even though both the buttons and BookInput slot basically go through the same hoops. Code: ExperienceBlockTile: public class ExperienceBlockTile extends BaseTile implements INamedContainerProvider, ITickableTileEntity { public static final int INPUT_SLOTS = 1; public static final int INPUT_BOOK_SLOTS = 1; public static final int OUTPUT_SLOTS = 1; public static final int EXP_BAR_SLOT = 1; public static final int TOTAL_SLOTS = INPUT_SLOTS + OUTPUT_SLOTS; private ExperienceBlockContents inputContents; private ExperienceBlockContents inputBookContents; private ExperienceBlockContents outputContents; private ExperienceBlockContents expBarContents; private ItemStack currentlyInfusingItemLastTick = ItemStack.EMPTY; private ItemStack currentlyExtractionItemLastTick = ItemStack.EMPTY; public ExperienceBlock.Tier tier; public ExperienceBlockTile tile; private final ExperienceBlockStateData experienceBlockStateData; // Constructor that creates the experienceBlockTile and the input/output contents public ExperienceBlockTile(ExperienceBlock.Tier tier) { super(getTier(tier)); inputContents = ExperienceBlockContents.createForTileEntity(INPUT_SLOTS, this::canPlayerAccessInventory, this::markDirty); inputBookContents = ExperienceBlockContents.createForTileEntity(INPUT_BOOK_SLOTS, this::canPlayerAccessInventory, this::markDirty); outputContents = ExperienceBlockContents.createForTileEntity(OUTPUT_SLOTS, this::canPlayerAccessInventory, this::markDirty); expBarContents = ExperienceBlockContents.createForTileEntity(EXP_BAR_SLOT, this::canPlayerAccessInventory, this::markDirty); this.tier = tier; this.tile = (ExperienceBlockTile) getTileEntity(); this.experienceBlockStateData = new ExperienceBlockStateData(); } @Override public ITextComponent getDisplayName() { return new TranslationTextComponent("experience_block_container"); } @Nullable @Override public Container createMenu(int windowId, PlayerInventory playerIn, PlayerEntity playerEn) { return ExperienceBlockContainer.createContainerServerSide(windowId, playerIn, tile, inputContents, inputBookContents, outputContents, expBarContents, experienceBlockStateData); } // Basically just checks to see if the player is within range, true if they are public boolean canPlayerAccessInventory(PlayerEntity playerIn){ if(this.world.getTileEntity(this.pos) != this){ return false; } final double X_CENTRE_OFFSET = 0.5; final double Y_CENTRE_OFFSET = 0.5; final double Z_CENTRE_OFFSET = 0.5; final double MAXIMUM_DIST_SQ = 8.0 * 8.0; return playerIn.getDistanceSq(pos.getX() + X_CENTRE_OFFSET, pos.getY() + Y_CENTRE_OFFSET, pos.getZ() + Z_CENTRE_OFFSET) < MAXIMUM_DIST_SQ; } @Override public void tick() { // do nothing on client if(world.isRemote) return; ItemStack currentItemExpInfuse = getCurrentInfuseItemInput(); ItemStack currentExtractionItemInput = getCurrentExpExtractItemInput(); if(!currentExtractionItemInput.isEmpty()){ extractExpItem(); } currentlyExtractionItemLastTick = currentExtractionItemInput.copy(); markDirty(); } public static boolean doesItemHaveExpTag(ItemStack item){ return item.getOrCreateTag().contains("exp"); } private ItemStack getCurrentInfuseItemInput(){ return infuseFirstSuitableInputItem(false); } private void infuseFirstSuitableInputItem(){ infuseFirstSuitableInputItem(true); } private ItemStack infuseFirstSuitableInputItem(boolean performInfuse){ Integer inputSlot = null; Integer outputSlot = null; return ItemStack.EMPTY; } private ItemStack getCurrentExpExtractItemInput(){ return extractExpItem(false); } private void extractExpItem(){ extractExpItem(true); } private ItemStack extractExpItem(boolean performExtract){ ItemStack extractItem = inputBookContents.getStackInSlot(0); if(!performExtract){ return extractItem; } int extractRate = getExtractRate(); performExtraction(extractItem, extractRate); currentlyExtractionItemLastTick = extractItem; markDirty(); return extractItem; } private void performExtraction(ItemStack extractItem, int extractRate){ // Store the amount of exp currently in the book, and also the amount of exp that will be stored int expAmount = extractItem.getOrCreateTag().getInt("exp"); int expBlockAmount = getExpBlockAmount(); int expBlockMaxAmount = getMaxExpAmount(); int extractedExp; // Base case for the lower, and upper end if(expAmount == 0 || expBlockAmount == expBlockMaxAmount){ return; } // If the extract rate is higher than the amount of exp stored, then it'll go into the minus territory // If expAmount is less than the extractRate then the amount will be saved, otherwise just use the extractRate extractedExp = (expAmount < extractRate) ? expAmount : extractRate; // If the amount of exp being extracted goes over the cap in the exp block then bring it down if(expBlockAmount + extractedExp > expBlockMaxAmount){ extractedExp = expBlockMaxAmount - expBlockAmount; } expAmount -= extractedExp; extractItem.getTag().putInt("exp", expAmount); addExpAmount(extractedExp); } public boolean willItemStackFit(ExperienceBlockContents experienceBlockContents, int slotIndex, ItemStack itemStackOrigin){ ItemStack itemStackDest = experienceBlockContents.getStackInSlot(slotIndex); if(itemStackDest.isEmpty() || itemStackOrigin.isEmpty()){ return true; } if(!itemStackOrigin.isItemEqual(itemStackDest)){ return false; } return false; } private final String INPUT_SLOT_NBT = "inputSlot"; private final String INPUT_BOOK_SLOT_NBT = "inputBookSlot"; private final String OUTPUT_SLOT_NBT = "outputSlot"; private final String EXP_BAR_NBT = "expBar"; @Override public CompoundNBT write(CompoundNBT compound) { super.write(compound); experienceBlockStateData.putIntoNBT(compound); compound.put(INPUT_SLOT_NBT, inputContents.serializeNBT()); compound.put(INPUT_BOOK_SLOT_NBT, inputBookContents.serializeNBT()); compound.put(OUTPUT_SLOT_NBT, outputContents.serializeNBT()); compound.put(EXP_BAR_NBT, expBarContents.serializeNBT()); return compound; } @Override public void read(BlockState state, CompoundNBT nbt) { super.read(state, nbt); experienceBlockStateData.readFromNBT(nbt); CompoundNBT invNBT = nbt.getCompound(INPUT_SLOT_NBT); inputContents.deserializeNBT(invNBT); invNBT = nbt.getCompound(INPUT_BOOK_SLOT_NBT); inputBookContents.deserializeNBT(invNBT); invNBT = nbt.getCompound(OUTPUT_SLOT_NBT); outputContents.deserializeNBT(invNBT); invNBT = nbt.getCompound(EXP_BAR_NBT); expBarContents.deserializeNBT(invNBT); if(inputContents.getSizeInventory() != INPUT_SLOTS || inputBookContents.getSizeInventory() != INPUT_BOOK_SLOTS || outputContents.getSizeInventory() != OUTPUT_SLOTS || expBarContents.getSizeInventory() != EXP_BAR_SLOT){ throw new IllegalArgumentException("Corrupted NBT: Number of inventory slots did not match expected"); } } @Nullable @Override public SUpdateTileEntityPacket getUpdatePacket() { CompoundNBT updateTagTileEntityState = getUpdateTag(); final int METADATA = 42; return new SUpdateTileEntityPacket(this.pos, METADATA, updateTagTileEntityState); } @Override public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) { CompoundNBT updateTagTileEntityState = pkt.getNbtCompound(); BlockState state = world.getBlockState(pos); handleUpdateTag(state, updateTagTileEntityState); } @Override public CompoundNBT getUpdateTag() { CompoundNBT nbt = new CompoundNBT(); write(nbt); return nbt; } @Override public void handleUpdateTag(BlockState state, CompoundNBT tag) { read(state, tag); } public void dropContents(World world, BlockPos pos){ InventoryHelper.dropInventoryItems(world, pos, inputContents); InventoryHelper.dropInventoryItems(world, pos, inputBookContents); InventoryHelper.dropInventoryItems(world, pos, outputContents); } public static boolean isItemValidForInputSlot(ItemStack item){ return true; } public static boolean isItemValidForOutputSlot(ItemStack item){ return true; } public int getExpBlockAmount(){ return experienceBlockStateData.expAmountInContainer; } // Methods for the Exp Manipulation for adding and removing exp from the player to the ExpBlock // Add Exp to the Block public void addExpAmount(int value){ experienceBlockStateData.expAmountInContainer += value; markDirty(); } // Take Exp from the Block public void takeExpAmount(int value){ experienceBlockStateData.expAmountInContainer -= value; markDirty(); } public static TileEntityType<ExperienceBlockTile> getTier(ExperienceBlock.Tier tier){ switch (tier){ case SMALL: return ModTiles.EXPERIENCE_BLOCK_TILES.get(ExperienceBlock.Tier.SMALL).get(); case MEDIUM: return ModTiles.EXPERIENCE_BLOCK_TILES.get(ExperienceBlock.Tier.MEDIUM).get(); case LARGE: return ModTiles.EXPERIENCE_BLOCK_TILES.get(ExperienceBlock.Tier.LARGE).get(); case CREATIVE: return ModTiles.EXPERIENCE_BLOCK_TILES.get(ExperienceBlock.Tier.CREATIVE).get(); default: throw new IllegalArgumentException("Unknown tier: " + tier); } } public int getMaxExpAmount(){ return getMaxExpFromTier(tier); } public int getMaxExpFromTier(ExperienceBlock.Tier tier){ switch(tier){ case SMALL: return 1395; case MEDIUM: return 8670; case LARGE: return 30970; case CREATIVE: return Integer.MAX_VALUE; default: throw new IllegalArgumentException("Tier is not recognized: " + tier); } } private int getExtractRate(){ switch (this.tier){ case SMALL: return 10; case MEDIUM: return 15; case LARGE: return 20; case CREATIVE: return 100; default: throw new IllegalArgumentException("Unknown tier: " + tier); } } } ExperienceContainerBlock: public class ExperienceBlockContainer extends BaseContainer { // Vanilla Inventory Basic slot counts -- 9 Slots for hotbar, 3x9 for inventory private static final int HOTBAR_SLOT_COUNT = 9; private static final int PLAYER_INVENTORY_ROW_COUNT = 3; private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9; private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT; private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT; // Vanilla Inventory Indexes private static final int VANILLA_FIRST_SLOT_INDEX = 0; private static final int HOTBAR_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX; private static final int PLAYER_INVENTORY_FIRST_SLOT_INDEX = HOTBAR_FIRST_SLOT_INDEX + HOTBAR_SLOT_COUNT; // Experience Block Inventory slot counts public static final int INPUT_SLOTS = ExperienceBlockTile.INPUT_SLOTS; public static final int INPUT_BOOK_SLOTS = ExperienceBlockTile.INPUT_BOOK_SLOTS; public static final int OUTPUT_SLOTS = ExperienceBlockTile.OUTPUT_SLOTS; public static final int EXP_BAR_SLOT = ExperienceBlockTile.EXP_BAR_SLOT; // Experience Block Inventory Indexes private static final int INPUT_SLOT_INDEX = PLAYER_INVENTORY_FIRST_SLOT_INDEX + PLAYER_INVENTORY_SLOT_COUNT; private static final int INPUT_BOOK_SLOT_INDEX = INPUT_SLOT_INDEX + INPUT_BOOK_SLOTS; private static final int OUTPUT_SLOT_INDEX = INPUT_BOOK_SLOT_INDEX + OUTPUT_SLOTS; private static final int EXP_BAR_SLOT_INDEX = OUTPUT_SLOT_INDEX + EXP_BAR_SLOT; // Gui Pos of the player inventory grid public static final int PLAYER_INVENTORY_XPOS = 8; public static final int PLAYER_INVENTORY_YPOS = 84; private World world; private ExperienceBlockContents inputContents; private ExperienceBlockContents inputBookContents; private ExperienceBlockContents outputContents; private ExperienceBlockContents expBarContents; private ExperienceBlockStateData experienceBlockStateData; private ExperienceBlockTile experienceBlockTile; public ExperienceBlock.Tier tier; public ExperienceBlockContainer(int windowId, PlayerInventory playerIn){ super(ModContainers.EXPERIENCE_BLOCK_CONTAINER.get(), windowId); } public static ExperienceBlockContainer createContainerServerSide(int windowId, PlayerInventory playerInventory, ExperienceBlockTile tile, ExperienceBlockContents inputZoneContents, ExperienceBlockContents inputBookZoneContents, ExperienceBlockContents outputZoneContents, ExperienceBlockContents expBarZoneContents, ExperienceBlockStateData experienceBlockStateData) { return new ExperienceBlockContainer(windowId, playerInventory, tile, inputZoneContents, inputBookZoneContents, outputZoneContents, expBarZoneContents, experienceBlockStateData); } public static ExperienceBlockContainer createContainerClientSide(int windowId, PlayerInventory playerInventory, ExperienceBlockTile tile) { ExperienceBlockContents inputZoneContents = ExperienceBlockContents.createForClientSideContainer(INPUT_SLOTS); ExperienceBlockContents inputBookZoneContents = ExperienceBlockContents.createForClientSideContainer(INPUT_BOOK_SLOTS); ExperienceBlockContents outputZoneContents = ExperienceBlockContents.createForClientSideContainer(OUTPUT_SLOTS); ExperienceBlockContents expBarZoneContents = ExperienceBlockContents.createForClientSideContainer(EXP_BAR_SLOT); ExperienceBlockStateData experienceBlockStateData = new ExperienceBlockStateData(); return new ExperienceBlockContainer(windowId, playerInventory, tile, inputZoneContents, inputBookZoneContents, outputZoneContents, expBarZoneContents, experienceBlockStateData); } public ExperienceBlockContainer(int windowId, PlayerInventory playerIn, @Nullable ExperienceBlockTile tile, ExperienceBlockContents inputZoneContents, ExperienceBlockContents inputBookZoneContents, ExperienceBlockContents outputZoneContents, ExperienceBlockContents expBarZoneContents, ExperienceBlockStateData experienceBlockStateData) { super(ModContainers.EXPERIENCE_BLOCK_CONTAINER.get(), windowId); if (ModContainers.EXPERIENCE_BLOCK_CONTAINER.get() == null) { throw new IllegalStateException("Must Initialise ContainerType ExperienceBlockContainer before constructing a ExperienceBlockContainer!"); } this.inputContents = inputZoneContents; this.inputBookContents = inputBookZoneContents; this.outputContents = outputZoneContents; this.expBarContents = expBarZoneContents; this.experienceBlockStateData = experienceBlockStateData; this.tier = tile.tier; this.world = playerIn.player.world; this.experienceBlockTile = tile; trackIntArray(experienceBlockStateData); // The amount of pixels from the first pixel of one slot to the next slot final int SLOT_SPACING_X = 18; final int SLOT_SPACING_Y = 18; // Gui Pos of the player hotbar final int HOTBAR_XPOS = 8; final int HOTBAR_YPOS = 142; // Adding the player's hotbar to the gui - (x,y) loc of each item for (int x = 0; x < HOTBAR_SLOT_COUNT; x++) { addSlot(new Slot(playerIn, x, HOTBAR_XPOS + SLOT_SPACING_X * x, HOTBAR_YPOS)); } // Adding the rest of the player's inventory for (int y = 0; y < PLAYER_INVENTORY_ROW_COUNT; y++) { for (int x = 0; x < PLAYER_INVENTORY_COLUMN_COUNT; x++) { int slotNumber = HOTBAR_SLOT_COUNT + y * PLAYER_INVENTORY_COLUMN_COUNT + x; // Gets the location of the slot using the positions and slot spacing int xpos = PLAYER_INVENTORY_XPOS + x * SLOT_SPACING_X; int ypos = PLAYER_INVENTORY_YPOS + y * SLOT_SPACING_Y; addSlot(new Slot(playerIn, slotNumber, xpos, ypos)); } } // Input Slot final int INPUT_SLOT_XPOS = 44; final int INPUT_SLOT_YPOS = 15; // This looks stupid just for one slot but it gives the chance to upgrade in the future if I really want to for (int i = 0; i < INPUT_SLOTS; i++) { addSlot(new SlotInput(inputZoneContents, i, INPUT_SLOT_XPOS + SLOT_SPACING_X * i, INPUT_SLOT_YPOS)); } // Input Slot final int INPUT_BOOK_SLOT_XPOS = 77; final int INPUT_BOOK_SLOT_YPOS = 32; // This looks stupid just for one slot but it gives the chance to upgrade in the future if I really want to for (int i = 0; i < INPUT_SLOTS; i++) { addSlot(new SlotInputBook(inputBookZoneContents, i, INPUT_BOOK_SLOT_XPOS + SLOT_SPACING_X * i, INPUT_BOOK_SLOT_YPOS)); } // Output Slot final int OUTPUT_SLOT_XPOS = 44; final int OUTPUT_SLOT_YPOS = 50; for (int i = 0; i < OUTPUT_SLOTS; i++) { addSlot(new SlotOutput(outputZoneContents, i, OUTPUT_SLOT_XPOS + SLOT_SPACING_X * i, OUTPUT_SLOT_YPOS)); } // Exp Slot // final int EXP_SLOT_SPACING_X = 21; // final int EXP_SLOT_SPACING_Y = 72; // // final int EXP_SLOT_XPOS = 8; // final int EXP_SLOT_YPOS = 7; } public double fractionOfExpAmount(){ int expAmount = experienceBlockTile.getExpBlockAmount(); if(expAmount == 0) return 0; double fraction = (double) expAmount / experienceBlockTile.getMaxExpFromTier(tier);; return MathHelper.clamp(fraction, 0.0, 1.0); } @Override public boolean canInteractWith(PlayerEntity playerIn) { return inputContents.isUsableByPlayer(playerIn) && outputContents.isUsableByPlayer(playerIn); } @Override public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) { Slot sourceSlot = inventorySlots.get(index); if(sourceSlot == null || !sourceSlot.getHasStack()) return ItemStack.EMPTY; ItemStack sourceItemStack = sourceSlot.getStack(); ItemStack sourceStackBeforeMerge = sourceItemStack.copy(); boolean successfulTransfer = false; SlotZone sourceZone = SlotZone.getZoneFromIndex(index); switch (sourceZone){ case OUTPUT_ZONE: case INPUT_ZONE: case INPUT_BOOK_ZONE: successfulTransfer = mergeInto(SlotZone.PLAYER_MAIN_INVENTORY, sourceItemStack, false); if(!successfulTransfer){ successfulTransfer = mergeInto(SlotZone.PLAYER_HOTBAR, sourceItemStack, false); } break; case PLAYER_HOTBAR: case PLAYER_MAIN_INVENTORY: if(ExperienceBlockTile.doesItemHaveExpTag(sourceItemStack)){ successfulTransfer = mergeInto(SlotZone.INPUT_BOOK_ZONE, sourceItemStack, false); } if(!successfulTransfer){ if(sourceZone == SlotZone.PLAYER_HOTBAR){ successfulTransfer = mergeInto(SlotZone.PLAYER_MAIN_INVENTORY, sourceItemStack, false); } else { successfulTransfer = mergeInto(SlotZone.PLAYER_HOTBAR, sourceItemStack, false); } } break; default: throw new IllegalArgumentException("Unexpected sourceZone: " + sourceZone); } if(!successfulTransfer) return ItemStack.EMPTY; if(sourceItemStack.isEmpty()){ sourceSlot.putStack(ItemStack.EMPTY); } else { sourceSlot.onSlotChanged(); } if(sourceItemStack.getCount() == sourceStackBeforeMerge.getCount()){ return ItemStack.EMPTY; } sourceSlot.onTake(playerIn, sourceItemStack); return sourceStackBeforeMerge; } private boolean mergeInto(SlotZone dest, ItemStack sourceItemStack, boolean fillFromEnd){ return mergeItemStack(sourceItemStack, dest.firstIndex, dest.lastIndexPlus1, fillFromEnd); } private enum SlotZone{ INPUT_ZONE(INPUT_SLOT_INDEX, INPUT_SLOTS), INPUT_BOOK_ZONE(INPUT_BOOK_SLOT_INDEX, INPUT_BOOK_SLOTS), OUTPUT_ZONE(OUTPUT_SLOT_INDEX, OUTPUT_SLOTS), EXP_ZONE(EXP_BAR_SLOT_INDEX, EXP_BAR_SLOT), PLAYER_MAIN_INVENTORY(PLAYER_INVENTORY_FIRST_SLOT_INDEX, PLAYER_INVENTORY_SLOT_COUNT), PLAYER_HOTBAR(HOTBAR_FIRST_SLOT_INDEX, HOTBAR_SLOT_COUNT); public final int firstIndex; public final int slotCount; public final int lastIndexPlus1; SlotZone(int firstIndex, int numberOfSlots){ this.firstIndex = firstIndex; this.slotCount = numberOfSlots; this.lastIndexPlus1 = firstIndex + numberOfSlots; } public static SlotZone getZoneFromIndex(int slotIndex){ for(SlotZone slotZone : SlotZone.values()){ if(slotIndex >= slotZone.firstIndex && slotIndex < slotZone.lastIndexPlus1) return slotZone; } throw new IndexOutOfBoundsException("Unexpected slotIndex"); } } //region Buttons for ExperienceBlockScreen // Plus Buttons ADD experience to the blockM // ADDING a single level to the block at a time public void singlePlusOnButtonPress(PlayerEntity playerIn){ int expLevel = playerIn.experienceLevel; int expTotal = playerIn.experienceTotal; int expBlockAmount = experienceBlockTile.getExpBlockAmount(); int expMaxAmount = experienceBlockTile.getMaxExpFromTier(tier); // Check if we have reached our cap if(expBlockAmount == expMaxAmount){ return; } // The amount of exp to take away from the player int expToTake; // Check if the player is level 0, if they are then check if they have 6 or less exp to take the dregs, // else just take the exp normally if(expLevel == 0){ if(expTotal < 7){ expToTake = expTotal; } else{ return; } } else{ expToTake = ExperienceHelper.takeExpToPrevLevel(expLevel); } // Check if the amount coming in can fit well under the cap, if not // then lower the amount and continue if(expToTake + expBlockAmount > expMaxAmount){ expToTake = expMaxAmount - expBlockAmount; } playerIn.giveExperiencePoints(-expToTake); experienceBlockTile.addExpAmount(expToTake); } // ADDING all of the levels to the block public void doublePlusOnButtonPress(PlayerEntity playerIn){ int expLevel = playerIn.experienceLevel; int expTotal = playerIn.experienceTotal; int expBlockAmount = experienceBlockTile.getExpBlockAmount(); int maxExp = experienceBlockTile.getMaxExpFromTier(tier); // Check if we have reached our cap if(expBlockAmount == maxExp){ return; } // Check if player is level 0 and has less than 7 exp int expToTake; if(expLevel == 0){ if(expTotal < 7){ expToTake = expTotal; } else{ return; } } else{ expToTake = expTotal; } // Clean up the dregs in the player exp bar if(expToTake + expBlockAmount > maxExp){ expToTake = maxExp - expBlockAmount; } playerIn.giveExperiencePoints(-expToTake); experienceBlockTile.addExpAmount(expToTake); } // Minus Buttons TAKE AWAY experience from the block // TAKE AWAY a single level from the block public void singleMinusOnButtonPress(PlayerEntity playerIn){ int expLevel = playerIn.experienceLevel; int expTotal = playerIn.experienceTotal; int expBlockAmount = experienceBlockTile.getExpBlockAmount(); int maxExp = experienceBlockTile.getMaxExpFromTier(tier); if(expBlockAmount == 0){ return; } int expToTake; int amountNeededToNextLevel = ExperienceHelper.recieveExpToNextLevel(expLevel); // Clean up the dregs stored in the block if(amountNeededToNextLevel > expBlockAmount){ expToTake = expBlockAmount; } else { expToTake = amountNeededToNextLevel; } playerIn.giveExperiencePoints(expToTake); experienceBlockTile.takeExpAmount(expToTake); } // TAKING AWAY all of the levels in the block public void doubleMinusOnButtonPress(PlayerEntity playerIn){ int expLevel = playerIn.experienceLevel; int expTotal = playerIn.experienceTotal; int expBlockAmount = experienceBlockTile.getExpBlockAmount(); int maxExp = experienceBlockTile.getMaxExpFromTier(tier); if(expBlockAmount == 0){ return; } int expToTake = expBlockAmount; // Clean up the dregs stored in the block if(expToTake > expBlockAmount) { expToTake = expBlockAmount; } playerIn.giveExperiencePoints(expToTake); experienceBlockTile.takeExpAmount(expToTake); } //endregion public class SlotInput extends Slot { public SlotInput(IInventory inventoryIn, int index, int xPosition, int yPosition) { super(inventoryIn, index, xPosition, yPosition); } @Override public boolean isItemValid(ItemStack stack) { return ExperienceBlockTile.isItemValidForInputSlot(stack); } } public class SlotInputBook extends Slot { public SlotInputBook(IInventory inventoryIn, int index, int xPosition, int yPosition) { super(inventoryIn, index, xPosition, yPosition); } @Override public boolean isItemValid(ItemStack stack) { return ExperienceBlockTile.isItemValidForInputSlot(stack); } } public class SlotOutput extends Slot { public SlotOutput(IInventory inventoryIn, int index, int xPosition, int yPosition) { super(inventoryIn, index, xPosition, yPosition); } @Override public boolean isItemValid(ItemStack stack) { return ExperienceBlockTile.isItemValidForOutputSlot(stack); } } public class SlotExp extends Slot { public SlotExp(IInventory inventoryIn, int index, int xPosition, int yPosition) { super(inventoryIn, index, xPosition, yPosition); } } } And my github repo, under the correct branch: https://github.com/RhysGrabany/Experienced/tree/ticking_entity_exp_book Thank you in advance! Hopefully I didn't do/say anything too dumb.
  9. I've been coding for like four years and it seems like I still don't know what it means. I'm gonna research what it means now cause it's been too long 😅 I've took off the static property and commented out all the code that was complaining for the meantime. That has cleared up the problem about the error showing. Thank you for the help!!
  10. Sweet, made those changes now, thank you https://github.com/RhysGrabany/Experienced Here you go, the changes I've made rn are under the tile_passing branch
  11. So I should delete the DeferredRegisters in the Registration class and just keep them separate in their respective classes? So ModItems gets the DeferrefRegister and so on? I did notice that when I changed in ModTiles from the DeferredRegister in Registration to the specific class DefReg it actually registered, so that explains something to me. This is my ExperienceBlockTile constructor and the getTier method that returns the Tile: public ExperienceBlockTile(ExperienceBlock.Tier tier) { super(getTier(tier)); inputContents = ExperienceBlockContents.createForTileEntity(INPUT_SLOTS, this::canPlayerAccessInventory, this::markDirty); outputContents = ExperienceBlockContents.createForTileEntity(OUTPUT_SLOTS, this::canPlayerAccessInventory, this::markDirty); expBarContents = ExperienceBlockContents.createForTileEntity(EXP_BAR_SLOT, this::canPlayerAccessInventory, this::markDirty); } public static TileEntityType<ExperienceBlockTile> getTier(ExperienceBlock.Tier tier){ switch (tier){ case SMALL: return ModTiles.EXPERIENCE_BLOCK_SMALL.get(); case MEDIUM: return ModTiles.EXPERIENCE_BLOCK_MEDIUM.get(); case LARGE: return ModTiles.EXPERIENCE_BLOCK_LARGE.get(); case CREATIVE: return ModTiles.EXPERIENCE_BLOCK_CREATIVE.get(); default: throw new IllegalArgumentException("Unkown tier: " + tier); } }
  12. I have a block that has four different tiers (SMALL, MEDIUM, LARGE, CREATIVE), I had everything working but then I wanted to send the tier of block down the pipeline to the container where it can be used, so I'm sending the tile down. The Tile accepts the Tier as a value to pass to its constructor, but for some reason I get an error in the console when I place any of this block that is not the CreativeTier. So if I place a Small/Medium/Large block then I get this error: I've searched on here and I get not much to go on. And when I step through with the debugger, all the Tiles seem to be registered just like my Items and Blocks. Code here: My Registration Class: public class Registration { public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, Constants.MOD_ID); public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, Constants.MOD_ID); public static final DeferredRegister<IRecipeSerializer<?>> RECIPES = DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, Constants.MOD_ID); public static final DeferredRegister<TileEntityType<?>> TILES = DeferredRegister.create(ForgeRegistries.TILE_ENTITIES, Constants.MOD_ID); public static final DeferredRegister<ContainerType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, Constants.MOD_ID); public static void register(){ IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); // The deferred registries BLOCKS.register(modEventBus); ITEMS.register(modEventBus); RECIPES.register(modEventBus); TILES.register(modEventBus); CONTAINERS.register(modEventBus); // Registry objects are registered ModItems.register(); ModBlocks.register(); ModRecipes.register(); ModTiles.register(); ModContainers.register(); } } My ModTiles code: @Mod.EventBusSubscriber(modid = Constants.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) public class ModTiles { public static final DeferredRegister<TileEntityType<?>> TILES = DeferredRegister.create(ForgeRegistries.TILE_ENTITIES, Constants.MOD_ID); public static final RegistryObject<TileEntityType<ExperienceBlockTile>> EXPERIENCE_BLOCK_SMALL; public static final RegistryObject<TileEntityType<ExperienceBlockTile>> EXPERIENCE_BLOCK_MEDIUM; public static final RegistryObject<TileEntityType<ExperienceBlockTile>> EXPERIENCE_BLOCK_LARGE; public static final RegistryObject<TileEntityType<ExperienceBlockTile>> EXPERIENCE_BLOCK_CREATIVE; static { EXPERIENCE_BLOCK_SMALL = TILES.register("experience_block_small", ()-> TileEntityType.Builder.create( ()-> new ExperienceBlockTile(ExperienceBlock.Tier.SMALL), ModBlocks.EXPERIENCE_BLOCKS.get(ExperienceBlock.Tier.SMALL).get() ).build(null)); EXPERIENCE_BLOCK_MEDIUM = TILES.register("experience_block_medium", ()-> TileEntityType.Builder.create( ()-> new ExperienceBlockTile(ExperienceBlock.Tier.MEDIUM), ModBlocks.EXPERIENCE_BLOCKS.get(ExperienceBlock.Tier.MEDIUM).get() ).build(null)); EXPERIENCE_BLOCK_LARGE = TILES.register("experience_block_large", ()-> TileEntityType.Builder.create( ()-> new ExperienceBlockTile(ExperienceBlock.Tier.LARGE), ModBlocks.EXPERIENCE_BLOCKS.get(ExperienceBlock.Tier.LARGE).get() ).build(null)); EXPERIENCE_BLOCK_CREATIVE = TILES.register("experience_block_creative", ()-> TileEntityType.Builder.create( ()-> new ExperienceBlockTile(ExperienceBlock.Tier.CREATIVE), ModBlocks.EXPERIENCE_BLOCKS.get(ExperienceBlock.Tier.CREATIVE).get() ).build(null)); } public static void register() { TILES.register(FMLJavaModLoadingContext.get().getModEventBus()); } } My ExperienceBlock Class just in case: public class ExperienceBlock extends Block { // The tiers of the experience block, this makes it easy to register the blocks and all that sort of stuff public static Tier BLOCK_TIER; public enum Tier { SMALL("small"), MEDIUM("medium"), LARGE("large"), CREATIVE("creative"); final String name; Tier(String name){ this.name = name; } public String getName(){ return name; } } public ExperienceBlock(Tier tier) { super(AbstractBlock .Properties .create(Material.ROCK) .harvestLevel(2)); BLOCK_TIER = tier; } //region Gui Functions //region Tile Entity @Override public boolean hasTileEntity(BlockState state) { return true; } @Nullable @Override public TileEntity createTileEntity(BlockState state, IBlockReader world) { return new ExperienceBlockTile(BLOCK_TIER); } //endregion @Nullable @Override public INamedContainerProvider getContainer(BlockState state, World worldIn, BlockPos pos) { TileEntity tile = worldIn.getTileEntity(pos); return tile instanceof INamedContainerProvider ? (INamedContainerProvider) tile : null; } //endregion @Override public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { if(worldIn.isRemote){ return ActionResultType.SUCCESS; } // If the selected block has no container then one will be made for it INamedContainerProvider nmContainer = this.getContainer(state, worldIn, pos); if(nmContainer != null){ TileEntity tile = worldIn.getTileEntity(pos); NetworkHooks.openGui((ServerPlayerEntity) player, nmContainer, (packetBuffer -> {})); } return ActionResultType.SUCCESS; } @Override public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { if(state.getBlock() != newState.getBlock()){ TileEntity tile = worldIn.getTileEntity(pos); if(tile instanceof ExperienceBlockTile){ ExperienceBlockTile tileEntity = (ExperienceBlockTile) tile; tileEntity.dropContents(worldIn, pos); } super.onReplaced(state, worldIn, pos, newState, isMoving); } } //region Helper Methods for Block // Method used to initialize the max amount of exp a certain block can hold // For now; Small = 30, Medium = 60, Large = 100, Creative = MAX_VALUE, and default is 0 cause that might not happen public static int getMaxExpFromTier(Tier tier){ switch(tier){ case SMALL: return 1395; case MEDIUM: return 8670; case LARGE: return 30970; case CREATIVE: return Integer.MAX_VALUE; default: return 0; } } //endregion } I also don't like how the registry objects are so verbose in my code tbh. I have the blocks in an EnumMap and just foreach through them all and that seems to work. Please help me here cause I've been stuck on this for a while.
  13. I was thinking, have the Recipe type and put the recipe for the item as (Item Input) -> (Item Output), and put the timeTaken as some arbitrary number like 0/60. Then when I actually put the item in, it checks if it has the NBT tag and then give it a custom timeTaken based on how full it is. That way a half full item won't take as long as a completely full item. And if the item doesnt have the tag, then it will check if there is a recipe that uses it and it will have the correct timeTaken. I don't know if this is the best way tbh, this is just me thinking based on what I know so far. If anybody has a better way then I'd love to hear it. Thank you.
  14. I have a few questions about recipes, or my options for what I want, and I want to ask them before I start implementing code. I have a block that holds experience, and there is an input and output. Currently I just have a book that holds experience as an NBT tag. But in the future I want to fill a bottle with experience for other uses. Right now I look to see if the tag is present and then take the exp from it, but this doesn't work for what I want in the future. Should I make a Recipe type for this block -- but my question here is how can I use the nbt data of the item and output the item with no tag? Sorry if I don't make much sense here. Basically I have an item with nbt data that is drawn out of the item and into the block, but I want to "future-proof" it so I don't have any problems in next time.
  15. That's me being stupid and not thinking stuff through. That actually fixed it tho, so thank you very much. Updated code in case someone in the future needs it: public class SingleMinusButton extends Button { private static final ResourceLocation BACKGROUND_TEXTURE = new ResourceLocation(Constants.MOD_ID, "textures/gui/experience_block_gui.png"); public SingleMinusButton(int x, int y, ITextComponent title, IPressable pressedAction) { super(x, y, 11, 11, title, pressedAction); } @Override public void renderButton(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { //Coords to base button final int SINGLE_MINUS_BUTTON_BASE_U = 216; final int SINGLE_MINUS_BUTTON_BASE_V = 68; // Coords to the texture of hovered button texture final int SINGLE_MINUS_BUTTON_HOV_U = 216; final int SINGLE_MINUS_BUTTON_HOV_V = 17; // Coords to the texture of the selected button texture final int SINGLE_MINUS_BUTTON_SEL_U = 216; final int SINGLE_MINUS_BUTTON_SEL_V = 42; Minecraft minecraft = Minecraft.getInstance(); minecraft.getTextureManager().bindTexture(BACKGROUND_TEXTURE); RenderSystem.color4f(1.0f, 1.0f,1.0f,1.0f); this.blit(matrixStack, x, y, SINGLE_MINUS_BUTTON_BASE_U, SINGLE_MINUS_BUTTON_BASE_V, width, height); } private static boolean inBounds(int x, int y, int xSize, int ySize, double mouseX, double mouseY) { return ((mouseX >= x && mouseX <= x + xSize) && (mouseY >= y && mouseY <= y + ySize)); } } Is there anything else I'm being stupid on btw? Might help me next time
  16. Hello, I am having a problem with creating a button for my gui. The button actually does get created and gets added to the screen, the problem is that it has no texture. I have double-triple checked the coords of the texture from my file, and I've looked at other modders code and I'm not seeing what they have done that I haven't relating to this issue. The BlockScreen code: public class ExperienceBlockScreen extends ContainerScreen<BaseContainer> { private static final ResourceLocation BACKGROUND_TEXTURE = new ResourceLocation(Constants.MOD_ID, "textures/gui/experience_block_gui.png"); // Coords for the graphical elements of the gui // Arrow Coords // B/G final static int ARROW_BAR_XPOS = 199; final static int ARROW_BAR_YPOS = 4; // Exp Bar Coords // B/G final static int EXP_BAR_XPOS = 8; final static int EXP_BAR_YPOS = 78; // Width and Height final static int EXP_BAR_SPACING_X = 21; final static int EXP_BAR_SPACING_Y = 72; // F/G final static int EXP_BAR_TEX_U = 177; final static int EXP_BAR_TEX_V = 75; // Buttons // Single Plus final static int SINGLE_PLUS_BUTTON_XPOS = 115; final static int SINGLE_PLUS_BUTTON_YPOS = 28; // Double Plus final static int DOUBLE_PLUS_BUTTON_XPOS = 129; final static int DOUBLE_PLUS_BUTTON_YPOS = 28; // Single Minus final static int SINGLE_MINUS_BUTTON_XPOS = 115; final static int SINGLE_MINUS_BUTTON_YPOS = 40; // Double Minus final static int DOUBLE_MINUS_BUTTON_XPOS = 129; final static int DOUBLE_MINUS_BUTTON_YPOS = 41; // Button Spacings final static int SINGLE_SPACING_X = 11; final static int SINGLE_SPACING_Y = 11; final static int DOUBLE_SPACING_X = 17; final static int DOUBLE_SPACING_Y = 9; public ExperienceBlockScreen(BaseContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) { super(screenContainer, inv, titleIn); xSize = 176; ySize = 166; } // @Override // protected void init() { // // super.init(); // // //this.buttons.clear(); // // } @Override public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { this.renderBackground(matrixStack); super.render(matrixStack, mouseX, mouseY, partialTicks); this.renderHoveredTooltip(matrixStack, mouseX, mouseY); } @Override protected void drawGuiContainerForegroundLayer(MatrixStack matrixStack, int x, int y) { // final float LABEL_XPOS = 5; // final float FONT_Y_SPACING = 12; // final float EXP_BLOCK_LABEL_YPOS = ExperienceBlockContainer.TILE_INV_YPOS - FONT_Y_SPACING; // this.font.func_243248_b(matrixStack, this.title, LABEL_XPOS, EXP_BLOCK_LABEL_YPOS, Color.darkGray.getRGB()); // // final float PLAYER_INV_LABEL_YPOS = ExperienceBlockContainer.PLAYER_INV_YPOS - FONT_Y_SPACING; // this.font.func_243248_b(matrixStack, this.playerInventory.getDisplayName(), LABEL_XPOS, PLAYER_INV_LABEL_YPOS, Color.darkGray.getRGB()); } @Override protected void drawGuiContainerBackgroundLayer(MatrixStack matrixStack, float partialTicks, int x, int y) { this.minecraft.getTextureManager().bindTexture(BACKGROUND_TEXTURE); RenderSystem.color4f(1.0f, 1.0f,1.0f,1.0f); int edgeSpacingX = (this.width - this.xSize)/2; int edgeSpacingY = (this.height - this.ySize)/2; // Drawing the main gui element this.blit(matrixStack, edgeSpacingX, edgeSpacingY, 0, 0, this.xSize, this.ySize); // Drawing the button for single minus // (x,y) this can be the (0,0) of the gui element, then the offsets to get the texture, then the width and height // this.blit(matrixStack, edgeSpacingX + SINGLE_MINUS_BUTTON_XPOS, edgeSpacingY + SINGLE_MINUS_BUTTON_YPOS, // SINGLE_MINUS_BUTTON_XPOS, SINGLE_MINUS_BUTTON_YPOS, // SINGLE_SPACING_X, SINGLE_SPACING_Y); this.addButton(new SingleMinusButton(guiLeft + SINGLE_MINUS_BUTTON_XPOS, guiTop + SINGLE_MINUS_BUTTON_YPOS, new TranslationTextComponent(""), (press)->{})); // Drawing the ExpBar this.blit(matrixStack, edgeSpacingX + EXP_BAR_XPOS, edgeSpacingY + EXP_BAR_YPOS - 17, EXP_BAR_TEX_U, EXP_BAR_TEX_V - 17, EXP_BAR_SPACING_X, EXP_BAR_SPACING_Y); } } And the SingleMinusButton code: public class SingleMinusButton extends Button { private static final ResourceLocation BACKGROUND_TEXTURE = new ResourceLocation(Constants.MOD_ID, "textures/gui/experience_block_gui.png"); private int xSize; private int ySize; public SingleMinusButton(int x, int y, ITextComponent title, IPressable pressedAction) { super(x, y, 11, 11, title, pressedAction); xSize = 176; ySize = 166; } @Override public void renderButton(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { int textureX = (this.width - xSize) / 2; int textureY = (this.height - ySize) / 2; // Where the button should be on the gui final int SINGLE_MINUS_BUTTON_XPOS = 115; final int SINGLE_MINUS_BUTTON_YPOS = 40; //Coords to base button final int SINGLE_MINUS_BUTTON_BASE_U = 216; final int SINGLE_MINUS_BUTTON_BASE_V = 68; // Coords to the texture of hovered button texture final int SINGLE_MINUS_BUTTON_HOV_U = 216; final int SINGLE_MINUS_BUTTON_HOV_V = 17; // Coords to the texture of the selected button texture final int SINGLE_MINUS_BUTTON_SEL_U = 216; final int SINGLE_MINUS_BUTTON_SEL_V = 42; Minecraft minecraft = Minecraft.getInstance(); minecraft.getTextureManager().bindTexture(BACKGROUND_TEXTURE); RenderSystem.color4f(1.0f, 1.0f,1.0f,1.0f); this.blit(matrixStack, textureX + SINGLE_MINUS_BUTTON_XPOS, textureY + SINGLE_MINUS_BUTTON_YPOS, SINGLE_MINUS_BUTTON_BASE_U, SINGLE_MINUS_BUTTON_BASE_V, width, height); } private static boolean inBounds(int x, int y, int xSize, int ySize, double mouseX, double mouseY) { return ((mouseX >= x && mouseX <= x + xSize) && (mouseY >= y && mouseY <= y + ySize)); } } If there's a call to a method that I'm missing, then the help would be wonderful. The issue I think is with the actual texture file if the button is being created, but it works for the main gui so I don't understand. Thank you for the help in advance.
  17. Oh wow, that worked. Thank you very much I have another issue with the durability bar, but I'll work on that for a while before asking the forum. Thanks again!
  18. Hello, I am trying to create an item that holds experience, later it will be blocks but little steps, and when I move the experience from the Player into the book, the exp bar doesn't update. Right now I have this: playerIn.experienceTotal -= expToStore; And the next time I use the Experience Book it does say that I don't have any experience left, just that the bar doesn't update. I've tried looking at the Enchanting Table Block/Tile Entity/Container, and from what I've seen they mark the inventory dirty when using the player experience, so I added this: playerIn.inventory.markDirty(); This hasn't fixed my problem, so I must be missing something. Full code for onItemRightClick here: public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { ItemStack stack = playerIn.getHeldItem(Hand.MAIN_HAND).getStack(); currentStoredExp = stack.getOrCreateTag().getInt("exp"); int expLevel = ExperienceHelper.playerTotalExp(playerIn); int expTotal = playerIn.experienceTotal; if (expTotal <= 0 || currentStoredExp == MAX_EXP) { return new ActionResult<>(ActionResultType.PASS, stack); } if ((!playerIn.isSneaking()) && handIn == Hand.MAIN_HAND && currentStoredExp < MAX_EXP) { int expToStore = (expLevel < (MAX_EXP - currentStoredExp)) ? expLevel : (MAX_EXP - currentStoredExp); //TODO: not the way to remove exp from the player app playerIn.experienceTotal -= expToStore; expToStore += currentStoredExp; stack.getTag().putInt("exp", expToStore); playerIn.inventory.markDirty(); return new ActionResult<>(ActionResultType.SUCCESS, stack); } return new ActionResult<>(ActionResultType.PASS, stack); } If I have missed anything, please let me know. Thank you!
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.