Jump to content

Recommended Posts

Posted

I have created a simple item tool, that works like a hoe with some extra features. Everything works perfect, but the problem is that even when it till the dirt, it doesn't play the sound that the hoes do.

 

Is there anything I should consider when calling a vanilla sound from inside my mod, or it's just something that can't be done?

 

    public void tillDirt(ItemStack stack, EntityPlayer player, World world, BlockPos pos, IBlockState state)
    {
        world.playSound(player, pos, SoundEvents.item_hoe_till, SoundCategory.BLOCKS, 1.0F, 1.0F);

        if (!world.isRemote)
        {
            world.setBlockState(pos, state, 11);
            stack.damageItem(1, player);
        }
    }

Posted

World#playSound plays a sound only when called on the client side (i.e. when the world IS remote). My guess is that your method is only getting called on the server.

 

Is #tillDirt your own method, or inherited from Item and/or ItemTool? If it's your own method, show the code that calls it. If it's a vanilla method, are you sure it is called on both the client and the server side?

 

If you haven't already, take a closer look at the hoe to see how and where it plays its sound.

Posted

I guess that is the problem. This is the code, I know it can be improved to make it compatible with crops other than the vanilla one, but as for now I kinda "hardcoded" how it works, gonna improve it on future updates.

 

	@Override
@SuppressWarnings("incomplete-switch")
public EnumActionResult onItemUse(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
	if(!world.isRemote)
	{

		//HOE
        if (!player.canPlayerEdit(pos.offset(facing), facing, stack))
        {
            return EnumActionResult.FAIL;
        }
        else
        {
            int hook = net.minecraftforge.event.ForgeEventFactory.onHoeUse(stack, player, world, pos);
            if (hook != 0) return hook > 0 ? EnumActionResult.SUCCESS : EnumActionResult.FAIL;

            IBlockState iblockstate = world.getBlockState(pos);
            Block block = iblockstate.getBlock();

            if (facing != EnumFacing.DOWN && world.isAirBlock(pos.up()))
            {
                if (block == Blocks.grass || block == Blocks.grass_path)
                {
                    this.tillDirt(stack, player, world, pos, Blocks.farmland.getDefaultState());
                    return EnumActionResult.SUCCESS;
                }

                if (block == Blocks.dirt)
                {
                    switch ((BlockDirt.DirtType)iblockstate.getValue(BlockDirt.VARIANT))
                    {
                        case DIRT:
                            this.tillDirt(stack, player, world, pos, Blocks.farmland.getDefaultState());
                            return EnumActionResult.SUCCESS;
                        case COARSE_DIRT:
                            this.tillDirt(stack, player, world, pos, Blocks.dirt.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.DIRT));
                            return EnumActionResult.SUCCESS;
                    }
                }
            }

            
        }


		//DONGLE
		IBlockState checkBlockState = world.getBlockState(pos);
		Block checkBlock = checkBlockState.getBlock();

		if(checkBlock!=null)
		{
			if(checkBlock instanceof BlockCarrot)
			{


				int meta = checkBlock.getMetaFromState(checkBlockState);



				if(meta == 7) {

					world.setBlockState(pos, checkBlockState.withProperty(AGE, Integer.valueOf(0)), 3);

					final int reward = (int) ((Math.random() * 3)+1);

					dropX = new ItemStack(Items.carrot,reward,0);
					flag = true;

				}


			}//END CARROT

			if(checkBlock instanceof BlockPotato)
			{
//					System.out.println("It's a potato!");

				int meta = checkBlock.getMetaFromState(checkBlockState);

//					System.out.println("Meta: " + meta);

				if(meta == 7) {

					world.setBlockState(pos, checkBlockState.withProperty(AGE, Integer.valueOf(0)), 3);

					final int reward = (int) ((Math.random() * 3)+1);

					dropX = new ItemStack(Items.potato,reward,0);
					flag = true;

					dropX2 = new ItemStack(Items.poisonous_potato,1,0);
					flag2 = true;

				}


			}//END POTATO

			if(checkBlock instanceof BlockCrops && !(checkBlock instanceof BlockCarrot) && !(checkBlock instanceof BlockPotato) && !(checkBlock instanceof BlockBeetroot))
			{
//					System.out.println("It's wheat!");

				int meta = checkBlock.getMetaFromState(checkBlockState);

//					System.out.println("Meta: " + meta);

				if(meta == 7) {

					world.setBlockState(pos, checkBlockState.withProperty(AGE, Integer.valueOf(0)), 3);

					dropX = new ItemStack(Items.wheat,1,0);
					flag = true;

					dropX3 = new ItemStack(Items.wheat_seeds,1,0);
					flag3 = true;

				}


			}//END WHEAT

			if(checkBlock instanceof BlockBeetroot)
			{
//					System.out.println("It's a beetroot!");

				int meta = checkBlock.getMetaFromState(checkBlockState);

//					System.out.println("Meta: " + meta);

				if(meta == 3) {

					world.setBlockState(pos, checkBlockState.withProperty(BEETROOT_AGE, Integer.valueOf(0)), 3);

					dropX = new ItemStack(Items.beetroot,1,0);
					flag = true;

					dropX3 = new ItemStack(Items.beetroot_seeds,1,0);
					flag3 = true;

				}


			}//END BEETROOT




			if (flag) {
			itemDropX = new EntityItem(world, pos.getX()+.5, pos.getY()+.5, pos.getZ()+.5, dropX);
		   	world.spawnEntityInWorld(itemDropX);
		   	stack.damageItem(1, player);
		   	flag = false;
			}

			if (flag2) {
				int rand = (int) (Math.random() * 10);
				if (rand<1){
				itemDropX2 = new EntityItem(world, pos.getX()+.5, pos.getY()+.5, pos.getZ()+.5, dropX2);
			   	world.spawnEntityInWorld(itemDropX2);
				}
			flag2 = false;
			}

			if (flag3) {
				int rand = (int) (Math.random() * 4);
				if (rand<1){
				itemDropX3 = new EntityItem(world, pos.getX()+.5, pos.getY()+.5, pos.getZ()+.5, dropX3);
			   	world.spawnEntityInWorld(itemDropX3);
				}
			flag3 = false;
			}

		}


	}


        return EnumActionResult.PASS;
    }

 

