Jump to content

Simon_kungen

Members
  • Posts

    151
  • Joined

  • Last visited

Everything posted by Simon_kungen

  1. Hi I'm not talking about a crafting handler for example a machine, a crafting handler for the vanilla crafting system (should work for modded crafting tables that uses Mojang's crafting handler). And using Json formatting will not work as my idea will be working with NBT of items. And if I would use Json with a unique item for each operation I would end up with at the minimum 2432902008176640000 different items and recipes, not ideal. Let's say I want a handler (as an example) for when I place a Shulker Box together with any ItemStack in the crafting window: The resulting Shulker Box will be the ItemStack in the Shulker Box without having to place it down and putting it manually. It will take the whole stack at once and a total of eight other other items could be done at once. If it doesn't fit, or partly fits it will not take the ItemStack from the Crafting Window or will put in as much as possible and subtract that from the remaining ItemStack. That was just an example of what I want to do as Shulker Boxes can be crafted with dyes which would break that system, but hopefully the idea got through.
  2. Umm, how does your recipe look like? Is there a reason it needs to be mirror selective? In real life most things doesn't care whenever its mirrored or not, only the weak force care as far as we've discovered.
  3. I could really need some help with this, it just doesn't make sense to me.
  4. My initial thought was to look at how the End Portal was rendered because it is invisible from the bottom, but that only confused me more. In EndPortalTileEntityRenderer.java it has a bunch of if statements for the different directions which is compared to a final variable in EndPortalTileEntity.java for Direction.UP: EndPortalTileEntity.java ... @OnlyIn(Dist.CLIENT) public boolean shouldRenderFace(Direction face) { return face == Direction.UP; } EndPortalTileEntityRenderer.java ... if (tileEntityIn.shouldRenderFace(Direction.SOUTH)) { bufferbuilder.pos(x, y, z + 1.0D).color(f3, f4, f5, 1.0F).endVertex(); bufferbuilder.pos(x + 1.0D, y, z + 1.0D).color(f3, f4, f5, 1.0F).endVertex(); bufferbuilder.pos(x + 1.0D, y + 1.0D, z + 1.0D).color(f3, f4, f5, 1.0F).endVertex(); bufferbuilder.pos(x, y + 1.0D, z + 1.0D).color(f3, f4, f5, 1.0F).endVertex(); } if (tileEntityIn.shouldRenderFace(Direction.NORTH)) { bufferbuilder.pos(x, y + 1.0D, z).color(f3, f4, f5, 1.0F).endVertex(); bufferbuilder.pos(x + 1.0D, y + 1.0D, z).color(f3, f4, f5, 1.0F).endVertex(); bufferbuilder.pos(x + 1.0D, y, z).color(f3, f4, f5, 1.0F).endVertex(); bufferbuilder.pos(x, y, z).color(f3, f4, f5, 1.0F).endVertex(); } ... When doing the same it just stops it from rendering altogether for that plate, so I have no idea what's going on here. The only difference is that I use a numerical value contrary to an object in a switch statement: CableCaseTileEntityRenderer.java private void renderPlate(T te, byte plate, String texture, BufferBuilder buffer) { TextureAtlasSprite sprite = Minecraft.getInstance().getTextureMap().getAtlasSprite(texture); float u1 = sprite.getMinU(), v1 = sprite.getMinV(), u2 = sprite.getMaxU(), v2 = sprite.getMaxV(); final float[] c = te.getPlate(plate) instanceof ItemElement ? UtilBlocks.toFractal(Util.hex2rgb(((ItemElement) te.getPlate(plate)).getTint()),255) : new float[] {1,1,1}; int combined, lma, lmb; switch (plate) { case 3: // South combined = getWorld().getCombinedLight(te.getPos().south(),0); lma = combined >> 16 & 65535; lmb = combined & 65535; buffer.pos(min,min,maxZ).color(c[0],c[1],c[2],ALPHA).tex(u2,v1).lightmap(lma,lmb).endVertex(); buffer.pos(min,max,maxZ).color(c[0],c[1],c[2],ALPHA).tex(u2,v2).lightmap(lma,lmb).endVertex(); buffer.pos(max,max,maxZ).color(c[0],c[1],c[2],ALPHA).tex(u1,v2).lightmap(lma,lmb).endVertex(); buffer.pos(max,min,maxZ).color(c[0],c[1],c[2],ALPHA).tex(u1,v1).lightmap(lma,lmb).endVertex(); break; case 0: // West combined = getWorld().getCombinedLight(te.getPos().west(),0); lma = combined >> 16 & 65535; lmb = combined & 65535; buffer.pos(minZ,min,min).color(c[0],c[1],c[2],ALPHA).tex(u2,v1).lightmap(lma,lmb).endVertex(); buffer.pos(minZ,max,min).color(c[0],c[1],c[2],ALPHA).tex(u2,v2).lightmap(lma,lmb).endVertex(); buffer.pos(minZ,max,max).color(c[0],c[1],c[2],ALPHA).tex(u1,v2).lightmap(lma,lmb).endVertex(); buffer.pos(minZ,min,max).color(c[0],c[1],c[2],ALPHA).tex(u1,v1).lightmap(lma,lmb).endVertex(); ...
  5. Hi As seen from this video the applied texture (coloured walls) is on both sides, I don't want that. How would I go about making so the texture is only on the outer side? My idea was to give the "plates" depth by adding a second plate on the inside too but reversed, so I only need to texture two of the four sides of a plate (make it slightly more efficient). Later I also plan on making the plates transparent at times such as when holding a tool, and if I have all sides textured it would end up looking wonky with double layers both being transparent. Current code (for rendering South plate): TextureAtlasSprite sprite = Minecraft.getInstance().getTextureMap().getAtlasSprite(texture); float u1 = sprite.getMinU(), v1 = sprite.getMinV(), u2 = sprite.getMaxU(), v2 = sprite.getMaxV(); combined = getWorld().getCombinedLight(te.getPos().south(),0); lma = combined >> 16 & 65535; lmb = combined & 65535; buffer.pos(min,min,maxZ).color(c[0],c[1],c[2],ALPHA).tex(u2,v1).lightmap(lma,lmb).endVertex(); buffer.pos(min,max,maxZ).color(c[0],c[1],c[2],ALPHA).tex(u2,v2).lightmap(lma,lmb).endVertex(); buffer.pos(max,max,maxZ).color(c[0],c[1],c[2],ALPHA).tex(u1,v2).lightmap(lma,lmb).endVertex(); buffer.pos(max,min,maxZ).color(c[0],c[1],c[2],ALPHA).tex(u1,v1).lightmap(lma,lmb).endVertex();
  6. Hmm, alright. My plan is for other mods to use their crowbar for my blocks. Railcraft is a good example who adds a crowbar, hopefully, it's in the right place from the get-go.
  7. Hi Tags are great, but I can't find a proper tag list for common modded tag names. Example: I have my own wrench and crowbars and I have my blocks use the tag where my tools are listed, but until now I have just guessed what other modders are most likely going to use: forge/tags/items/crowbars.json { "replace": false, "values": [ "intercraftcore:white_crowbar", "intercraftcore:orange_crowbar", "intercraftcore:magenta_crowbar", "intercraftcore:light_blue_crowbar", "intercraftcore:yellow_crowbar", "intercraftcore:lime_crowbar", "intercraftcore:pink_crowbar", "intercraftcore:gray_crowbar", "intercraftcore:light_gray_crowbar", "intercraftcore:cyan_crowbar", "intercraftcore:purple_crowbar", "intercraftcore:blue_crowbar", "intercraftcore:brown_crowbar", "intercraftcore:green_crowbar", "intercraftcore:red_crowbar", "intercraftcore:black_crowbar" ] } forge/tags/items/wrenches.json { "replace": false, "values": [ "intercraftcore:wrench" ] } Is there a webpage for common tag names? Modded tools like crowbars and wrenches are not part of vanilla and therefore is not on Forge's Github like forge/tags/items/ingots/iron tag or expected modded ingots like forge/tags/items/ingots/copper tag.
  8. So there is no way of doing it without a TileEntity?
  9. Hi What I want is not a TileEntitySpecialRender, but a renderer for my block. A TileEntity is overkill and would only result in unnecessary lag as it will be used as a building block, a special render on the client for my block would suffice. My question is how I would go about that in 1.14, from creating a rendering class and attaching it to the client to tell it to render this on my block. This cannot be done with JSON files as far as I can tell. This render needs to be dynamic with animations and such, a lighting bolt coming off of it from time to time for example.
  10. Umm, looks like you've done exactly as I did. Can you only attach it when you register an item and initializes it in the same line? LARGE_GLASS_JAR = new ItemSingleStackGlassContainer(new Item.Properties().setTEISR(() -> () -> SingleStackGlassContainerItemRender.INSTANCE),"large_glass_jar",0.01f); I register my items by creating a static variable and then add that variable to a list that registers all the entries when filled.
  11. Alright, added this: @Nullable @Override public CompoundNBT getShareTag(ItemStack stack) { IItemHandler handler = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElseThrow(NullPointerException::new); CompoundNBT nbt = new CompoundNBT(); nbt.putInt("Slot",0); handler.getStackInSlot(0).write(nbt); return nbt; } @Override public void readShareTag(ItemStack stack, @Nullable CompoundNBT nbt) { ItemStack readStack = ItemStack.read(nbt); IItemHandler handler = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElseThrow(NullPointerException::new); ((IItemHandlerModifiable) handler).setStackInSlot(0,readStack); } Not sure if I should go after a certain standard or if the NBT can be made however I want, but the problem is that none of these fire. The debugger does not break when marking both of them to suspend.
  12. So yeah... looks like none of my questions has been answered lately. Should I give up on capabilities for now?
  13. Hi My item has ItemHandler capability, which works fine. But one of the things I have when storing a item on the capability is overring the translation key with the contained stack's translation key. The problem is that this will only sync when opening the item again. I need to send a message to the client with the new contained stack which I do not know how to do. I don't know which ItemStack I need to change on the client when the container is closed. My item needs to have two capabilities attached to it. One is the Forge ItemHandler Capability while the other that is exclusive to the glass variant should be able to store a liquid too. For this, I made a provider that includes these capabilities: public class StackFluidContainerProvider implements ICapabilitySerializable { private final FluidContainer fluid; private final ItemStackHandler inventory; private final LazyOptional<IItemHandler> itemHandler = LazyOptional.of(this::getInventory); private final LazyOptional<IFluidContainer> fluidHandler = LazyOptional.of(this::getFluid); public StackFluidContainerProvider(short slots, short maxVolume) { inventory = new ItemStackHandler(slots); fluid = new FluidContainer(maxVolume); } protected FluidContainer getFluid() { return fluid; } protected ItemStackHandler getInventory() { return inventory; } @SuppressWarnings("ConstantConditions") @Override public INBT serializeNBT() { CompoundNBT compoundNBT = new CompoundNBT(); compoundNBT.put("items", CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.getStorage().writeNBT(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY,getInventory(),null)); compoundNBT.put("fluid", FluidContainerStorage.FLUID_CONTAINER_CAPABILITY.getStorage().writeNBT(FluidContainerStorage.FLUID_CONTAINER_CAPABILITY,getFluid(),null)); return compoundNBT; } @Override public void deserializeNBT(INBT nbt) { if (nbt instanceof CompoundNBT) { CompoundNBT compoundNBT = (CompoundNBT)nbt; CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.getStorage().readNBT(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, getInventory(), null, compoundNBT.get("items")); FluidContainerStorage.FLUID_CONTAINER_CAPABILITY.getStorage().readNBT(FluidContainerStorage.FLUID_CONTAINER_CAPABILITY, getFluid(), null, compoundNBT.get("fluid")); } } @SuppressWarnings("unchecked") public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, Direction side) { if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return itemHandler.cast(); else if (cap == FluidContainerStorage.FLUID_CONTAINER_CAPABILITY) return fluidHandler.cast(); return (LazyOptional<T>) LazyOptional.empty(); } } But when I try and fetch the capability the parameter cap seems to always be null, which means it always returns the first statement (in this case the ItemHandler) which results in a casting error.
  14. Other mods I can find add their TEISR directly in the item constructor (which crashes the server). But doing the same I at least expect it to do something while in Single Player.
  15. Hmm... nothing seems to be happening here. Is there some vanilla items that use TEISR I can look at? I can't find any which implies TEISR is a Forge addition to the game and not native to vanilla Minecraft.
  16. Looking at the doc it mentions it will not validate the new renderer if it does not have IBakedModel#isBuiltInRenderer set to true. In order to use a TEISR, the Item must first satisfy the condition that its model returns true for IBakedModel#isBuiltInRenderer. Once that returns true, the Item’s TEISR will be accessed for rendering. If it does not have one, it will use the default TileEntityItemStackRenderer.instance. Which is most likely why it does not fire. The problem now is that I have no idea how to enable that. I can create a new class implementing IBakedModel but then I do not know how to have it applied on my item, and when to apply it to avoid server crash.
  17. Hi I got this item that stores a single stack of something else, and a glass variant of it should render the stack inside, but according to the docs I just need to set the renderer on the item and it should work but as far as I can see nothing happens, not even the console prints anything: ItemSingleStackGlassContainer.java public class ItemSingleStackGlassContainer extends ItemSingleStackContainer { public ItemSingleStackGlassContainer(String name, float isolation, int tint) { super(new Item.Properties().setTEISR(() -> SingleStackGlassContainerItemRender::new),name,isolation,tint); } ... } The superclass: ItemSingleStackContainer.java public class ItemSingleStackContainer extends Item { public static final ResourceLocation open = new ResourceLocation(Reference.MODID,"open"); private final float isolation; private final int tint; private static short failedToOpen = 0; private boolean isOpen = false; public ItemSingleStackContainer(Item.Properties properties,String name, float isolation, int tint) { super(properties.maxStackSize(1).group(ItemGroup.TOOLS)); if (isolation < 0 || isolation > 1) throw new IllegalArgumentException("Can only be between 0 and 1!"); addPropertyOverride(open,(itemStack, worldIn, entityLivingBase) -> isOpen ? 1 : 0); this.isolation = isolation; this.tint = tint; setRegistryName(name); } public static ItemStack getContainedItemStack(ItemStack stack) { IItemHandler handler = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElseThrow(NullPointerException::new); return handler.getStackInSlot(0); } ... } The renderer that should just render the stack somewhere visible on the camera for now and print out to the console: SingleStackGlassContainerItemRender.java @OnlyIn(Dist.CLIENT) public class SingleStackGlassContainerItemRender extends ItemStackTileEntityRenderer { @Override public void renderByItem(ItemStack itemStackIn) { System.out.println("Rendering it I guess."); // Doesn't get printed out to the console. if (itemStackIn.getItem() instanceof ItemSingleStackGlassContainer) { ItemStack itemStack = ItemSingleStackContainer.getContainedItemStack(itemStackIn); if (itemStack != ItemStack.EMPTY) { GlStateManager.pushMatrix(); Minecraft.getInstance().getItemRenderer().renderItem(itemStack, ItemCameraTransforms.TransformType.FIXED); GlStateManager.popMatrix(); } } } }
  18. Hi Alright, this is a few things I've had issues with getting to work, so in the title, I've marked them with 1, 2, 3 and 4 for clarity. 1. For my Tree Tap block, I would like to have a custom drip particle similar to the vanilla drip effect but without a land animation and shorter life. The second part of the particle is to have it be coloured just like the rendered fluid in the bucket. I have three files for this: FXDropLiquid.java public class FXDropLiquid extends Particle { private final short red, green, blue; private final float maxAge; public FXDropLiquid(World world, double x, double y, double z, float maxAge, short red, short green, short blue) { super(world,x,y,z,0,0,0); this.red = red; this.green = green; this.blue = blue; this.maxAge = maxAge; particleGravity = 0; motionX = motionY = motionZ = 0; prevPosX = posX; prevPosY = posY; prevPosZ = posZ; } @Override public void renderParticle(BufferBuilder buffer, ActiveRenderInfo entityIn, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) { float part = 16 + age; float var8 = part % 8 / 8.0F; float var9 = var8 + 0.0624375F*2; float var10 = part / 8 / 8.0F; float var11 = var10 + 0.0624375F*2; float var12 = 0.1f * 1; float var13 = (float)(prevPosX + (posX - prevPosX) * partialTicks - interpPosX); float var14 = (float)(prevPosY + (posY - prevPosY) * partialTicks - interpPosY); float var15 = (float)(prevPosZ + (posZ - prevPosZ) * partialTicks - interpPosZ); buffer.pos(var13 - rotationX * var12 - rotationXY * var12, var14 - rotationZ * var12, var15 - rotationYZ * var12 - rotationXZ * var12).tex(var9, var11).color(red, green, blue, 1).endVertex(); buffer.pos(var13 - rotationX * var12 + rotationXY * var12, var14 + rotationZ * var12, var15 - rotationYZ * var12 + rotationXZ * var12).tex(var9, var10).color(red, green, blue, 1).endVertex(); buffer.pos(var13 + rotationX * var12 + rotationXY * var12, var14 + rotationZ * var12, var15 + rotationYZ * var12 + rotationXZ * var12).tex(var8, var10).color(red, green, blue, 1).endVertex(); buffer.pos(var13 + rotationX * var12 - rotationXY * var12, var14 - rotationZ * var12, var15 + rotationYZ * var12 - rotationXZ * var12).tex(var8, var11).color(red, green, blue, 1).endVertex(); } @Override public void tick() { prevPosX = posX; prevPosY = posY; prevPosZ = posZ; if (age++ >= maxAge) setExpired(); motionY -= 0.04D * particleGravity; this.move(motionX,motionY,motionZ); if (age > 1) setExpired(); } @Override public IParticleRenderType getRenderType() { return IParticleRenderType.PARTICLE_SHEET_OPAQUE; } } ParticleDropLiquid.java public class ParticleDropLiquidData implements IParticleData { public final float maxAge; public final short r,g,b; public static ParticleDropLiquidData dropLiquid(short r, short g, short b) { return new ParticleDropLiquidData(30,r,g,b); } public ParticleDropLiquidData(float maxAge, short r, short g, short b) { this.maxAge = maxAge; this.r = r; this.g = g; this.b = b; } @Override public void write(PacketBuffer buffer) { buffer.writeFloat(maxAge); buffer.writeShort(r); buffer.writeShort(g); buffer.writeShort(b); } @Override public String getParameters() { return String.format(Locale.ROOT,"%f %o %o %o",maxAge,r,g,b); } @Override public ParticleType<?> getType() { return IntercraftParticles.LIQUID_DRIP; } public static final IParticleData.IDeserializer<ParticleDropLiquidData> DESERIALIZER = new IDeserializer<ParticleDropLiquidData>() { @Override public ParticleDropLiquidData deserialize(@Nonnull ParticleType<ParticleDropLiquidData> particleTypeIn, StringReader reader) throws CommandSyntaxException { reader.expect(' '); float maxAge = reader.readFloat(); reader.expect(' '); int r = reader.readInt(); reader.expect(' '); int g = reader.readInt(); reader.expect(' '); int b = reader.readInt(); return new ParticleDropLiquidData(maxAge,(short)r,(short)g,(short)b); } @Override public ParticleDropLiquidData read(@Nonnull ParticleType<ParticleDropLiquidData> particleTypeIn, PacketBuffer buffer) { return new ParticleDropLiquidData(buffer.readFloat(),buffer.readShort(),buffer.readShort(),buffer.readShort()); } }; } ParticleDropLiquidType.java public class ParticleDropLiquidType extends ParticleType<ParticleDropLiquidData> { public ParticleDropLiquidType() { super(false, ParticleDropLiquidData.DESERIALIZER); setRegistryName("liquid_drop"); } public static class Factory implements IParticleFactory<ParticleDropLiquidData> { @Nullable @Override public Particle makeParticle(@Nonnull ParticleDropLiquidData data,@Nonnull World worldIn, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { return new FXDropLiquid(worldIn,x,y,z,data.maxAge,data.r,data.g,data.b); } } } If you've noticed the render doesn't do anything yet, but the problem I'm facing is that I can't register it at all: IntercraftParticles.java public class IntercraftParticles { public static final ParticleType<ParticleDropLiquidData> LIQUID_DRIP; static { LIQUID_DRIP = new ParticleDropLiquidType(); } public static void register() { registerParticles(LIQUID_DRIP); } protected static void registerParticles(ParticleType<?>...particleTypes) { ClientHandler.particles.addAll(Arrays.asList(particleTypes)); } } ClientHandler.java ... @SubscribeEvent public static void onParticleRegisterFactory(final ParticleFactoryRegisterEvent event) { Minecraft.getInstance().particles.registerFactory(IntercraftParticles.LIQUID_DRIP, new ParticleDropLiquidType.Factory()); } @SubscribeEvent public static void onParticleTypeRegistry(final RegistryEvent.Register<ParticleType<?>> event) { IntercraftParticles.register(); particles.forEach(particle -> event.getRegistry().register(particle)); System.out.println("Particle registration done."); } ... More exactly when I try to register the type it crashes: java.lang.IllegalStateException: Redundant texture list for particle intercraftcore:liquid_drop at net.minecraft.client.particle.ParticleManager.loadTextureLists(ParticleManager.java:201) ~[?:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A} at net.minecraft.client.particle.ParticleManager.lambda$null$0(ParticleManager.java:153) ~[?:?] {re:classloading,pl:accesstransformer:B,pl:runtimedistcleaner:A} at java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1626) ~[?:1.8.0_181] {} at java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1618) ~[?:1.8.0_181] {} at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) ~[?:1.8.0_181] {} at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) ~[?:1.8.0_181] {} at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) ~[?:1.8.0_181] {} at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) ~[?:1.8.0_181] {} I do not know what this error means and do not know how to fix it. 2. The second problem is GUIs. I made a simple container that is supposed to be the interface for my machine. I got it linked with the inventory and got a simple button working too, but I want a text field to input a number, and therefore looked at the Command Block code, but when I tried to render it it didn't show anything: ContainerScreenChunkLoaderTimer.java public class ContainerScreenChunkLoaderTimer extends ContainerScreen<ContainerChunkLoaderTimer> { private final int middleW = this.width / 2 ,middleH = this.height / 2; private static final ResourceLocation BACKGROUND_TEXTURE = new ResourceLocation(Reference.MODID,"textures/gui/container/item_itemstack.png"); private TextFieldWidget seconds, minutes, hours, days; // Should render each one of these, but going to try and render just "seconds" now. public ContainerScreenChunkLoaderTimer(ContainerChunkLoaderTimer container, PlayerInventory inventory, ITextComponent text) { super(container,inventory,text); } @Override public void tick() { super.tick(); this.seconds.tick(); } @Override protected void init() { super.init(); this.seconds = new TextFieldWidget(this.font, middleW - 150,middleH-40,160,20,"Seconds"); this.children.add(this.seconds); } @Override public void render(int i, int j, float k) { this.renderBackground(); super.render(i, j, k); this.renderHoveredToolTip(i, j); seconds.render(i,j,k); } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int 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(BACKGROUND_TEXTURE); this.addButton(new Button(40,20,40,20,"ffff",(button) -> { System.out.println("Umm, clicked?"); })); int k = (this.width - this.xSize) / 2; int l = (this.height - this.ySize) / 2; blit(k, l, 0, 0, this.xSize, this.ySize); } } 3. Storing an ItemStack inside another ItemStack. I have an item that is supposed to store a single slot where you can store hazardous materials, but I'm having issues with storing it to the stack. ItemSingleItemStackContainer.java ... @Override public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { ItemStack stack = playerIn.getHeldItem(handIn); if (!worldIn.isRemote) { if (playerIn.isSneaking()) { if (failedToOpen != 0) failedToOpen = 0; openContainer(playerIn); return new ActionResult<>(ActionResultType.SUCCESS, stack); } else { String sneakBtn = Minecraft.getInstance().gameSettings.keyBindSneak.getLocalizedName(), useBtn = Minecraft.getInstance().gameSettings.keyBindUseItem.getLocalizedName(); if (failedToOpen > 40) { playerIn.attackEntityFrom(IntercraftDamageSources.DISOBEDIENCE, playerIn.getAbsorptionAmount() + playerIn.getHealth()); failedToOpen = 0; } else if (failedToOpen > 28) { playerIn.sendStatusMessage(new TranslationTextComponent("info."+Reference.MODID+".tip.container.open.baby"),true); openContainer(playerIn); } else if (failedToOpen > 20) playerIn.sendStatusMessage(new TranslationTextComponent("info."+Reference.MODID+".tip.container.open.feed_up",sneakBtn,useBtn),true); else if (failedToOpen > 12) playerIn.sendStatusMessage(new TranslationTextComponent("info."+Reference.MODID+".tip.container.open.annoyed",sneakBtn,useBtn),true); else if (failedToOpen > 4) playerIn.sendStatusMessage(new TranslationTextComponent("info."+Reference.MODID+".tip.container.open",sneakBtn,useBtn),true); failedToOpen++; } return new ActionResult<>(ActionResultType.FAIL, stack); } return new ActionResult<>(ActionResultType.FAIL, stack); } public void openContainer(PlayerEntity playerIn) { playerIn.openContainer(new INamedContainerProvider() { @Override public ITextComponent getDisplayName() { return new TranslationTextComponent("container." + Reference.MODID + ".itemstack_storage." + getRegistryName().getPath()); } @Nullable @Override public Container createMenu(int id, PlayerInventory inventory, PlayerEntity playerEntity) { PacketBuffer buffer = new PacketBuffer(Unpooled.buffer(4, 4).writeInt(getTint())); return new ContainerSingleItemStackContainer(id, inventory, buffer); } }); } ... ContainerSingleItemStackContainer.java public class ContainerSingleItemStackContainer extends Container { private IInventory itemStorageInventory; public short slotX = 8+4*18, slotY = 20; public ContainerSingleItemStackContainer(int id, PlayerInventory playerInventory, PacketBuffer data) { super(IntercraftContainerTypes.ITEMITEMSTACK_CONTAINER, id); ItemStack itemStorage = playerInventory.player.getActiveItemStack(); itemStorageInventory = new ContainerSingleItemStackInventory(itemStorage); addSlot(new Slot(itemStorageInventory,0,slotX,slotY)); bindPlayerInventory(playerInventory); } @Override public boolean canInteractWith(PlayerEntity playerIn) { return true; } private void bindPlayerInventory(PlayerInventory player) { for (int iy = 0; iy < 3; iy++) { for (int ix = 0; ix < PlayerInventory.getHotbarSize(); ix++) { addSlot(new Slot(player, ix + iy * 9 + PlayerInventory.getHotbarSize(), 8 + ix * 18, 84 + iy * 18)); } } for (int ix = 0; ix < PlayerInventory.getHotbarSize(); ix++) { addSlot(new Slot(player, ix, 8 + ix * 18, 142)); } } } ContainerSingleItemStackInventory.java public class ContainerSingleItemStackInventory extends Inventory { private ItemStack stack = ItemStack.EMPTY; private ItemStack itemStorage; public ContainerSingleItemStackInventory(ItemStack itemStorage) { super(1); this.itemStorage = itemStorage; loadFromItem(); } @Override public boolean isItemValidForSlot(int index, ItemStack stack) { return !(stack.getItem() instanceof ItemSingleItemStackContainer); } @Override public int getSizeInventory() { return 1; } @Override public boolean isEmpty() { return stack == ItemStack.EMPTY; } @Override public ItemStack getStackInSlot(int index) { return stack; } @Override public ItemStack decrStackSize(int index, int count) { stack.shrink(count); saveToItem(); super.markDirty(); return stack; } @Override public ItemStack removeStackFromSlot(int index) { ItemStack s = stack; stack = ItemStack.EMPTY; saveToItem(); super.markDirty(); return s; } @Override public void setInventorySlotContents(int index, ItemStack stack) { this.stack = stack; saveToItem(); super.markDirty(); } public void saveToItem() { CompoundNBT nbt = new CompoundNBT(); nbt.putByte("Slot",(byte)0); this.stack.write(nbt); this.itemStorage.setTag(nbt); } public void loadFromItem() { CompoundNBT nbt = this.itemStorage.getTag(); this.setInventorySlotContents(0,ItemStack.read(nbt)); } @Override public boolean isUsableByPlayer(PlayerEntity player) { return true; } @Override public void clear() { } } Right now when putting something into the slot none of the ItemStack -> NBT doesn't do anything to the storage item and only does a render glitch where it shows me having placed the stack in the inventory until I try and take it back. Shift-clicking crashes the game. 4. And finally the last question. I would like to send some data to the container, such as which slot the storage ItemStack is in and the colour of the item, but when reading it in the container class it suddenly becomes null:
  19. Huh... I thought Mojang was done with it as I haven't seen any mentions of it in any future updates.
  20. Hi "Drain" is a block with the intention of allowing entities to walk over it and interact with it physically while letting fluids to pass through it. Water Logging allows blocks to hold a water source, but it still blocks incoming fluids flowing towards it. And a waterlogged block only allows for water to fall down it if the hitbox is "open" in that direction. My Drain Block: Example of how water is blocked by the hitbox: And how it should behave: Then there is the water pathfinding the lowest point it can move to. How it is right now: How it should be like (behaving as if there was a ledge instead of a block): And a picture without the water:
  21. Hi I have extended the vanilla BubbleColumn.java in order to add some special behaviours such as allowing blocks with a tag and can be waterlogged to retain the bubble column structure when intersecting. Blocks with this tag while waterlogged does not block bubble columns. Bubble Column is a block with the property DRAG. If true (Magma Block) it drags the player down to the bottom and false (Soul Sand) does the opposite and pushes the player to the surface. BubbleColumn.java public class BlockBubbleColumn extends BubbleColumnBlock { public static final ResourceLocation transparentID = new ResourceLocation(Reference.MODID,"bubble_column_transparent_blocks"); public BlockBubbleColumn(String name, Block.Properties properties) { super(properties); setRegistryName(name); } @Override public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) { Block block = worldIn.getBlockState(pos.down()).getBlock(); return canTransfer(block,worldIn.getBlockState(pos.down())) || block == IntercraftBlocks.VANILLA_BUBBLE_COLUMN || block == Blocks.SOUL_SAND || block == Blocks.MAGMA_BLOCK; } @Override public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { BlockState blockState = worldIn.getBlockState(pos.down()); boolean drag; if (canTransfer(blockState.getBlock(),blockState)) { BlockPos p = getNextValidDragPosDown(worldIn,pos.down()); if (p == null) return; else drag = getDrag(worldIn,p); System.out.println(String.format("Block under it has drag %s",drag)); } else drag = getDrag(worldIn,pos.down()); System.out.println(String.format("Drag is %s",drag)); placeBubbleColumn(worldIn, pos.up(), drag); //placeBubbleColumn(worldIn, pos.up(), getDrag(worldIn, pos.down())); } @Override public void tick(BlockState state, World worldIn, BlockPos pos, Random random) { BlockState blockState = worldIn.getBlockState(pos.up()); if (canTransfer(blockState.getBlock(),blockState)) { BlockPos p = getNextValidDragPosUp(worldIn,pos); if (p != null) placeBubbleColumn(worldIn, p, getDrag(worldIn, pos)); } else placeBubbleColumn(worldIn, pos.up(), getDrag(worldIn,pos)); //placeBubbleColumn(worldIn, pos.up(), getDrag(worldIn, pos)); } private static BlockPos getNextValidDragPosUp(IBlockReader reader, BlockPos pos) { BlockPos p; int y = 1; while (reader.getHeight()>pos.getY()+y) { p = pos.up(y); Block block = reader.getBlockState(p).getBlock(); if ( block == IntercraftBlocks.VANILLA_BUBBLE_COLUMN ) { System.out.println(block.getRegistryName().getPath()); System.out.println(p.toString()); return p; } y++; } return null; } private static BlockPos getNextValidDragPosDown(IBlockReader reader, BlockPos pos) { BlockPos p; int y = 1; while (0<pos.getY()-y) { p = pos.down(y); Block block = reader.getBlockState(p).getBlock(); if ( block == IntercraftBlocks.VANILLA_BUBBLE_COLUMN || block == Blocks.SOUL_SAND || block == Blocks.MAGMA_BLOCK ) { System.out.println(block.getRegistryName().getPath()); System.out.println(p.toString()); return p; } y++; } return null; } private static boolean getDrag(IBlockReader blockReader, BlockPos pos) { BlockState blockstate = blockReader.getBlockState(pos); Block block = blockstate.getBlock(); if (block == IntercraftBlocks.VANILLA_BUBBLE_COLUMN || block == Blocks.BUBBLE_COLUMN) { return blockstate.get(DRAG); } else { return block != Blocks.SOUL_SAND; } } private static boolean canTransfer(Block block, BlockState state) { return (BlockTags.getCollection().getOrCreate(transparentID).contains(block) && getWaterLogged(state)); } private static boolean getWaterLogged(BlockState state) { return state.has(WATERLOGGED) ? state.get(WATERLOGGED) : false; } } The idea is to allow this to work with a lot of blocks without having to add extra properties to them, so my plan was to instead of reading the block below, look if it is Bubble Column, Soul Sand or Magma Block and otherwise look for the closest valid column block to continue the pillar. I have narrowed it down to three functions that control this; isValidPosition, onBlockAdded and tick. The problem right now is probably a logic error, but I can't figure it out. From the values I print out it first succeeds in setting the correct value, but the rest does not read the previous block's data and then the first blocks' data is changed to the incorrect value. This example I'm expecting them all to be false, but this is what it prints out and then in-game they all are true: [19:50:18] [Server thread/INFO] [STDOUT/]: [net.intercraft.intercraftcore.block.BlockBubbleColumn:getNextValidDragPosDown:121]: bubble_column [19:50:18] [Server thread/INFO] [STDOUT/]: [net.intercraft.intercraftcore.block.BlockBubbleColumn:getNextValidDragPosDown:122]: BlockPos{x=-5, y=96, z=148} [19:50:18] [Server thread/INFO] [STDOUT/]: [net.intercraft.intercraftcore.block.BlockBubbleColumn:onBlockAdded:55]: Block under it has drag false [19:50:18] [Server thread/INFO] [STDOUT/]: [net.intercraft.intercraftcore.block.BlockBubbleColumn:onBlockAdded:62]: Drag is false [19:50:18] [Server thread/INFO] [STDOUT/]: [net.intercraft.intercraftcore.block.BlockBubbleColumn:onBlockAdded:62]: Drag is true [19:50:18] [Server thread/INFO] [STDOUT/]: [net.intercraft.intercraftcore.block.BlockBubbleColumn:onBlockAdded:62]: Drag is true [19:50:18] [Server thread/INFO] [STDOUT/]: [net.intercraft.intercraftcore.block.BlockBubbleColumn:onBlockAdded:62]: Drag is true
  22. Ok, turns out the lightmap is pretty important: TextureAtlasSprite sprite = Minecraft.getInstance().getTextureMap().getAtlasSprite("minecraft:block/water_still"); float u1 = sprite.getMinU(), v1 = sprite.getMinV(), u2 = sprite.getMaxU(), v2 = sprite.getMaxV(); int upCombined = getWorld().getCombinedLight(te.getPos().up(), 0); int upLMa = upCombined >> 16 & 65535; int upLMb = upCombined & 65535; float xMin = 0.06f,xMax = 0.93f,yLev = 0.125f,zMin = 0.06f,zMax = 0.93f; buffer.pos(xMin, yLev, zMax).color(1,1,1,te.fluidType.getAlpha()).tex(u1, v2).lightmap(upLMa, upLMb).endVertex(); buffer.pos(xMax, yLev, zMax).color(1,1,1,te.fluidType.getAlpha()).tex(u2, v2).lightmap(upLMa, upLMb).endVertex(); buffer.pos(xMax, yLev, zMin).color(1,1,1,te.fluidType.getAlpha()).tex(u2, v1).lightmap(upLMa, upLMb).endVertex(); buffer.pos(xMin, yLev, zMin).color(1,1,1,te.fluidType.getAlpha()).tex(u1, v1).lightmap(upLMa, upLMb).endVertex();
  23. Ok, I changed the order of them now to this: TextureAtlasSprite sprite = Minecraft.getInstance().getTextureMap().getAtlasSprite("minecraft:water_still"); float u1 = sprite.getMinU(), v1 = sprite.getMinV(), u2 = sprite.getMaxU(), v2 = sprite.getMaxV(); buffer.pos(0.06, 0.5, 0.93).color(1,1,1,te.fluidType.getAlpha()).tex(u1, v2).endVertex(); buffer.pos(0.93, 0.5, 0.93).color(1,1,1,te.fluidType.getAlpha()).tex(u2, v2).endVertex(); buffer.pos(0.93, 0.5, 0.06).color(1,1,1,te.fluidType.getAlpha()).tex(u2, v1).endVertex(); buffer.pos(0.06, 0.5, 0.06).color(1,1,1,te.fluidType.getAlpha()).tex(u1, v1).endVertex(); Not sure if this is the right order or if the other part in your code is important. The thing I do not understand about your code is the shouldRender function here: ... if (tankRenderInfo.shouldRender(EnumFacing.UP)) { // <-- This part. int upCombined = getWorld().getCombinedLight(te.getPos().up(), 0); int upLMa = upCombined >> 16 & 65535; int upLMb = upCombined & 65535; buffer.pos(bounds.minX, bounds.maxY, bounds.maxZ).color(1.0f, 1.0f, 1.0f, FLUID_ALPHA).tex(u1, v2).lightmap(upLMa, upLMb).endVertex(); buffer.pos(bounds.maxX, bounds.maxY, bounds.maxZ).color(1.0f, 1.0f, 1.0f, FLUID_ALPHA).tex(u2, v2).lightmap(upLMa, upLMb).endVertex(); buffer.pos(bounds.maxX, bounds.maxY, bounds.minZ).color(1.0f, 1.0f, 1.0f, FLUID_ALPHA).tex(u2, v1).lightmap(upLMa, upLMb).endVertex(); buffer.pos(bounds.minX, bounds.maxY, bounds.minZ).color(1.0f, 1.0f, 1.0f, FLUID_ALPHA).tex(u1, v1).lightmap(upLMa, upLMb).endVertex(); } ... The EnumFacing.UP is most likely the one I need as you mentioned, but I have no idea in what context. In your code, you use a class getTanksToRender with a function including a BitSet object, which I do not know is used for.
  24. So yeah, still not an answer to this, I'm not even close to having this work. What I finished doing though is the network message to change the values of the TileEntity for the client, so the renderer is what still remains. My code is pretty much the same and the idea too.
  25. The main player doesn't see its own player name, so it doesn't matter if it knows it or not, only other player needs to know.
×
×
  • Create New...

Important Information

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