Résolu SetBlockState qui ne fonctionne pas (opération binaires sur la metadata)
-
Bonjour,
Alors j’ai un block avec plusieurs variantes et orientable (verticalement), quand je le pose, avec un variante en particulier, un autre block est posé, j’ai mis des print dans la fonction “onBlockPlacedBy” et je trouve ça un peu bizarre…@Override public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { EnumFacing face = WorldUtil.getVerticalFacingFromEntity(placer, pos); Energy.log.info("Before : " + worldIn.getBlockState(pos) + " ; Given by function : " + state); worldIn.setBlockState(pos, state.withProperty(onGround, Boolean.valueOf(face.equals(EnumFacing.DOWN))), 3); Energy.log.info("State added in world : " + state.withProperty(onGround, Boolean.valueOf(face.equals(EnumFacing.DOWN)))); Energy.log.info("Current state in world : " + worldIn.getBlockState(pos)); try { TileEntityEntityDetector te = (TileEntityEntityDetector) worldIn.getTileEntity(pos); if(placer instanceof EntityPlayer) te.setOwner((EntityPlayer) placer); } catch (Exception e) { //Je ne veux pas que ça crash (comme c'est pas le bon block, pas le bon tile entity...) } }
Et voici les logs qui vont avec :
[22:33:18] [Server thread/INFO] [Energy/]: Before : energy:EntityDetector[detectionRange=range_5,killMods=false,onGround=false] ; Given by function : energy:EntityDetector[detectionRange=range_5,killMods=false,onGround=false] Les states avant que l'on change quelque chose [22:33:18] [Server thread/INFO] [Energy/]: State added in world : energy:EntityDetector[detectionRange=range_5,killMods=false,onGround=true] //Le state donné à setBlockState [22:33:18] [Server thread/INFO] [Energy/]: Current state in world : energy:Computer[facing=south] //Après l'ajout dans le world obtenu avec getBlockState
C’est un peu bizarre…
-
Donc en gros quand tu poses le bloc il se transforme en energy:Computer ?!?
-
C’est très bizarre … Une solution serais peut-être de passer directement par onBlockPlaced.
-
@Robin oui
@max ah oui ouais j’essaye demainEnvoyé de mon RAINBOW LITE 4G en utilisant Tapatalk
-
Si tu remplaces :
worldIn.setBlockState(pos, state.withProperty(onGround, Boolean.valueOf(face.equals(EnumFacing.DOWN))), 3);
par :
worldIn.setBlockState(pos, ClassePrincipale.tonBlock.getDefaultBlockState().withProperty(onGround, Boolean.valueOf(face.equals(EnumFacing.DOWN))), 3);
ça fonctionne ? -
Je vois ce soir chez moiEDIT : alors les deux solutions proposées ne changent rien, mais j’ai l’impression que c’est un problème de block state id.
J’ai retiré le block (le computer) qui est posé à la place du bon (l’entity detector) du registry et quand je réessaye de poser le block, je fais un clic dans le vide, il y a l’animation mais aucun block est posé. Puis, j’ai créé une autre map, et cette fois-ci, le block est bien posé mais la propriété “onGround” n’est pas appliquée (je set un block avec “onGround” = true et quand je fais world.getBlockState, la valeur “onGround” est à false.
J’ai regardé les block state ids (Block.BLOCKS_STATES_IDS) du state avec “onGround” = false et celui avec “onGround” = true, et il se trouve qu’ils sont le même id, donc je pense que ça vient de là comme mc les considères identiques, si quelqu’un sait comment résoudre ça… Je regarderais demain les blocks states ids du mauvais block qui est posé à la place de l’entity detector pour voir si ils ne seraient pas identiques pas hasard… -
Up please
-
Tu peux envoyer le code de ton bloc ?
-
Voici :
package net.mystical.energy.blocks; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.properties.PropertyEnum; import net.minecraft.block.state.BlockState; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.util.IStringSerializable; import net.minecraft.util.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.mystical.energy.mod.Energy; import net.mystical.energy.registry.BlocksRegistry; import net.mystical.energy.tileentity.TileEntityEntityDetector; import net.mystical.energy.world.WorldUtil; public class BlockEntityDetector extends BlockBaseContainer { private static Map <string, integer="">elements = new HashMap(); public static final PropertyEnum detectionRange = PropertyEnum.create("detectionRange", EnumDetectorRange.class); public static final PropertyBool onGround = PropertyBool.create("onGround"); public static final PropertyBool killMobs = PropertyBool.create("killMods"); public BlockEntityDetector() { super(Material.glass); this.setDefaultState(this.getDefaultState().withProperty(detectionRange, BlockEntityDetector.EnumDetectorRange.RANGE_5).withProperty(onGround, Boolean.valueOf(false)).withProperty(killMobs, Boolean.valueOf(false))); } @Override public void setBlockBoundsBasedOnState(IBlockAccess world, BlockPos pos) { IBlockState state = world.getBlockState(pos); if(state.getValue(onGround)) { this.setBlockBounds(0.25F, 0F, 0.25F, 0.75F, 0.15F, 0.75F); } else { this.setBlockBounds(0.25F, 0.85F, 0.25F, 0.75F, 1F, 0.75F); } } @Override public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { Energy.log.info("Current state in world before : " + worldIn.getBlockState(pos)); EnumFacing face = WorldUtil.getVerticalFacingFromEntity(placer, pos); IBlockState state = this.getStateFromMeta(meta).withProperty(onGround, Boolean.valueOf(face.equals(EnumFacing.DOWN))); Energy.log.info("Giving : " + state + " ; from meta " + meta + " and face : " + face); return state; //return super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer); } @Override public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { Energy.log.info("Before : " + worldIn.getBlockState(pos) + " ; Given by function : " + state); //EnumFacing face = WorldUtil.getVerticalFacingFromEntity(placer, pos); //worldIn.setBlockState(pos, BlocksRegistry.entityDetector.getDefaultState().withProperty(onGround, Boolean.valueOf(face.equals(EnumFacing.DOWN))), 3); Energy.log.info("Current state in world : " + worldIn.getBlockState(pos)); try { TileEntityEntityDetector te = (TileEntityEntityDetector) worldIn.getTileEntity(pos); if(placer instanceof EntityPlayer) te.setOwner((EntityPlayer) placer); } catch (Exception e) { //Je ne veux pas que ça crash (comme c'est un autre block } } @Override public boolean isFullCube() { return false; } @Override public boolean isOpaqueCube() { return false; } @Override public boolean canProvidePower() { return true; } @Override public int getStrongPower(IBlockAccess worldIn, BlockPos pos, IBlockState state, EnumFacing side) { TileEntity te = worldIn.getTileEntity(pos); if(te instanceof TileEntityEntityDetector) return ((TileEntityEntityDetector)te).isDetectingEntity() ? 15 : 0; return 0; } @Override public int getWeakPower(IBlockAccess worldIn, BlockPos pos, IBlockState state, EnumFacing side) { TileEntity te = worldIn.getTileEntity(pos); if(te instanceof TileEntityEntityDetector) return ((TileEntityEntityDetector)te).isDetectingEntity() ? 15 : 0; return 0; } @Override public TileEntity createNewTileEntity(World world, int meta) { return new TileEntityEntityDetector(); } @Override public int damageDropped(IBlockState state) { return this.getMetaFromState(state); } @SideOnly(Side.CLIENT) @Override public void getSubBlocks(Item itemIn, CreativeTabs tab, List list) { Iterator it = elements.values().iterator(); int meta; int metaKillMobs; while(it.hasNext()) { meta = (Integer) it.next(); list.add(new ItemStack(itemIn, 1, meta)); metaKillMobs = meta | 8; list.add(new ItemStack(itemIn, 1, metaKillMobs)); } } @Override public IBlockState getStateFromMeta(int meta) { boolean killMobs = (meta & 8) != 0; boolean onGround = (meta & 16) != 0; IBlockState st = BlocksRegistry.entityDetector.getDefaultState().withProperty(detectionRange, EnumDetectorRange.byMetadata(meta)).withProperty(this.killMobs, Boolean.valueOf(killMobs)).withProperty(this.onGround, Boolean.valueOf(onGround)); //Energy.log.info("Given state : " + st + " from meta : " + meta + " ; " + killMobs + " ; " + onGround + " ; " + EnumDetectorRange.byMetadata(meta)); //Energy.log.info("Corresponding id : " + Block.BLOCK_STATE_IDS.get(st)); return st; } @Override public int getMetaFromState(IBlockState state) { int meta = 0 | ((EnumDetectorRange)state.getValue(detectionRange)).getMetadata(); boolean killMobs = state.getValue(this.killMobs); boolean onGround = state.getValue(this.onGround); if(killMobs) { meta |= 8; } if(onGround) { meta |= 16; } //Energy.log.info("Given meta : " + meta + " from state : " + state + " ; " + killMobs + " ; " + onGround + " ; " + ((EnumDetectorRange)state.getValue(detectionRange)).getMetadata()); //Energy.log.info("Corresponding id : " + Block.BLOCK_STATE_IDS.get(state)); return meta; } @Override public String getItemVariantNameFromMeta(int meta) //Une fonction de mon cru pour l'enregistrement des rendus { String str = EnumDetectorRange.byMetadata(meta).getName(); if(Boolean.valueOf((meta & 8) != 0)) { str += "_killMobs"; } return str; } @Override protected BlockState createBlockState() { return new BlockState(this, new IProperty[] {detectionRange, onGround, killMobs}); } public enum EnumDetectorRange implements IStringSerializable { //Maximum metadata : 7 (on 3bits), others bits are for other properties RANGE_5(0, 5, "range_5"); private static final EnumDetectorRange[] META_LOOKUP = new EnumDetectorRange[values().length]; private final int meta; private final int range; private final String name; private EnumDetectorRange(int meta, int range, String name) { this.meta = meta; this.range = range; this.name = name; BlockEntityDetector.elements.put(name, meta); } public int getMetadata() { return this.meta; } public int getRange() { return this.range; } public static EnumDetectorRange byMetadata(int meta) { return META_LOOKUP[MathHelper.abs_int(meta % META_LOOKUP.length)]; } @Override public String toString() { return this.name; } @Override public String getName() { return this.name; } static { EnumDetectorRange[] var0 = values(); int var1 = var0.length; for (int var2 = 0; var2 < var1; ++var2) { EnumDetectorRange var3 = var0[var2]; META_LOOKUP[var3.getMetadata()] = var3; } } } }
Regarde les opérations binaires pour la metadata, c’est peut-être à cause de ça (première fois que je l’utilise).</string,>
-
Oula en effet ça ne me semble pas du tout bon.
Ton bloc est sensé avoir combien d’état différent possible ? -
Pour le binaire ? Je me suis inspiré d’un block vanilla et d’un tuto, mais j’ai pas tout compris (et bien appliqué je pense).
Pour l’instant il peut avoir 4 états mais je compte rajouter différentes portées. -
http://gfx.developpez.com/tutoriel/java/binaire/#L3
Ceci devrait t’aider. -
Merci je lis ça
EDIT : Après avoir lus le tuto et refais le code, j’ai n’ai plus de problème, c’était donc bien les blockstates que Minecraft confondait à cause de mon code.