Jump to content

[1.15.2] Toggle a block's BooleanProperty on onBlockActivated


Recommended Posts

Posted

Hello there, i'm a rather new at minecraft modding so sorry in advance if i'm missing any obvious solution.

 

So i'm trying to implement something really simple, with no real purpose, simply to wrap my head around the matter. I simply wanted to add a property to a block I made (a BooleanProperty)  and be able to toggle it's value by right-clicking the block.  It seems to be kinda doing what it is suppose to but the issue is as soon as the value of the property is switched, it gets instantly switched again back to it's previous value.  I thought that maybe it was due to the onBlockActivated function being called twice, on the client side and the server side, but the code to toggle the property is only ran if the world is remote and furthermore my logging clearly shows the code being executed only once.

I've also looked into the minecraft's LeverBlock class (for an instance of a value toggling process) and from what I could gather the code is rather similar.. The exception being the code not being mapped quite yet which might hide the solution for my problem:

   public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {
      if (worldIn.isRemote) {
         BlockState blockstate1 = state.cycle(POWERED);
         if (blockstate1.get(POWERED)) {
            addParticles(blockstate1, worldIn, pos, 1.0F);
         }

         return ActionResultType.SUCCESS;
      } else {
         BlockState blockstate = this.func_226939_d_(state, worldIn, pos);
         float f = blockstate.get(POWERED) ? 0.6F : 0.5F;
         worldIn.playSound((PlayerEntity)null, pos, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 0.3F, f);
         return ActionResultType.SUCCESS;
      }
   }

   public BlockState func_226939_d_(BlockState p_226939_1_, World p_226939_2_, BlockPos p_226939_3_) {
      p_226939_1_ = p_226939_1_.cycle(POWERED);
      p_226939_2_.setBlockState(p_226939_3_, p_226939_1_, 3);
      this.updateNeighbors(p_226939_1_, p_226939_2_, p_226939_3_);
      return p_226939_1_;
   }

 

I really don't know what else to do so if anyone could save me, I'd be very grateful !

 

Below is the full code of my block's class if needed:

 

package com.firebolt.justtolearnmod.objects.blocks;

import com.firebolt.justtolearnmod.JustToLearnMod;
import com.firebolt.justtolearnmod.init.ModTileEntityTypes;
import com.firebolt.justtolearnmod.tileentity.StorageUnitTileEntity;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.DirectionProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;

public class StorageUnitBlock extends Block {

	// Constructor
	public StorageUnitBlock(Properties properties) {
		super(properties);

		setDefaultState(this.getDefaultState().with(LOADED, false));
	}

	// Static Properties
	public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
	public static final BooleanProperty LOADED = BooleanProperty.create("loaded");

	// Methods
	@Override
	public BlockState getStateForPlacement(BlockItemUseContext context) {
		return this.getDefaultState().with(FACING, context.getPlacementHorizontalFacing().getOpposite());
	}

	@Override
	protected void fillStateContainer(Builder<Block, BlockState> builder) {
		builder.add(FACING, LOADED);
	}

	@Override
	public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {
		if (!worldIn.isRemote) {
			TileEntity tile = worldIn.getTileEntity(pos);

			if (tile instanceof StorageUnitTileEntity) {
				NetworkHooks.openGui((ServerPlayerEntity) player, (StorageUnitTileEntity) tile, pos);
				return ActionResultType.SUCCESS;
			}
		} else {
			BlockState blockstateCycled = state.cycle(LOADED);

			JustToLearnMod.LOGGER.debug("before: " + worldIn.getBlockState(pos).get(LOADED).toString());
			JustToLearnMod.LOGGER.debug("expected: " + blockstateCycled.get(LOADED).toString());

			worldIn.setBlockState(pos, blockstateCycled, 3);

			JustToLearnMod.LOGGER.debug("after: " + worldIn.getBlockState(pos).get(LOADED).toString());

			return ActionResultType.SUCCESS;
		}

		return ActionResultType.FAIL;
	}

	@Override
	public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
		if (state.getBlock() != newState.getBlock()) {
			TileEntity tile = worldIn.getTileEntity(pos);
			if (tile instanceof StorageUnitTileEntity) {
				InventoryHelper.dropItems(worldIn, pos, ((StorageUnitTileEntity) tile).getItems());
			}
		}
	}

	@Override
	public boolean hasTileEntity(BlockState state) {
		return true;
	}

	@Override
	public TileEntity createTileEntity(BlockState state, IBlockReader world) {
		return ModTileEntityTypes.STORAGE_UNIT.get().create();
	}
}

 

Posted
3 hours ago, firebolt said:

BlockState blockstateCycled = state.cycle(LOADED); JustToLearnMod.LOGGER.debug("before: " + worldIn.getBlockState(pos).get(LOADED).toString()); JustToLearnMod.LOGGER.debug("expected: " + blockstateCycled.get(LOADED).toString()); worldIn.setBlockState(pos, blockstateCycled, 3);

You are doing this on the logical client you cannot do that. Do it on the logical server IE !world.isRemote

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted

It did work (kinda), thanks a lot, however I now have another issue that I don't understand but probably has an easy fix that I don' know of: when right-clicking with a block in hand, the code is executed once which effectively toggles the property, but when right-clicking with an empty hand or any other item than a block the code is executed twice in a row which toggles the property twice resulting in no change whatsoever at the end...

I have a vague idea of why this might be happening but certainly no idea how to fix it. I would love to understand why this is acting this way, not just to solve my issue, but to get a better sense of modding basically.

 

Here's the code (just the part I changed). I also commented the gui part to avoid myself some trouble debugging.

	@Override
	public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {
		if (!worldIn.isRemote) {
//			TileEntity tile = worldIn.getTileEntity(pos);

			BlockState blockstateCycled = state.cycle(LOADED);

			JustToLearnMod.LOGGER.debug("before: " + worldIn.getBlockState(pos).get(LOADED).toString());
			JustToLearnMod.LOGGER.debug("expected: " + blockstateCycled.get(LOADED).toString());

			worldIn.setBlockState(pos, blockstateCycled, 3);

			JustToLearnMod.LOGGER.debug("after: " + worldIn.getBlockState(pos).get(LOADED).toString());
			
//			if (tile instanceof StorageUnitTileEntity) {
//				NetworkHooks.openGui((ServerPlayerEntity) player, (StorageUnitTileEntity) tile, pos);
//				return ActionResultType.SUCCESS;
//			}
		}

		return ActionResultType.FAIL;
	}

 

Posted
2 minutes ago, firebolt said:

code is executed twice in a row which toggles the property twice resulting in no change whatsoever at the end...

The Block::onBlockActivated method is called per logical side per hand. IE 2 sides 2 hands 2*2=4.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted (edited)

Yes, so that was the "vague idea" I had, but I'm not quite sure what that means. Why does it executes only once when holding a block then? Why doesn't it executes twice every time ? 

Edited by firebolt

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



×
×
  • Create New...

Important Information

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