I guess I should remove that first if(!world.isRemote) I always have problems on knowing when or not to use it...

Thanks for the answer.

 

PS: tillDirt is the same code that is on the hoes from Minecraft, just with a readable name.

 

Posted

As you read more vanilla code, you will see cases of when and when not to use !world.isRemote. Generally, you use it to encapsulate code that changes the world or things within the world, such as modifying a block state, giving a player an item, or spawning an entity. You only need to encapsulate the actual changing code, not necessarily everything around it, though sometimes that is useful to avoid wasting processing power on the client.

 

Anyway, if you model your item after the hoe, then mimic their #onItemUse implementation more closely as I doubt they encapsulate the entire thing in an if (!world.isRemote) statement.

Posted

Thanks coolAlias, yes I just removed it from there, and only use it now surrounding when I drop the items on the floor and when I set the state of the crop back to age 0.

 

Now it looks like this :D

	@Override
@SuppressWarnings("incomplete-switch")
public EnumActionResult onItemUse(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
		//HOE
        if (!player.canPlayerEdit(pos.offset(facing), facing, stack))
        {
            return EnumActionResult.FAIL;
        }
        else
        {
            int hook = net.minecraftforge.event.ForgeEventFactory.onHoeUse(stack, player, world, pos);
            if (hook != 0) return hook > 0 ? EnumActionResult.SUCCESS : EnumActionResult.FAIL;

            IBlockState iblockstate = world.getBlockState(pos);
            Block block = iblockstate.getBlock();

            if (facing != EnumFacing.DOWN && world.isAirBlock(pos.up()))
            {
                if (block == Blocks.grass || block == Blocks.grass_path)
                {
                    this.tillDirt(stack, player, world, pos, Blocks.farmland.getDefaultState());
                    return EnumActionResult.SUCCESS;
                }

                if (block == Blocks.dirt)
                {
                    switch ((BlockDirt.DirtType)iblockstate.getValue(BlockDirt.VARIANT))
                    {
                        case DIRT:
                            this.tillDirt(stack, player, world, pos, Blocks.farmland.getDefaultState());
                            return EnumActionResult.SUCCESS;
                        case COARSE_DIRT:
                            this.tillDirt(stack, player, world, pos, Blocks.dirt.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.DIRT));
                            return EnumActionResult.SUCCESS;
                    }
                }
            }

            
        }


		//DONGLE
		IBlockState checkBlockState = world.getBlockState(pos);
		Block checkBlock = checkBlockState.getBlock();

		if(checkBlock!=null)
		{
			if(checkBlock instanceof BlockCarrot)
			{
				int meta = checkBlock.getMetaFromState(checkBlockState);
				if(meta == 7) {
					if (!world.isRemote)
			        {
					world.setBlockState(pos, checkBlockState.withProperty(AGE, Integer.valueOf(0)), 3);
			        }
					final int reward = (int) ((Math.random() * 3)+1);
					dropX = new ItemStack(Items.carrot,reward,0);
					flag = true;
				}

			}//END CARROT

			if(checkBlock instanceof BlockPotato)
			{
				int meta = checkBlock.getMetaFromState(checkBlockState);
				if(meta == 7) {
					if (!world.isRemote)
			        {						
					world.setBlockState(pos, checkBlockState.withProperty(AGE, Integer.valueOf(0)), 3);
			        }
					final int reward = (int) ((Math.random() * 3)+1);
					dropX = new ItemStack(Items.potato,reward,0);
					flag = true;

					dropX2 = new ItemStack(Items.poisonous_potato,1,0);
					flag2 = true;
				}

			}//END POTATO

			if(checkBlock instanceof BlockCrops && !(checkBlock instanceof BlockCarrot) && !(checkBlock instanceof BlockPotato) && !(checkBlock instanceof BlockBeetroot))
			{
				int meta = checkBlock.getMetaFromState(checkBlockState);
				if(meta == 7) {
					if (!world.isRemote)
			        {						
					world.setBlockState(pos, checkBlockState.withProperty(AGE, Integer.valueOf(0)), 3);
			        }
					dropX = new ItemStack(Items.wheat,1,0);
					flag = true;

					dropX3 = new ItemStack(Items.wheat_seeds,1,0);
					flag3 = true;

				}

			}//END WHEAT

			if(checkBlock instanceof BlockBeetroot)
			{
				int meta = checkBlock.getMetaFromState(checkBlockState);
				if(meta == 3) {
					if (!world.isRemote)
			        {						
					world.setBlockState(pos, checkBlockState.withProperty(BEETROOT_AGE, Integer.valueOf(0)), 3);
			        }
					dropX = new ItemStack(Items.beetroot,1,0);
					flag = true;

					dropX3 = new ItemStack(Items.beetroot_seeds,1,0);
					flag3 = true;
				}

			}//END BEETROOT

			if (flag) {
				if (!world.isRemote)
		        {
			itemDropX = new EntityItem(world, pos.getX()+.5, pos.getY()+.5, pos.getZ()+.5, dropX);
		   	world.spawnEntityInWorld(itemDropX);
		   	stack.damageItem(1, player);
		   	flag = false;
		        }
			}

			if (flag2) {
				if (!world.isRemote)
		        {
				int rand = (int) (Math.random() * 10);
				if (rand<1){
				itemDropX2 = new EntityItem(world, pos.getX()+.5, pos.getY()+.5, pos.getZ()+.5, dropX2);
			   	world.spawnEntityInWorld(itemDropX2);
				}
			flag2 = false;
		        }
			}

			if (flag3) {
				if (!world.isRemote)
		        {
				int rand = (int) (Math.random() * 4);
				if (rand<1){
				itemDropX3 = new EntityItem(world, pos.getX()+.5, pos.getY()+.5, pos.getZ()+.5, dropX3);
			   	world.spawnEntityInWorld(itemDropX3);
				}
			flag3 = false;
		        }
			}

		}





        return EnumActionResult.PASS;
    }

 

