Jump to content

TheMCJavaFre4k

Members
  • Posts

    84
  • Joined

  • Last visited

Posts posted by TheMCJavaFre4k

  1. 6 hours ago, Cadiboo said:

    Please post your code as a GitHub repository. Hardcoding 0 as your ID isn’t the best idea. I recommend registering entity renders in the model registry event. 99% of the time you don’t need a proxy. 

    My repository if found here: https://bitbucket.org/TheMCJavaFre4k/mcdjmod/src/master/

    Will probably swap to using a better ID system for my entities but just thought 0 would suffice for the single entity in testing.

  2. Ive now moved to EntityEntryBuilder for entity registration, but as expected, it has not changed the situation.

    The entity still doesn't have a bounding box or is rendered in any way but is being spawned.

     

    New Entity registration code:

    public static void registerEntity(RegistryEvent.Register<EntityEntry> reg){
    		
    		EntityEntry entityScreen = EntityEntryBuilder.create().entity(EntityScreen.class).id(new ResourceLocation(MCDJMod.modId, "screenentity"), 0).name("screenentity").tracker(160, Integer.MAX_VALUE, true).build();
    		reg.getRegistry().register(entityScreen);
    	
    	}

     

     Any suggestions are appreciated.

  3. Hi There

    Ive been trying to create a identical painting item to default minecraft to later modify with custom rendering. Currently I've made a copy of the Entity, Render and Item classes and registered them(See below). With this code how it is, The entity seems to spawn as it has the behaviour of a minecraft painting, ie - breaks off the wall if a block behind is removed, but has no hitbox and is not rendered. I have tried finding information on this topic but since a custom painting item is such a niche thing to need, I haven't had much luck. Im hoping its just a registration problem and a simple fix. Any suggestions are welcome!

     

    EntityScreen:

    Spoiler
    
    public class EntityScreen extends EntityHanging implements IEntityAdditionalSpawnData
    {
        public EntityScreen.EnumArt art;
    
        public EntityScreen(World worldIn)
        {
            super(worldIn);
        }
    
        public EntityScreen(World worldIn, BlockPos pos, EnumFacing facing)
        {
            super(worldIn, pos);
            
            this.setInvisible(false);
            
            System.out.println("New Entity");
            
            List<EntityScreen.EnumArt> list = Lists.<EntityScreen.EnumArt>newArrayList();
            int i = 0;
    
            for (EntityScreen.EnumArt entitypainting$enumart : EntityScreen.EnumArt.values())
            {
                this.art = entitypainting$enumart;
                this.updateFacingWithBoundingBox(facing);
    
                if (this.onValidSurface())
                {
                    list.add(entitypainting$enumart);
                    int j = entitypainting$enumart.sizeX * entitypainting$enumart.sizeY;
    
                    if (j > i)
                    {
                        i = j;
                    }
                }
            }
    
            if (!list.isEmpty())
            {
                Iterator<EntityScreen.EnumArt> iterator = list.iterator();
    
                while (iterator.hasNext())
                {
                	EntityScreen.EnumArt entitypainting$enumart1 = iterator.next();
    
                    if (entitypainting$enumart1.sizeX * entitypainting$enumart1.sizeY < i)
                    {
                        iterator.remove();
                    }
                }
    
                this.art = list.get(this.rand.nextInt(list.size()));
            }
    
            this.updateFacingWithBoundingBox(facing);
        }
    
        @SideOnly(Side.CLIENT)
        public EntityScreen(World worldIn, BlockPos pos, EnumFacing facing, String title)
        {
            this(worldIn, pos, facing);
    
            for (EntityScreen.EnumArt entitypainting$enumart : EntityScreen.EnumArt.values())
            {
                if (entitypainting$enumart.title.equals(title))
                {
                    this.art = entitypainting$enumart;
                    break;
                }
            }
    
            this.updateFacingWithBoundingBox(facing);
        }
    
        /**
         * (abstract) Protected helper method to write subclass entity data to NBT.
         */
        @Override
        public void writeEntityToNBT(NBTTagCompound compound)
        {
            compound.setString("Motive", this.art.title);
            super.writeEntityToNBT(compound);
        }
    
        /**
         * (abstract) Protected helper method to read subclass entity data from NBT.
         */
        @Override
        public void readEntityFromNBT(NBTTagCompound compound)
        {
            String s = compound.getString("Motive");
    
            for (EntityScreen.EnumArt entitypainting$enumart : EntityScreen.EnumArt.values())
            {
                if (entitypainting$enumart.title.equals(s))
                {
                    this.art = entitypainting$enumart;
                }
            }
    
            if (this.art == null)
            {
                this.art = EntityScreen.EnumArt.KEBAB;
            }
    
            super.readEntityFromNBT(compound);
        }
    
        @Override
        public int getWidthPixels()
        {
            return this.art.sizeX;
        }
    
        @Override
        public int getHeightPixels()
        {
            return this.art.sizeY;
        }
    
        /**
         * Called when this entity is broken. Entity parameter may be null.
         */
        @Override
        public void onBroken(@Nullable Entity brokenEntity)
        {
            if (this.world.getGameRules().getBoolean("doEntityDrops"))
            {
                this.playSound(SoundEvents.ENTITY_PAINTING_BREAK, 1.0F, 1.0F);
    
                if (brokenEntity instanceof EntityPlayer)
                {
                    EntityPlayer entityplayer = (EntityPlayer)brokenEntity;
    
                    if (entityplayer.capabilities.isCreativeMode)
                    {
                        return;
                    }
                }
    
                this.entityDropItem(new ItemStack(Items.PAINTING), 0.0F);
            }
        }
    
        @Override
        public void playPlaceSound()
        {
            this.playSound(SoundEvents.ENTITY_PAINTING_PLACE, 1.0F, 1.0F);
        }
    
        /**
         * Sets the location and Yaw/Pitch of an entity in the world
         */
        @Override
        public void setLocationAndAngles(double x, double y, double z, float yaw, float pitch)
        {
            this.setPosition(x, y, z);
        }
    
        /**
         * Set the position and rotation values directly without any clamping.
         */
        @Override
        @SideOnly(Side.CLIENT)
        public void setPositionAndRotationDirect(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean teleport)
        {
            BlockPos blockpos = this.hangingPosition.add(x - this.posX, y - this.posY, z - this.posZ);
            this.setPosition((double)blockpos.getX(), (double)blockpos.getY(), (double)blockpos.getZ());
        }
    
        public static enum EnumArt
        {
            KEBAB("Kebab", 16, 16, 0, 0),
            AZTEC("Aztec", 16, 16, 16, 0),
            ALBAN("Alban", 16, 16, 32, 0),
            AZTEC_2("Aztec2", 16, 16, 48, 0),
            BOMB("Bomb", 16, 16, 64, 0),
            PLANT("Plant", 16, 16, 80, 0),
            WASTELAND("Wasteland", 16, 16, 96, 0),
            POOL("Pool", 32, 16, 0, 32),
            COURBET("Courbet", 32, 16, 32, 32),
            SEA("Sea", 32, 16, 64, 32),
            SUNSET("Sunset", 32, 16, 96, 32),
            CREEBET("Creebet", 32, 16, 128, 32),
            WANDERER("Wanderer", 16, 32, 0, 64),
            GRAHAM("Graham", 16, 32, 16, 64),
            MATCH("Match", 32, 32, 0, 128),
            BUST("Bust", 32, 32, 32, 128),
            STAGE("Stage", 32, 32, 64, 128),
            VOID("Void", 32, 32, 96, 128),
            SKULL_AND_ROSES("SkullAndRoses", 32, 32, 128, 128),
            WITHER("Wither", 32, 32, 160, 128),
            FIGHTERS("Fighters", 64, 32, 0, 96),
            POINTER("Pointer", 64, 64, 0, 192),
            PIGSCENE("Pigscene", 64, 64, 64, 192),
            BURNING_SKULL("BurningSkull", 64, 64, 128, 192),
            SKELETON("Skeleton", 64, 48, 192, 64),
            DONKEY_KONG("DonkeyKong", 64, 48, 192, 112);
    
            public static final int MAX_NAME_LENGTH = "SkullAndRoses".length();
            /** Painting Title. */
            public final String title;
            public final int sizeX;
            public final int sizeY;
            public final int offsetX;
            public final int offsetY;
    
            private EnumArt(String titleIn, int width, int height, int textureU, int textureV)
            {
                this.title = titleIn;
                this.sizeX = width;
                this.sizeY = height;
                this.offsetX = textureU;
                this.offsetY = textureV;
            }
        }
    
    	@Override
    	public void writeSpawnData(ByteBuf buffer) {
    		buffer.writeInt(this.art.ordinal());
            buffer.writeInt(this.chunkCoordX);       // x
            buffer.writeInt(this.chunkCoordY);       // y
            buffer.writeInt(this.chunkCoordZ);       // z
            buffer.writeByte(this.getHorizontalFacing().getIndex());
    		
    	}
    
    	@Override
    	public void readSpawnData(ByteBuf buffer) {
    		EntityScreen.EnumArt[] aenumart = EntityScreen.EnumArt.values();
    		this.art = aenumart[buffer.readInt()];
    	        this.chunkCoordX = buffer.readInt();
    	        this.chunkCoordY = buffer.readInt();
    	        this.chunkCoordZ = buffer.readInt();
    	        this.facingDirection = (EnumFacing.getFront((buffer.readByte())));
    		
    	        System.out.println("Info Read, X=" + this.chunkCoordX + ", Y=" + this.chunkCoordY + ", Z=" + this.chunkCoordZ + ", Facing=" + this.facingDirection);
    	        
    	}
    }

     

     

    RenderScreen:

    Spoiler
    
    @SideOnly(Side.CLIENT)
    public class RenderScreen extends Render<EntityScreen>
    {
        private static final ResourceLocation KRISTOFFER_PAINTING_TEXTURE = new ResourceLocation("mcdj", "textures/painting/painting.png");
    
        public RenderScreen(RenderManager renderManagerIn)
        {
            super(renderManagerIn);
            
            System.out.println("Create Renderer in class");
            
        }
    
        /**
         * Renders the desired {@code T} type Entity.
         */
        public void doRender(EntityScreen entity, double x, double y, double z, float entityYaw, float partialTicks)
        {
        	
        	System.out.println("Do Render");
        	
            GlStateManager.pushMatrix();
            GlStateManager.translate(x, y, z);
            GlStateManager.rotate(180.0F - entityYaw, 0.0F, 1.0F, 0.0F);
            GlStateManager.enableRescaleNormal();
            this.bindEntityTexture(entity);
            EntityScreen.EnumArt entitypainting$enumart = entity.art;
            float f = 0.0625F;
            GlStateManager.scale(0.0625F, 0.0625F, 0.0625F);
    
            if (this.renderOutlines)
            {
                GlStateManager.enableColorMaterial();
                GlStateManager.enableOutlineMode(this.getTeamColor(entity));
            }
    
            this.renderPainting(entity, entitypainting$enumart.sizeX, entitypainting$enumart.sizeY, entitypainting$enumart.offsetX, entitypainting$enumart.offsetY);
    
            if (this.renderOutlines)
            {
                GlStateManager.disableOutlineMode();
                GlStateManager.disableColorMaterial();
            }
    
            GlStateManager.disableRescaleNormal();
            GlStateManager.popMatrix();
            super.doRender(entity, x, y, z, entityYaw, partialTicks);
        }
    
        /**
         * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
         */
        protected ResourceLocation getEntityTexture(EntityScreen entity)
        {
            return KRISTOFFER_PAINTING_TEXTURE;
        }
    
        private void renderPainting(EntityScreen painting, int width, int height, int textureU, int textureV)
        {
        	
        	
        	
            float f = (float)(-width) / 2.0F;
            float f1 = (float)(-height) / 2.0F;
            float f2 = 0.5F;
            float f3 = 0.75F;
            float f4 = 0.8125F;
            float f5 = 0.0F;
            float f6 = 0.0625F;
            float f7 = 0.75F;
            float f8 = 0.8125F;
            float f9 = 0.001953125F;
            float f10 = 0.001953125F;
            float f11 = 0.7519531F;
            float f12 = 0.7519531F;
            float f13 = 0.0F;
            float f14 = 0.0625F;
    
            for (int i = 0; i < width / 16; ++i)
            {
                for (int j = 0; j < height / 16; ++j)
                {
                    float f15 = f + (float)((i + 1) * 16);
                    float f16 = f + (float)(i * 16);
                    float f17 = f1 + (float)((j + 1) * 16);
                    float f18 = f1 + (float)(j * 16);
                    this.setLightmap(painting, (f15 + f16) / 2.0F, (f17 + f18) / 2.0F);
                    float f19 = (float)(textureU + width - i * 16) / 256.0F;
                    float f20 = (float)(textureU + width - (i + 1) * 16) / 256.0F;
                    float f21 = (float)(textureV + height - j * 16) / 256.0F;
                    float f22 = (float)(textureV + height - (j + 1) * 16) / 256.0F;
                    Tessellator tessellator = Tessellator.getInstance();
                    BufferBuilder bufferbuilder = tessellator.getBuffer();
                    bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_NORMAL);
                    bufferbuilder.pos((double)f15, (double)f18, -0.5D).tex((double)f20, (double)f21).normal(0.0F, 0.0F, -1.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f18, -0.5D).tex((double)f19, (double)f21).normal(0.0F, 0.0F, -1.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f17, -0.5D).tex((double)f19, (double)f22).normal(0.0F, 0.0F, -1.0F).endVertex();
                    bufferbuilder.pos((double)f15, (double)f17, -0.5D).tex((double)f20, (double)f22).normal(0.0F, 0.0F, -1.0F).endVertex();
                    bufferbuilder.pos((double)f15, (double)f17, 0.5D).tex(0.75D, 0.0D).normal(0.0F, 0.0F, 1.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f17, 0.5D).tex(0.8125D, 0.0D).normal(0.0F, 0.0F, 1.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f18, 0.5D).tex(0.8125D, 0.0625D).normal(0.0F, 0.0F, 1.0F).endVertex();
                    bufferbuilder.pos((double)f15, (double)f18, 0.5D).tex(0.75D, 0.0625D).normal(0.0F, 0.0F, 1.0F).endVertex();
                    bufferbuilder.pos((double)f15, (double)f17, -0.5D).tex(0.75D, 0.001953125D).normal(0.0F, 1.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f17, -0.5D).tex(0.8125D, 0.001953125D).normal(0.0F, 1.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f17, 0.5D).tex(0.8125D, 0.001953125D).normal(0.0F, 1.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f15, (double)f17, 0.5D).tex(0.75D, 0.001953125D).normal(0.0F, 1.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f15, (double)f18, 0.5D).tex(0.75D, 0.001953125D).normal(0.0F, -1.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f18, 0.5D).tex(0.8125D, 0.001953125D).normal(0.0F, -1.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f18, -0.5D).tex(0.8125D, 0.001953125D).normal(0.0F, -1.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f15, (double)f18, -0.5D).tex(0.75D, 0.001953125D).normal(0.0F, -1.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f15, (double)f17, 0.5D).tex(0.751953125D, 0.0D).normal(-1.0F, 0.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f15, (double)f18, 0.5D).tex(0.751953125D, 0.0625D).normal(-1.0F, 0.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f15, (double)f18, -0.5D).tex(0.751953125D, 0.0625D).normal(-1.0F, 0.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f15, (double)f17, -0.5D).tex(0.751953125D, 0.0D).normal(-1.0F, 0.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f17, -0.5D).tex(0.751953125D, 0.0D).normal(1.0F, 0.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f18, -0.5D).tex(0.751953125D, 0.0625D).normal(1.0F, 0.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f18, 0.5D).tex(0.751953125D, 0.0625D).normal(1.0F, 0.0F, 0.0F).endVertex();
                    bufferbuilder.pos((double)f16, (double)f17, 0.5D).tex(0.751953125D, 0.0D).normal(1.0F, 0.0F, 0.0F).endVertex();
                    tessellator.draw();
                }
            }
        }
    
        private void setLightmap(EntityScreen painting, float p_77008_2_, float p_77008_3_)
        {
            int i = MathHelper.floor(painting.posX);
            int j = MathHelper.floor(painting.posY + (double)(p_77008_3_ / 16.0F));
            int k = MathHelper.floor(painting.posZ);
            EnumFacing enumfacing = painting.facingDirection;
    
            if (enumfacing == EnumFacing.NORTH)
            {
                i = MathHelper.floor(painting.posX + (double)(p_77008_2_ / 16.0F));
            }
    
            if (enumfacing == EnumFacing.WEST)
            {
                k = MathHelper.floor(painting.posZ - (double)(p_77008_2_ / 16.0F));
            }
    
            if (enumfacing == EnumFacing.SOUTH)
            {
                i = MathHelper.floor(painting.posX - (double)(p_77008_2_ / 16.0F));
            }
    
            if (enumfacing == EnumFacing.EAST)
            {
                k = MathHelper.floor(painting.posZ + (double)(p_77008_2_ / 16.0F));
            }
    
            int l = this.renderManager.world.getCombinedLight(new BlockPos(i, j, k), 0);
            int i1 = l % 65536;
            int j1 = l / 65536;
            OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)i1, (float)j1);
            GlStateManager.color(1.0F, 1.0F, 1.0F);
        }
    
    }

     

     

    ItemScreen:

    Spoiler
    
    public class ItemScreen extends Item
    {
    
        public ItemScreen()
        {
            setUnlocalizedName("screen");
            setRegistryName("screen");
        }
        
        public void registerItemModel(){
    		MCDJMod.proxy.registerItemRenderer(this, 0, "screen", "mcdj");
    	}
    
        /**
         * Called when a Block is right-clicked with this Item
         */
        public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
        {
            ItemStack itemstack = player.getHeldItem(hand);
            BlockPos blockpos = pos.offset(facing);
    
            if (facing != EnumFacing.DOWN && facing != EnumFacing.UP && player.canPlayerEdit(blockpos, facing, itemstack))
            {
                EntityHanging entityhanging = this.createEntity(worldIn, blockpos, facing);
    
                if (entityhanging != null && entityhanging.onValidSurface())
                {
                    if (!worldIn.isRemote)
                    {
                        entityhanging.playPlaceSound();
                        worldIn.spawnEntity(entityhanging);
                    }
    
                    itemstack.shrink(1);
                }
    
                return EnumActionResult.SUCCESS;
            }
            else
            {
                return EnumActionResult.FAIL;
            }
        }
    
        @Nullable
        private EntityHanging createEntity(World worldIn, BlockPos pos, EnumFacing clickedSide)
        {
                return new EntityScreen(worldIn, pos, clickedSide);
        }
    }

     

     

    Renderer Registration in ClientProxy:

     RenderingRegistry.registerEntityRenderingHandler(EntityScreen.class, new RenderScreenFactory());

     

    RenderScreenFactory:

    public class RenderScreenFactory implements IRenderFactory<EntityScreen> {
    
    	@Override
    	public Render<? super EntityScreen> createRenderFor(RenderManager manager) {
    		return new RenderScreen(manager);
    	}
    
    }

     

    Entity Registration called in PreInit:

    EntityRegistry.registerModEntity(new ResourceLocation("mcdj", "screenentity"), EntityScreen.class, "screenEntity", 0, MCDJMod.instance, 160, Integer.MAX_VALUE, false);		

     

    If any more information is required, let me know.

  4. 7 hours ago, Draco18s said:

    Option (b) use an ITickableSound in order for it to terminate itself when its source block is removed.

    https://github.com/Draco18s/ReasonableRealism/blob/1.12.1/src/main/java/com/draco18s/ores/client/SoundWindmill.java#L37

    I totally forgot to check if I could use the sound to stop itself. I guess I just had tunnel vision when looking at the problem. Considering my custom sound is a tickable sound, this works flawlessly. Thanks heaps!

  5. 3 hours ago, Ice2670 said:

    thank you for replying! are there 3 kinds of counters for ServerTickEvent, WorldTcikEvent and PlayerTickEvent? 

     Mind show me an example or just direct me to a thread with examples?

    By counter, I believe DavidM is suggesting you use a type such as an Integer which is incremented by 1(int++) within update().

    You would then have the if statement check the value of this Integer and if it reaches 5, set it back to 0.

  6. 6 minutes ago, Cadiboo said:

    Couldn’t you subscribe to the sound play event and cancel it?

    I haven't dealt with any Events thus far other than the standard registration ones so I wouldn't know where to begin. They current way I'm dealing with sounds is by using a custom MovingSound class(So to update positioning) being played by Minecraft.getMinecraft().getSoundHandler().playSound(). I can then stop it by passing in the exact same sound. This allows me to differentiate the exact same sound being played from 2 TileEntities and stop them independent of one another. Is this same functionality obtainable using a @SubscribeEvent and subscribing to the PlaySoundEvent class?

  7. 1 minute ago, Cadiboo said:

    Why are you trying to do this? You can probably send whatever data you need in the packet

    My tile entity has a few methods responsible for stopping sound playback. The packet is used to update all nearby clients to stop any sound the TileEntity is making before it is removed. So in the packet handler I'm getting the TileEntity from the position sent over the packet and calling my methods on the client from there.

  8. Hi There

    Im wanting to prevent the tile entity of a block from being removed until after Ive executed some code within the tile entity via a custom packet.

     

    Im able to get this working in survival mode by sending the packet within the getDrops method and delaying removal until the harvestBlock method(Similar to blockFlowerPot) as so:

    Spoiler
    
    @Override
    	public void getDrops(net.minecraft.util.NonNullList<ItemStack> drops, IBlockAccess worldIn, BlockPos pos, IBlockState state, int fortune)
    	{
    		super.getDrops(drops, worldIn, pos, state, fortune);
    		World world = (World)worldIn;
    
    		TileEntityDJDeck te = world.getTileEntity(pos) instanceof TileEntityDJDeck ? (TileEntityDJDeck)world.getTileEntity(pos) : null;
    
    		System.out.println("Called Get Drops");
    
    		if (te != null) {
    
    			System.out.println("Sending Stop To Server");
    
    			MCDJMod.network.sendToAllAround(new PacketPlaySoundOnClient(pos, 0, 3), new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX(), pos.getY(), pos.getZ(), 20)); 
    
    		}
    
    	}
    
    	@Override
    	public void harvestBlock(World world, EntityPlayer player, BlockPos pos, IBlockState state, @Nullable TileEntity te, ItemStack tool)
    	{
    		super.harvestBlock(world, player, pos, state, te, tool);
    
    		System.out.println("Harvesting");
    
    		world.setBlockToAir(pos);
    		world.removeTileEntity(pos);
    	}
    
    	@Override
    	public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) {
    		return true; 
    	}

     

     Currently when broken in creative, nothing happens(Only breaking particles). I was initially using breakBlock but that didn't provide enough time for the packet to be read and when it was, the tile entity at the BlockPos was already removed.

    Im just not sure what methods would provide the necessary time or how i would modify the above setup to work for creative mode.

  9. 15 hours ago, MayusYT said:

    HI! I started Forge modding a few weeks ago and I'm stuck at understanding the packets I have to use when e.g. clicking on a button on a GUI of a block. Let's choose an enable/disable button for this example. The button will change its texture whether the machine is enabled or not. So I understand that I have to send a packet from the GUI click "listener" that has to change my boolean "enabled" in my tile class. But when you open the GUI, you should see whether the machine is enabled or not. How do I do the communication between the server and the client? I heard that sending a packet is unnecessary.

     

     

    Thank you very much in advance!

    Ive just used my container class to get the tile entity into the gui. Using:

    container.tileEntity.variables

     I just grab the variables I need straight from the tile entity. Not sure if this is the most correct way to do it but it works on both logical and physical servers with no issue.

    • Like 1
  10. Hi There

    Im currently sending packets from a tile entity to all nearby clients to play sounds(This is necessary over traditional playSound methods due to high control over the sound). On a single player world, everything works as expected and the debug printouts within the code come from the expected sides. When running on a dedicated server, the packet constructor and toBytes() are both called with correct data but nothing happens following that. No code within the Packet Handler is executed and neither is fromBytes().

     

    PacketPlaySoundOnClient:

    Spoiler
    
    import io.netty.buffer.ByteBuf;
    import net.minecraft.util.math.BlockPos;
    import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
    
    
    public class PacketPlaySoundOnClient implements IMessage{
    
    	public BlockPos pos;
    	public int slot;	
    	public int instruction;
    
    	public PacketPlaySoundOnClient(BlockPos pos, int slot, int instruction) {
    		this.pos = pos;
    		this.slot = slot;
    		this.instruction = instruction;
    		
    		System.out.println("Constructing Packet");
    		
    	}
    
    	public PacketPlaySoundOnClient() {}
    	
    	@Override
    	public void fromBytes(ByteBuf buf) {
    		pos = BlockPos.fromLong(buf.readLong());
    		slot = buf.readInt();
    		instruction = buf.readInt();	
    		System.out.println("From Bytes Pos = " + pos + ", Slot = " + slot);
    	}
    
    	@Override
    	public void toBytes(ByteBuf buf) {
    		System.out.println("To Bytes Pos = " + pos + ", Slot = " + slot);
    		buf.writeLong(pos.toLong());
    		buf.writeInt(slot);
    		buf.writeInt(instruction);
    	}
    
    	
    
    
    
    }

     

     

    ClientSoundHandler:

    Spoiler
    
    package net.themcjavafre4k.mcdj.networking;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import net.minecraft.client.Minecraft;
    import net.minecraft.item.ItemStack;
    import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
    import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
    import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
    import net.minecraftforge.fml.relauncher.Side;
    import net.minecraftforge.fml.relauncher.SideOnly;
    import net.themcjavafre4k.mcdj.SoundHandler;
    import net.themcjavafre4k.mcdj.item.ItemCustomRecord;
    import net.themcjavafre4k.mcdj.item.MCDJItems;
    import net.themcjavafre4k.mcdj.sound.SoundDJDeck;
    import net.themcjavafre4k.mcdj.tileentity.TileEntityDJDeck;
    
    public class ClientSoundHandler implements IMessageHandler<PacketPlaySoundOnClient, IMessage> {
    
    	private List<SoundDJDeck> slot1 = new ArrayList<SoundDJDeck>();
    
    	@Override
    	public IMessage onMessage(PacketPlaySoundOnClient msg, MessageContext ctx) {
    
    		if(ctx.side != Side.CLIENT) {
    
    			System.err.println("Recieved on Server Side");
    			return null;
    
    		}
    		
    		System.out.println("Packet recieved");
    
    		Minecraft.getMinecraft().addScheduledTask(() -> {
    
    			TileEntityDJDeck tile = (TileEntityDJDeck) Minecraft.getMinecraft().world.getTileEntity(msg.pos);
    
    			System.out.print("Plays");
    
    			ItemStack records = tile.inventory.getStackInSlot(0);
    			ItemCustomRecord slot1Record = (ItemCustomRecord)records.getItem();
    
    				switch(msg.slot) {
    				case 0:
    					System.out.println("Playing Sound In Slot 1");
    
    					slot1.add(new SoundDJDeck(msg.pos, SoundHandler.getRecordSound(MCDJItems.customRecord.indexOf(tile.inventory.getStackInSlot(0).getItem())), 0));			
    					Minecraft.getMinecraft().getSoundHandler().playSound(slot1.get(0));
    					break;
    
    				}
    
    
    
    		});
    		return null;
    	}
    
    }

     

     

    Registering packet in my ClientProxy(Only packet with id 11):

    MCDJMod.network.registerMessage(ClientSoundHandler.class, PacketPlaySoundOnClient.class, 11, Side.CLIENT);
    		

     

     

    Calling send method:

    Spoiler
    
    System.out.print("Play Method Called \n");
    
    		if(!world.isRemote) {
    
    			MCDJMod.network.sendToAllAround(new PacketPlaySoundOnClient(pos, slot, 0), new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX(), pos.getY(), pos.getZ(), 20)); 
    
    		}

     

     

    On a side not, If i leave out the instruction integer from my packet, I get the following IndexOutOfBoundException from the client followed by disconnection from the server:

    readerIndex(11) + length(2) exceeds writerIndex(12): UnpooledSlicedByteBuf(ridx: 11, widx: 12, cap: 12/12, unwrapped: PooledUnsafeDirectByteBuf(ridx: 0, widx: 13, cap: 13))
    	

     

    Not sure if this may have something to do with the issue.

  11. 1 minute ago, Cadiboo said:

    Have you searched the forums for similar topics? If I remember correctly there was a topic about something very similar not long ago, and I think the person posted their working code at the end.

     The only real similar one i found was the one i referenced in the post. All others seem to be regarding tile entities with the same issues. Will have another look though.

  12. Hi there

    My aim was to create a single slot inventory when an item was right clicked. Im good with all the gui stuff but can seem to nail the capabilities and NBT. 

    I found this post(

    I also don't know using the current setup how I would go about accessing the contents of the slot from within the item class.

     

    Any guidance is appreciated.

     

    Code:

    ItemClass:

    package net.themcjavafre4k.mcdj.item.headphones;
    
    import net.minecraft.entity.EntityLivingBase;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.inventory.EntityEquipmentSlot;
    import net.minecraft.item.ItemArmor;
    import net.minecraft.item.ItemStack;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.util.ActionResult;
    import net.minecraft.util.EnumActionResult;
    import net.minecraft.util.EnumHand;
    import net.minecraft.world.World;
    import net.minecraftforge.common.capabilities.ICapabilityProvider;
    import net.minecraftforge.items.CapabilityItemHandler;
    import net.minecraftforge.items.IItemHandler;
    import net.themcjavafre4k.mcdj.MCDJGuiHandler;
    import net.themcjavafre4k.mcdj.MCDJMod;
    import net.themcjavafre4k.mcdj.item.CustomRecord;
    import net.themcjavafre4k.mcdj.item.MCDJItems;
    
    public class ItemHeadphones extends ItemArmor{
    
    	private String title;
    
    	public ItemHeadphones(String name){
    		super(MCDJItems.headphoneMaterial, 1, EntityEquipmentSlot.HEAD);
    		this.title = name;
    		setUnlocalizedName(name);
    		setRegistryName(name);
    		setCreativeTab(MCDJMod.creativeTab);
    		INSTANCE = this;
    	}
    
    	public void registerItemModel(){
    		MCDJMod.proxy.registerItemRenderer(this, 0, title, "mcdj");
    	}
    
    	@Override
    	public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand){
    		ItemStack itemstack = player.getHeldItem(hand);
    
    		if (!world.isRemote){
    			player.openGui(MCDJMod.instance, MCDJGuiHandler.HEADPHONES, world, (int)player.posX, (int)player.posY, (int)player.posZ);
    			//LogHelper.info("Succesfully opened GUI");
    		}
    
    		return new ActionResult<ItemStack>(EnumActionResult.PASS, player.getHeldItemMainhand());
    	}
    
    	@Override
    	public ICapabilityProvider initCapabilities( ItemStack item, NBTTagCompound nbt ) {
    		return new HeadphonesProvider();
    	}
    
    }

     

    Provider:

    package net.themcjavafre4k.mcdj.item.headphones;
    
    import net.minecraft.nbt.NBTBase;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.util.EnumFacing;
    import net.minecraftforge.common.capabilities.Capability;
    import net.minecraftforge.common.capabilities.ICapabilityProvider;
    import net.minecraftforge.common.capabilities.ICapabilitySerializable;
    import net.minecraftforge.items.CapabilityItemHandler;
    import net.minecraftforge.items.ItemStackHandler;
    
    public class HeadphonesProvider implements ICapabilityProvider, ICapabilitySerializable<NBTTagCompound>{
    
    	private ItemStackHandler inventory;
    
    	public HeadphonesProvider() {
    		inventory = new ItemStackHandler(1);
    	}
    
    	@Override
    	public NBTTagCompound serializeNBT() {
    		return inventory.serializeNBT();
    	}
    
    	@Override
    	public void deserializeNBT( NBTTagCompound nbt ) {
    		// nbt = new NBTTagCompound();
        	inventory.deserializeNBT(nbt);
    
    	}
    
    	@Override
    	public boolean hasCapability( Capability<?> capability, EnumFacing facing ) {
    		if( capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY ) {
    			return true;
    		}
    		return false;
    	}
    
    	@Override
    	public <T> T getCapability( Capability<T> capability, EnumFacing facing ) {
    		if( capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY ) {
    			return (T) inventory; 
    		}
    		return null;
    	}
    	
    	
    }
    
    

     

    Container:

    package net.themcjavafre4k.mcdj.item.headphones;
    
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.inventory.Container;
    import net.minecraft.inventory.Slot;
    import net.minecraft.item.ItemStack;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraftforge.items.IItemHandler;
    import net.themcjavafre4k.mcdj.inventory.SlotInput;
    import net.themcjavafre4k.mcdj.item.CustomRecord;
    import net.themcjavafre4k.mcdj.item.MCDJItems;
    
    public class ContainerHeadphones extends Container{
    
    	public IItemHandler inv;
    
    	public ContainerHeadphones(IItemHandler itemHandler, EntityPlayer player ) {
    
    		this.inv = itemHandler;
    
    		addSlotToContainer(new SlotInput(itemHandler, 0, 44, 35));
    
    		for(int i = 0; i < 3; i++){
    			for(int j = 0; j < 9; j++){
    				addSlotToContainer(new Slot(player.inventory, j+i*9+9, 8+j*18, 84+i*18));
    			}
    		}
    
    		for(int i = 0; i < 9; i++){
    			addSlotToContainer(new Slot(player.inventory, i, 8+i*18, 142));
    		}
    
    	}
    
    	@Override
    	public boolean canInteractWith(EntityPlayer playerIn) {
    		return true;
    	}
    
    	//Crashing game
    	//	@Nullable
    	//	@Override
    	//	public ItemStack transferStackInSlot(EntityPlayer playerIn, int index)
    	//    {
    	//        ItemStack itemstack = ItemStack.EMPTY;
    	//        Slot slot = this.inventorySlots.get(index);
    	//
    	//        if (slot != null && slot.getHasStack())
    	//        {
    	//            ItemStack itemstack1 = slot.getStack();
    	//            itemstack = itemstack1.copy();
    	//
    	//            if (index == 2)
    	//            {
    	//                if (!this.mergeItemStack(itemstack1, 3, 39, true))
    	//                {
    	//                    return ItemStack.EMPTY;
    	//                }
    	//
    	//                slot.onSlotChange(itemstack1, itemstack);
    	//            }
    	//            else if (!this.mergeItemStack(itemstack1, 3, 39, false))
    	//            {
    	//                return ItemStack.EMPTY;
    	//            }
    	//
    	//            if (itemstack1.isEmpty())
    	//            {
    	//                slot.putStack(ItemStack.EMPTY);
    	//            }
    	//            else
    	//            {
    	//                slot.onSlotChanged();
    	//            }
    	//
    	//            if (itemstack1.getCount() == itemstack.getCount())
    	//            {
    	//                return ItemStack.EMPTY;
    	//            }
    	//
    	//            slot.onTake(playerIn, itemstack1);
    	//        }
    	//
    	//        return itemstack;
    	//    }
    
    
    
    }

     

    SlotInput:

    package net.themcjavafre4k.mcdj.inventory;
    
    import javax.annotation.Nonnull;
    
    import net.minecraft.item.ItemStack;
    import net.minecraftforge.items.IItemHandler;
    import net.minecraftforge.items.SlotItemHandler;
    import net.themcjavafre4k.mcdj.item.CustomRecord;
    import net.themcjavafre4k.mcdj.item.MCDJItems;
    
    
    public class SlotInput extends SlotItemHandler {
    	public SlotInput(IItemHandler inventory, int par2, int par3, int par4) {
    		super(inventory, par2, par3, par4);
    	}
    
    	@Override
    	public boolean isItemValid(ItemStack itemstack) {
    		return itemstack.getItem() instanceof CustomRecord;
    		//return true;
    	}
    
    	@Override
    	public int getSlotStackLimit() {
    		return 1;
    	}
    	
    	
    }

     

    Gui:

    package net.themcjavafre4k.mcdj.item.headphones;
    
    import net.minecraft.client.Minecraft;
    import net.minecraft.client.gui.GuiButton;
    import net.minecraft.client.gui.inventory.GuiContainer;
    import net.minecraft.client.renderer.GlStateManager;
    import net.minecraft.client.resources.I18n;
    import net.minecraft.entity.player.InventoryPlayer;
    import net.minecraft.inventory.Container;
    import net.minecraft.util.ResourceLocation;
    import net.minecraftforge.fml.relauncher.Side;
    import net.minecraftforge.fml.relauncher.SideOnly;
    import net.themcjavafre4k.mcdj.MCDJMod;
    import net.themcjavafre4k.mcdj.SoundHandler;
    import net.themcjavafre4k.mcdj.item.MCDJItems;
    
    
    @SideOnly(Side.CLIENT)
    public class GuiHeadphones extends GuiContainer{
    
    	private static final ResourceLocation BG_TEXTURE = new ResourceLocation(MCDJMod.modId, "textures/gui/headphonegui.png");
    
    	public GuiHeadphones(Container container, InventoryPlayer inventory) {
    		super(container);
    
    	}
    
    	@Override
    	public void initGui(){
    		super.initGui();
    	}
    
    	@Override
    	public void drawScreen(int mouseX, int mouseY, float partialTicks) {
    		this.drawDefaultBackground();
    		super.drawScreen(mouseX, mouseY, partialTicks);
    		this.renderHoveredToolTip(mouseX, mouseY);
    	}
    
    	@Override
    	protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY){
    		GlStateManager.color(1, 1, 1, 1);
    		mc.getTextureManager().bindTexture(BG_TEXTURE);
    		int x = (width - xSize) / 2;
    		int y = (height - ySize) / 2;
    		drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
    	}
    
    	@Override
    	protected void drawGuiContainerForegroundLayer(int mousX, int mouseY){
    		String name = I18n.format(MCDJItems.headphones.getUnlocalizedName());
    		//fontRenderer.drawString("Search For Songs", 195, 4, 0xFFFFFF);
    		fontRenderer.drawString("Headphone Player", (xSize/2 - fontRenderer.getStringWidth(name)/2), 5, 0xFFFFFF);
    		//fontRenderer.drawString(invPlayer.getDisplayName().getUnformattedText(), 8, ySize/2 - 10, 0xFFFFFF);
    	}
    
    
    }

     If any more information is needed I will provide.

  13. 4 hours ago, skeeter144 said:

    If you're calling playSound from the server (which you were in your original example), you want to pass null as the player reference:

     

    
    player.world.playSound(null, pos, SoundHandler.record1, SoundCategory.RECORDS, 1.0f, 1.0f);   

     

    Calling world.playSound (ON THE SERVER) plays the sound for everybody EXCEPT the player passed into it. If you pass null, it plays for everyone.

     

    Calling world.playSounds (ON THE CLIENT) plays the sound ONLY for the player passed in. (Which should only be the local player anyway... it is local after all)

     

     

    Next, You've got a few issues here with your sound registering.

     

    In your SoundHandler class, you need to register with your MODID and sound name, e.g. 

    You also don't want .ogg in the regsistry because this ResourceLocation is not a RL to a sound file, but a .json entry describing your sound

     

    
    private static SoundEvent createSoundEvent2(String soundName){
    		final ResourceLocation sound = new ResourceLocation(MODID /* whatever your mod id is... */, soundName);
    		System.out.println("Create Sound2");
    		return new SoundEvent(sound).setRegistryName(soundName);
    	}

     

    If you don't use your mod id, it will default to looking in Minecraft's sound folder.

     

     

    That should get you on the right direction and getting some kinks worked out!

    Thanks heaps for your suggestions, It worked. It turns out it was the missing domain for the resourcelocation. Its interesting that it would still play via /playSound command but not using world.playSound method.

  14. Ive double checked with the documentation(found https://mcforge.readthedocs.io/en/latest/effects/sounds/) and it looks like it should be working since I am using the second method under World option. This should play to all players and if the passed in player is the client, it should play to them aswell. 

    The Method I have at the moment:

    player.world.playSound(player, pos, SoundHandler.record1, SoundCategory.RECORDS, 1.0f, 1.0f);     

     

  15. I’ve just recently changed my item class to extend ItemRecord and removed the onItemUse function to see if it is the way I am implementing playSound. I pass in the sound event when creating the item but still the same result. No errors return and the jukebox displays the correct sound event.desc(as I haven’t added it in Lang) but still doesn’t play the audio.

    playing through a command still plays the audio after this change.

    any ideas are welcome.

  16. 1 hour ago, American2050 said:

    Try with:

    
    worldIn.playSound(player, pos, SoundHandler.record1, SoundCategory.RECORDS, 1.0f, 1.0f); 

    Also I believe you don't need the .ogg when creating the Sounds.
     

    
    public class CreateSoundEvent extends SoundEvent {
    
        public CreateSoundEvent(String name) {
            super(new ResourceLocation(ModInfo.MODID, name));
            this.setRegistryName(new ResourceLocation(ModInfo.MODID, name));
    
            ModSounds.SOUNDS.add(this);
        }
    
    }

     

     Still no sound using updated play method. But same thing, I can use default Minecraft sounds and it works and I can also play the required sound via command.

     

    Thanks for the heads up about no need for the extension. Makes everything a little neater.

  17. I can't seem to figure out why I'm able to play my custom sound through the command /playsound... but not when calling the function world.play(...);

    I know the code is correctly firing on right click and will even work with playing default sounds but not custom ones.

     

    Trigger Code:

    @Override
    	public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
        {
            IBlockState iblockstate = worldIn.getBlockState(pos);
    
            if (iblockstate.getBlock() == Blocks.JUKEBOX && !((Boolean)iblockstate.getValue(BlockJukebox.HAS_RECORD)).booleanValue())
            {
            	
                if (!worldIn.isRemote)
                {
                    ItemStack itemstack = player.getHeldItem(hand);
                    ((BlockJukebox)Blocks.JUKEBOX).insertRecord(worldIn, pos, iblockstate, itemstack);
                    player.world.playSound((EntityPlayer)null, pos, SoundHandler.record1, SoundCategory.RECORDS, 1.0f, 1.0f);       
                    itemstack.setCount(0);
                    player.addStat(StatList.RECORD_PLAYED);
                }
    
                return EnumActionResult.SUCCESS;
            }
            else
            {
                return EnumActionResult.PASS;
            }
        }

     

    SoundHandler class(SoundHandler() called in preInit() to set record1 but can easily be moved up to declaration):

    public final class SoundHandler {
    
    	public static SoundEvent record1;
    
    	public SoundHandler(){
    		
    		record1 = createSoundEvent2("record1");
    
    	}
    	
    	private static SoundEvent createSoundEvent2(String soundName){
    		final ResourceLocation sound = new ResourceLocation(soundName + ".ogg");
    		System.out.println("Create Sound2");
    		return new SoundEvent(sound).setRegistryName(soundName);
    	}
    
    	@Mod.EventBusSubscriber
    	public static class Registration{
    		@SubscribeEvent
    		public static void registerSoundEvents(RegistryEvent.Register<SoundEvent> e){
    			
    			e.getRegistry().register(record1);
    		}
    	}
    
    }

     

    sounds.json

    {
      "record1": {
        "category": "record",
        "sounds": [
          {
            "name": "testsoundmod:record1",
            "stream": true
          }
        ]
      }
    }

     

    Any help would be appreciated.

    Thanks

     

  18. Ill add some context on what I'm trying to achieve.

     

    Im hoping to be able to allow a user to dump mainly sounds but possibly images into a file in the .minecraft directory which the mod will be able to read. The files then have the corresponding .json file created, so for custom sounds the sounds.json would be written by the mod, and since it is obviously impossible if not very unadvisable to try editing files within a bundled jar file I'm looking for ways to get around this.

     

    If there is a location i can create a resource pack based structure then have forge look in that domain instead of the jar resources or treat it as a resource pack and automatically load it that would be perfect.

     

    Thanks

×
×
  • Create New...

Important Information

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