Jump to content

[1.6.4]Problem with NBT, TEs and onItemUse


skullywag

Recommended Posts

Apologies for the vague title but couldnt fit it into one short sentence.

 

Simply I need to get at the nbt of a tile entity created when onItemUse does a setBlock:

 

public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
    {
        if (par7 != 1)
        {
            return false;
        }
        else if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) && par2EntityPlayer.canPlayerEdit(par4, par5 + 1, par6, par7, par1ItemStack))
        {
            int i1 = par3World.getBlockId(par4, par5, par6);
            Block soil = Block.blocksList[i1];

            if (soil != null && soil == Block.cobblestoneMossy && soil.canBlockStay(par3World, par4, par5, par6) && par3World.isAirBlock(par4, par5 + 1, par6))
            {
                par3World.setBlock(par4, par5 + 1, par6, this.blockType);                
                --par1ItemStack.stackSize;
                TileEntity te = par3World.getBlockTileEntity(par4, par5+1, par6);
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }

 

You can see where I grab the tile entity in the above code but that "te" doesnt let me "getEntityData" or anything else to get the tag. Is this possible and if not how do i transfer data about the item being used to the block/te it creates?

 

Am i again missing something plainly obvious.....(not having a good day for problem solving)

Link to comment
Share on other sites

The TileEntity is created automatically when the block is placed. There is no 'getEntityData' for TileEntity, but you can get the TE from the world and set class fields accordingly, which will then be saved/loaded if you wrote your TE correctly.

 

You're on the right track:

par3World.setBlock(par4, par5 + 1, par6, this.blockType);                
--par1ItemStack.stackSize;
TileEntity te = par3World.getBlockTileEntity(par4, par5+1, par6);
// you've got the tile entity, now just make sure it's yours and do whatever you want with it:
if (te instanceof YourTileEntityClass) {
YourTileEntityClass myTile = (YourTileEntityClass) te;
// now you can use your tile entity class methods:
myTile.setSomeField(someValue);
// now some field = some value, which will save and load with the tile entity
}
return true;

Link to comment
Share on other sites

Thanks guys, this was just a misunderstanding on my part of how I thought it worked (Java is not my main programming language in my day job), but a question does pop into my head after reading the above, granted I have access to the getter and setter for fields on the TE class so for this instance im good, but if i needed to how do i simply view whats currently in the NBT for the given entity, its something thats always bugged me and something ive not found anyone doing (probably because you wouldnt need it in the final code, debug only)

Link to comment
Share on other sites

No one ever does it because the NBT tag for tile entities is only used to store the data between quitting and restarting the world, unlike that for ItemStacks which is often modified and referenced during the course of the game. Once the tile entity loads, all the data should be stored in local fields, which you can print normally for debugging.

 

If you really want to see what is in the NBT tag, then put your debugging messages in the read / write NBT methods.

Link to comment
Share on other sites

ok its becoming clearer, let me set out what im doing:

 

I have 16 meta items on an item ID, they use the getColorFromItemStack to set a colour to their icon based on a list of colours in the class(16 of them). In the onItemUse method once some checks have been passed it does a setBlock and sets a field on the TileEntity for this block to its metaID, the TileEntityRenderer grabs the metaID from the TE and converts it into a set of RGB colour floats (im probably doing this rather heavily but it works for now) it then uses glColor4f to set the colour to the block/te model when rendered. This all works fine I get coloured renders in world.

 

The issue now is if i log off and back on, all my blocks are grey/white (the orginal texture colour before the gl pass), based on what youve said above should I be saving the colour in NBT as it will then survive past a restart. I that correct? and if so where is the best place to do the write to NBT. I have always set NBT like:

 

NBTTagCompound nbt= tileEntity.getTagCompound();	
nbt.setBoolean("something",(boolean)true);

 

the issue I face is that the above doesnt seem to be posible from anywhere in the classes ive set out above, now this may be (and probably is) down to me screwing something up.

 

Or am i finally going ot have to start working out the madness that is packets...

Link to comment
Share on other sites

If your block isn't using metadata for anything other than your rendering, why not just use the block's metadata value directly as stored in the world? world.setBlockMetatata(x, y, z, meta), then in your rendering class world.getBlockMetadata(x, y, z) done, you've got the index of the item responsible.

 

If that doesn't work for you for whatever reason, store the value as a field in the tile entity (making sure to save it in the tile entity's write / read NBT methods) and override the getDescriptionPacket method.

@Override
public void writeToNBT(NBTTagCompound compound) {
super.writeToNBT(compound);
compound.setInteger("key", value);
}

@Override
public void readFromNBT(NBTTagCompound compound) {
super.readFromNBT(compound);
yourField = compound.getInteger("key");
}

// now this will automatically synchronize your TileEntity from server to client:
@Override
public Packet getDescriptionPacket() {
NBTTagCompound tag = new NBTTagCompound();
this.writeToNBT(tag);
return new Packet132TileEntityData(xCoord, yCoord, zCoord, 1, tag);
}

// combined with this:
@Override
public void onDataPacket(INetworkManager net, Packet132TileEntityData packet) {
readFromNBT(packet.data);
}

From the sounds of it, you are simply missing the synchronization part.

Link to comment
Share on other sites

Thanks guys, this was just a misunderstanding on my part of how I thought it worked (Java is not my main programming language in my day job), but a question does pop into my head after reading the above, granted I have access to the getter and setter for fields on the TE class so for this instance im good, but if i needed to how do i simply view whats currently in the NBT for the given entity, its something thats always bugged me and something ive not found anyone doing (probably because you wouldnt need it in the final code, debug only)

There is a simple way to read the NBT tags from any tileentity, have an example:

 

NBTTagCompound tags = new NBTTagCompound();
tileentity.writeToNBT(tags);
System.out.println(tags);//debug here

 