Next step will actually be getting the drops and not "emulating" them, I think that's a better way to code this tool, but I got confused when trying that, but for sure will try again on the near future, so at some point I may come again to ask some doubts I have on how to achieve that, specially when apparently Beetroots makes things a little bit more complicate that wheats, carrots and potatoes.

 

Thanks once again for the help ;)

Posted

Counter-intuitively, vanilla Minecraft initiates most of its sounds on the server. That's because it wants all (nearby) players to hear the sounds, not just the player performing an action. You'll see calls to World#playSoundEffect. If you trace it, you'll eventually see a packet sent to all clients (World-Accesses) whose players are within earshot. The actual sound is eventually played client-side (of course), but only in response to the packet.

 

Your code usually should not call those client-side methods used to render sound. Instead, your mod should almost always call the server-side sound-effect method and let vanilla handle the distribution to clients. An exception would be, for instance, if you set-up a tile entity to emit a continuous sound, or if you gave a helmet to one player to play sounds in response to objects in his environment.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Posted

@jeffryfisher Or if he doesn't want anyone nearby to hear and figure out that he's using a hoe, which is what I assumed* :P

 

* given that he was wanting to play the sound on the client, but perhaps that was the only way he found? or is that how vanilla tools or just the hoes behave? I don't have an IDE to check right now, but I kinda think that tool sounds are client only - do you actually hear other players chopping and mining? Not that I recall, but it's been ages since I've played.

