-
Posts
84 -
Joined
-
Last visited
Posts posted by TheMCJavaFre4k
-
-
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.
-
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:
Spoilerpublic 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:
Spoilerpublic 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.
-
7 hours ago, Draco18s said:
Option (b) use an ITickableSound in order for it to terminate itself when its source block is removed.
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!
-
1 minute ago, Cadiboo said:
probably an int, not an Integer
Indeed, probably should have worded it with int so to not confuse it with the class.
-
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 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?
-
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.
-
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.
-
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.
- 1
-
44 minutes ago, diesieben07 said:
registerMessage must be called on both sides.
Thanks heaps for the reply, that would be the issue. Its now working as intended.
-
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:
Spoilerimport 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:
Spoilerpackage 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:
SpoilerSystem.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.
-
2 hours ago, TyrellPlayz said:
Here's my code. Link
The item in question in it is ItemWallet. That has a container
Thanks so much for sharing that. I added the INBTInventory implementation to handle the NBT tags and everything is working perfectly now.
Couldn't thank you enough!
- 1
-
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.
-
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.
-
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.
-
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);
-
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.
-
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.
-
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
-
Thanks for mentioning IResourcePack.
Was able to use a FolderResourcePack and everything Is working as supposed to.
Thanks again
-
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
-
Would forge be able to load and apply a resource pack internally without the user having to select it manually in the menu?
-
Hi There
I would like to be able to load sounds and the sounds.json from another folder within the .minecraft folder so they can be easily changed even when the mod has been bundled into a jar.
Is this something that is possible with Forge and if so where would be a good starting point?
Thanks
-
I believe i have it all working now, thanks everyone for there help.
[1.12.2]Custom painting not rendering
in Modder Support
Posted
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.