You can also use readFromNBT to actually change some data within the tileentity, but it isn't recommended.

Link to comment
Share on other sites

You can also use readFromNBT to actually change some data within the tileentity, but it isn't recommended.

 

I use that feature to put custom values into a mob spawner placed during world gen, so that it will spawn a custom mob and at a much lower rate than the default.

http://www.minecraftforge.net/wiki/Mob_Spawners

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Thanks everyone, not only is it working perfectly now, but due to me now understanding how this all works now i tidied lots of code up and feel a lot happier about this.

 

The block that is set uses 5 metas to render different stages of its model (it "grows" on update) so had to transfer the nbt "colour" to the new TE on update so it didnt lose its colour when it set the next block meta. other than that turns out this was pretty darnd simple.

 

My only issue now is my models....techne seems to not like rotating things the right way, looks fine in techne, looks totally wrong in game. Dont suppose anyone knows why this is, seems to be an issue with the middleslider, I did find a post for help by who i can only assume is the maintainer of it:

 

http://answers.unity3d.com/questions/375526/techne-y-rotation-bug-minecraft-modeling-program.html

 

think this is the issue im having. Wonder if techne will ever get completed.

Link to comment
Share on other sites

My only issue now is my models....techne seems to not like rotating things the right way, looks fine in techne, looks totally wrong in game. Dont suppose anyone knows why this is, seems to be an issue with the middleslider, I did find a post for help by who i can only assume is the maintainer of it

 

Probably has to do with the fact that Euler angles suck and quaternions are better.

 

There is probably not anything you can do.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

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

    • The error still remains. For additional information, I can send you some more code,  main class Afraid.java:  package org.mymod.afraid; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.monster.Zombie; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.EntityAttributeCreationEvent; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegistryObject; @Mod("afraid") public class Afraid { public static final String MODID = "afraid"; public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, MODID); public static final RegistryObject<EntityType<AfraidBoss>> AFRAID_BOSS = ENTITY_TYPES.register("afraid_boss", () -> EntityType.Builder.of(AfraidBoss::new, MobCategory.MONSTER) .sized(0.6F, 1.95F) // Size of the entity .build(new ResourceLocation(MODID, "afraid_boss").toString())); public Afraid() { IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); ENTITY_TYPES.register(modEventBus); modEventBus.addListener(this::commonSetup); MinecraftForge.EVENT_BUS.register(this); } private void commonSetup(final FMLCommonSetupEvent event) { // Additional common setup if needed } @Mod.EventBusSubscriber(modid = MODID, bus = Mod.EventBusSubscriber.Bus.MOD) public static class ModEvents { @SubscribeEvent public static void onRegisterAttributes(EntityAttributeCreationEvent event) { event.put(Afraid.AFRAID_BOSS.get(), AfraidBoss.createAttributes().build()); } } } EntityEvents.java:  package org.mymod.afraid; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegistryObject; public class EntityEvents { public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, Afraid.MODID); public static final RegistryObject<EntityType<AfraidBoss>> AFRAID_BOSS = ENTITY_TYPES.register("afraid_boss", () -> EntityType.Builder.of(AfraidBoss::new, MobCategory.MONSTER) .sized(0.6F, 1.95F) .build("afraid_boss")); } As for attributes, they are only in the boss class itself.
    • Hello, new coder and first time posting, sorry if I get stuff wrong Been having a really difficult time trying to figure out this potion effect. I want to give a potion effect that denies the wither effect on the player. I've looked over a lot of different tutorials, and through some other mods and made something that sort of works but it was based on applyEffectTick and the players would still take a tick of damage before the potion effect kicked in. When looking up other ways to do this I saw there was like the PotionEvent but whenever I try to use it, I get errors of how it cannot be defined. This is my code right now that doesn't work package io.github.AndroPups.tsmp_models.effect; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.LivingEntity; public class NoWitherEffect extends MobEffect { public NoWitherEffect(MobEffectCategory mobEffectCategory, int color) { super(mobEffectCategory.BENEFICIAL, color); } public static void onPotionAdded(PotionEvent.PotionAddedEvent event) { LivingEntity entity = event.getEntityLiving(); MobEffect potionEffect = event.getPotionEffect().getEffect(); if (potionEffect == MobEffects.WITHER); { entity.removeEffect(MobEffects.WITHER); } } @Override public boolean isDurationEffectTick(int duration, int amplifier) { return true; } } And this code works but occasionally still applies damage because of ticking effect.   package io.github.AndroPups.tsmp_models.effect; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.LivingEntity; public class NoWitherEffect extends MobEffect { public NoWitherEffect(MobEffectCategory mobEffectCategory, int color) { super(mobEffectCategory.BENEFICIAL, color); } @Override public void applyEffectTick(LivingEntity pLivingEntity, int pAmplifier) { if (!pLivingEntity.level().isClientSide()) { if (pLivingEntity.hasEffect(MobEffects.WITHER)); { pLivingEntity.getEffect(MobEffects.WITHER); } } } @Override public boolean isDurationEffectTick(int duration, int amplifier) { return true; } } I've tried to see if PotionEvent was removed from recent Forge updates but can't really find any information on it. Any information at all would be helpful! Thanks!
    • Right after "private final Item item;" you will need "private final float chance;" Then you will need to add that variable to your constructor the same way you did for Item. It should work after that.
    • I am playing on Mac, tried to install a mod to the Forge mod folder, restarted Minecraft to activate it and now the game is crashing on launch with error code 1. Because I'm on Mac, I can't remotely access the mods folder without having to get into the Minecraft title screen to click the mods tab. Is there any way I can extract the file remotely, or is there a way to uninstall Forge so I can reinstall it with no mods?
  • Topics

×
×
  • Create New...

Important Information

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