Posted

Yes, other players' chopping and picking and running etc makes noise that will play for you and all other nearby players. Tools initiate sound effects on the server that are eventually rendered on clients, with each client's rendition attenuated for distance (IIRC, zero-volume sfx are dropped before packets are sent).

 

Therefore, one should normally call the playSoundEffect method. It does its own server-side / client-side check, only doing something on the server (causing packets to be sent).

 

Counter-intuitively, this means that if you call playSoundEffect from inside a client-only method (such as inside a client-proxy), then it won't do diddly. You need to make sure that your call is executing on the server.

 

This actually makes some sense when you figure that the server is the authority on what really happens in the world. The server is also (by definition) responsible for distributing info to multiple players.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I need to know what mod is doing this crash, i mean the mod xenon is doing the crash but i want to know who mod is incompatible with xenon, but please i need to know a solution if i need to replace xenon, i cant use optifine anymore and all the other mods i tried(sodium, lithium, vulkan, etc) doesn't work, it crash the game.
    • I have been trying to solve a consistent crashing issue on my brother's computer where it will crash during the "Scanning Mod Candidates" phase of the loading process that starts when you click the play button on the Minecraft launcher. The issue seems to stem from a missing library that it mentions in the log file I provide below. I might I'm missing the bigger issue here for a smaller one but hopefully someone can find what I'm missing. Here's all of the stuff that I've been able to figure out so far: 1. It has nothing to do with mods, the crash happened with a real modpack, and even when I made a custom modpack and launched it without putting ANY mods into it (That is where the log file comes from by the way). 2. I have tried to find this class like a file in the Minecraft folders, but I've had no luck finding it (I don't think it works like that, but since I really don't understand how it works, I just figured I'd try). 3. I haven't seen anyone else have this issue before. 4. I know that my modpack (with mods) does work since I've run it on my computer, and it works fantastic. For some reason my brother's computer can't seem to run anything through curseforge. 5. This is for Minecraft version 1.20.1, Minecraft launcher version 3.4.50-2.1.3, forge 47.3.0, and curseforge app version 1.256.0.21056 6. My brother is using a Dell laptop from 6 years ago running Windows 10 (If you think more info on this would help, please ask as I do have it. I'm just choosing not to put it here for now). 7. I have reinstalled the curseforge app and installed Minecraft version 1.20.1. I have not reinstalled Minecraft or forge 47.3.0 but I didn't know if that would help. 8. I had an error code of 1 Please let me know if there is anything else that I am missing that you would like me to add to this post/add in a comment! Lastly, many thanks in advance to whoever can help! ------------- LOG FILE (latest.log) ------------- (from /Users/<NAME OF USER>/cursforge/minecraft/Instances/<THE NAME OF MY EMPTY MODPACK>/logs/latest.log) (This was made after running an empty modpack with same versions for all apps) ("[REDACTED]" is not the actual text from the log, it is me replacing text I figured wouldn't be necessary for fixing and would hurt my privacy) https://pastebin.com/hxXvGGEK ------------- DEBUG.LOG (I realized that I should have put this here first after I had done all of the work on putting latest.log in) -------------------- (again, "[REDACTED]" is not the actual text from the log, it is me replacing text I figured wouldn't be necessary for fixing and would hurt my privacy) https://pastebin.com/Fmh8GHYs
    • Pastebin... https://pastebin.com/Y3iZ85L5   Brand new profile, does not point to a mod as far as I can tell, my fatal message just has something about mixins. Don't know much about reading logs like this, but am genuinely stuck, please help. Java updated, pc restarted.
    • I was playing minecraft, forge 47.3.0 and 1.20.1, but when i tried to play minecraft now only crashes, i need help please. here is the crash report: https://securelogger.net/files/e6640a4f-9ed0-4acc-8d06-2e500c77aaaf.txt
  • Topics

×
×
  • Create New...

Important Information

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