Jump to content

Recommended Posts

Posted

Help, I created an Entity which summonable by right-clicking an item but when i spawn it, it dies instantly and i dont know why, this just happened after i added something and changed a part of the code, before it worked fine and the entity didn't died.

 

 

here the summon code in the item class:

 

  Reveal hidden contents

 

 

the entity:

 

  Reveal hidden contents

 

 

note no error, but it dies by his self. thanks for any help!

"My Crew is World Wide." 「ヤング • エルトウ」

Posted

EntityNikora entitynikora = new EntityNikora(world, player); 
player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.RED +"You de-summoned Nikora."));
entitynikora.spawnExplosionParticle();
entitynikora.setDead();

 

what exactly are you triing to do there

Posted
  On 2/3/2016 at 7:13 PM, Failender said:

EntityNikora entitynikora = new EntityNikora(world, player); 
player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.RED +"You de-summoned Nikora."));
entitynikora.spawnExplosionParticle();
entitynikora.setDead();

 

what exactly are you triing to do there

 

That part is commented out.

 

But back to topic.

 

Sure about getCurrentMana() is over manacost?

Not all things in the world are red, there are round objects too!

Posted
  On 2/3/2016 at 8:51 PM, DasKaktus said:

  Quote

EntityNikora entitynikora = new EntityNikora(world, player); 
player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.RED +"You de-summoned Nikora."));
entitynikora.spawnExplosionParticle();
entitynikora.setDead();

 

what exactly are you triing to do there

 

That part is commented out.

 

But back to topic.

 

Sure about getCurrentMana() is over manacost?

 

Yes im sure, when the current mana is lower than the manacost it will send a Chat Message and a System out print but it doesnt do.

 

"My Crew is World Wide." 「ヤング • エルトウ」

Posted

Tried to debug and breakpoint to trace where the entity dies?

 

By the way which difficulty level are you running the game in?

Not all things in the world are red, there are round objects too!

Posted

First, make sure you are not in peaceful mode.

 

Second:

if(props.getCurrentMana() >= manacost){
     		props.consumeMana(manacost);
     		tick = 0;
     	}
     	
     	if(props.getCurrentMana() < manacost){
     		player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.RED + "You have not enough Mana, your Celestial Spirit was desummoned."));
     		this.worldObj.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, this.posX, this.posY, this.posZ, 0, 0, 0, 0);
     		this.setDead();	
     	}

Let's follow that logic. I don't know your current mana at that point, but let's say you have 6 mana. You have manacost = 5.

 

-

if(props.getCurrentMana() >= manacost)

  Your current mana is 6, and manacost is 5, so that condition is true.

---

props.consumeMana(manacost)

  I suspect

consumeMana

is reducing your current mana with the manacost, leaving you with only 1 mana left.

-

if(props.getCurrentMana() < manacost)

  Your current mana is 1 at this point, and manacost is 5, so that is indeed less and that condition is true.

--- Kill the entity

 

Have you figured it out yet? If you don't have atleast 2*manacost when you start, the entity instantly dies because the second if-statement is true because you already removed the mana from the player. You have to add

else

to the second if-statement.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Posted
  On 2/3/2016 at 9:47 PM, larsgerrits said:

First, make sure you are not in peaceful mode.

 

Second:

if(props.getCurrentMana() >= manacost){
     		props.consumeMana(manacost);
     		tick = 0;
     	}
     	
     	if(props.getCurrentMana() < manacost){
     		player.addChatComponentMessage(new ChatComponentText(EnumChatFormatting.RED + "You have not enough Mana, your Celestial Spirit was desummoned."));
     		this.worldObj.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, this.posX, this.posY, this.posZ, 0, 0, 0, 0);
     		this.setDead();	
     	}

Let's follow that logic. I don't know your current mana at that point, but let's say you have 6 mana. You have manacost = 5.

 

-

if(props.getCurrentMana() >= manacost)

  Your current mana is 6, and manacost is 5, so that condition is true.

---

props.consumeMana(manacost)

  I suspect

consumeMana

is reducing your current mana with the manacost, leaving you with only 1 mana left.

-

if(props.getCurrentMana() < manacost)

  Your current mana is 1 at this point, and manacost is 5, so that is indeed less and that condition is true.

--- Kill the entity

 

Have you figured it out yet? If you don't have atleast 2*manacost when you start, the entity instantly dies because the second if-statement is true because you already removed the mana from the player. You have to add

else

to the second if-statement.

 

It seems logical what you mean but i found out that this two variables are the problem, i can fix that with replacing them at applyEntityAttributes with there value, but why i can't use them as variables?

 

private double spirit_damage = 2.0D;
private double spirit_health = 20D;

protected void applyEntityAttributes()
    {
        super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(spirit_health);}

 

The Entity is dying because the health is 0 seems logical, but i would like to know why i can't use this 2 variables that i created. thanks for any help!

"My Crew is World Wide." 「ヤング • エルトウ」

Posted

1. Read about how Java creates instances.

2. Notice that applyEntityAttributes() is called from super-constructor of your entity.

3. Think about what is happening and say: "Oh, shit, those 2 globals "spirit_damage" and "spirit_health" are not yet initialized! Therefore, generic data in java is set to default 0.0 for doubles!

4. Ahh... so that's why my entity dies!

EDIT

 

What you need:

Use "static" keyword to make it shared between all entities.

If you need different entities have different health you CANNOT use "SharedMonsterAttributes" - notice word "Shared".

To achieve different values (and make them sync automatically) for different you need to apply AttributeModifier to entity after it's been spawned.

  Quote

1.7.10 is no longer supported by forge, you are on your own.

Posted
  On 2/3/2016 at 10:58 PM, Ernio said:

1. Read about how Java creates instances.

2. Notice that applyEntityAttributes() is called from super-constructor of your entity.

3. Think about what is happening and say: "Oh, shit, those 2 globals "spirit_damage" and "spirit_health" are not yet initialized! Therefore, generic data in java is set to default 0.0 for doubles!

4. Ahh... so that's why my entity dies!

 

thanks!  ;D

"My Crew is World Wide." 「ヤング • エルトウ」

Posted
  On 2/3/2016 at 10:58 PM, Ernio said:

1. Read about how Java creates instances.

2. Notice that applyEntityAttributes() is called from super-constructor of your entity.

3. Think about what is happening and say: "Oh, shit, those 2 globals "spirit_damage" and "spirit_health" are not yet initialized! Therefore, generic data in java is set to default 0.0 for doubles!

4. Ahh... so that's why my entity dies!

EDIT

 

What you need:

Use "static" keyword to make it shared between all entities.

If you need different entities have different health you CANNOT use "SharedMonsterAttributes" - notice word "Shared".

To achieve different values (and make them sync automatically) for different you need to apply AttributeModifier to entity after it's been spawned.

 

Thanks Ernio you're the best, it works, thanks for your help! And thanks to you guys for helping me too.

"My Crew is World Wide." 「ヤング • エルトウ」

Posted

I have one last question, how can i get the summoned Entity that if i right-click again the item, the summoned Entity will disappear?

"My Crew is World Wide." 「ヤング • エルトウ」

Posted
  On 2/3/2016 at 11:23 PM, DasKaktus said:

Save a reference to the entity in the item when summoned?

 

i'll try.

"My Crew is World Wide." 「ヤング • エルトウ」

Posted

Should be noted:

If you don't know yet - Item is singleton, logically speaking "a description of what you are holding". The thing you are actually holding is ItemStack and only ItemStack can hold per-stack data. To save reference to entity in ItemStack you need to use entity.getUniqueId() which can then be saved in ItemStack's NBT as 2 longs (UUID#getMost/LeastSignificantBits()).

Then you can re-reference entity by getting it from saved UUID - World#getEntityById (or similar method, i don't remember).

Do note that entity might not be found (unloaded), might only be found on server (client is too far to see entity) or other expected or not behaviours - that all needs to be handled properly.

  Quote

1.7.10 is no longer supported by forge, you are on your own.

Posted

Or.. If im reading you right there could only be one summoned entity, then tell all entities that have the player as caster to disappear?

Not all things in the world are red, there are round objects too!

Posted
  On 2/3/2016 at 11:40 PM, Ernio said:

Should be noted:

If you don't know yet - Item is singleton, logically speaking "a description of what you are holding". The thing you are actually holding is ItemStack and only ItemStack can hold per-stack data. To save reference to entity in ItemStack you need to use entity.getUniqueId() which can then be saved in ItemStack's NBT as 2 longs (UUID#getMost/LeastSignificantBits()).

Then you can re-reference entity by getting it from saved UUID - World#getEntityById (or similar method, i don't remember).

Do note that entity might not be found (unloaded), might only be found on server (client is too far to see entity) or other expected or not behaviours - that all needs to be handled properly.

 

getEntityByID needs a Int but UUID is a String, so i can't use it.

is there any method to get a Entity by his UUID?

because there is just a method for player UUID, i changed the item class now its saving the UUID of the Entity but i can't do anything with the UUID, when there is no Method for it.

"My Crew is World Wide." 「ヤング • エルトウ」

Posted

Ah, I used bad naming, getEntityByID uses "network" IDs used to sync server and client entity data.

It's just that I have my own utilitiy method that does it for UUID (thus, my confusion).

 

Anyway:

World isntance has "loadedEntityList".

You need to make utility method that will take UUID and return Entity.

Then in that method you will iterate through all entities ("loadedEntityList") and check if entity.getUniqueId().equals(paramUUID), if so - return entity.

 

As one could expect - retrieving UUID from ItemStack's NBT, converting it from 2 longs to "new UUID(least, most)" and then comparing it to list of ALL entities (until found) MIGHT be a little overhead if not used with care - so if you'd ever use it in future to manage per-tick actions - try caching refernce at all cost (not quite possible with ItemStacks).

  Quote

1.7.10 is no longer supported by forge, you are on your own.

Posted
  On 2/4/2016 at 12:20 AM, diesieben07 said:

WorldServer has a method getEntityFromUuid.

 

yes, but the problem is, that the UUID that i save into the Item NBT-Tag, is a String, and getEntityFromUuid needs a UUID, so how can i check that?

"My Crew is World Wide." 「ヤング • エルトウ」

Posted
  On 2/4/2016 at 12:19 AM, Ernio said:

Ah, I used bad naming, getEntityByID uses "network" IDs used to sync server and client entity data.

It's just that I have my own utilitiy method that does it for UUID (thus, my confusion).

 

Anyway:

World isntance has "loadedEntityList".

You need to make utility method that will take UUID and return Entity.

Then in that method you will iterate through all entities ("loadedEntityList") and check if entity.getUniqueId().equals(paramUUID), if so - return entity.

 

As one could expect - retrieving UUID from ItemStack's NBT, converting it from 2 longs to "new UUID(least, most)" and then comparing it to list of ALL entities (until found) MIGHT be a little overhead if not used with care - so if you'd ever use it in future to manage per-tick actions - try caching refernce at all cost (not quite possible with ItemStacks).

 

i tried to make a method how you said but im getting errors could you give me an example how you did that?

"My Crew is World Wide." 「ヤング • エルトウ」

Posted

UUID#fromString and UUID#toString? Or, using long values instead:

// Writing to NBT:
compound.setLong("YourUUIDMost", uuid.getMostSignificantBits());
compound.setLong("YourUUIDLeast", uuid.getLeastSignificantBits());

// Recreating from NBT:
UUID uuid = new UUID(compound.getLong("YourUUIDMost"), compound.getLong("YourUUIDLeast"));

Posted
  On 2/4/2016 at 1:48 AM, coolAlias said:

UUID#fromString and UUID#toString? Or, using long values instead:

// Writing to NBT:
compound.setLong("YourUUIDMost", uuid.getMostSignificantBits());
compound.setLong("YourUUIDLeast", uuid.getLeastSignificantBits());

// Recreating from NBT:
UUID uuid = new UUID(compound.getLong("YourUUIDMost"), compound.getLong("YourUUIDLeast"));

 

i made an method to return the entity when the UUID is the same with the one that is saved to the NBT, but it seems that its not working it seems that the UUID is not the same with the saved UUID.

 

  Reveal hidden contents

 

 

This line isn't called, so it seems that the EntityUUID is not the same, could somebody tell me why?

System.out.println("NIKORA UUID CHECKED");

 

and here the getUUID method:

public static String getUUID(ItemStack stack){
    	NBTTagCompound nbtTagCompound = stack.getTagCompound();
    	if (nbtTagCompound != null){
    	return nbtTagCompound.getString("UUID");
    	}
    	else return "";
    }

 

"My Crew is World Wide." 「ヤング • エルトウ」

Posted

No, No, No, No...

 

Minecraft is client-only class. Everything there is a display stuff - You cannot edit it, it won't do shit to actual data on server.

 

public static UUID getUUID(ItemStack stack)
{
    NBTTagCompound nbt = stack.getTagCompound();
    if (nbtTagCompound != null)
    {
        return new UUID(nbt.getLong("MSB"), nbt.getLong("LSB")); // most and least significant bits
    }
    return null;
}

In your Item class you need to write data to NBT on usage:

UUID uuid = entity.getUniqueId(); // entity is some entity you want to save ref to.
nbt.setLong("MSB", uuid.getMostSignificantBits()); // nbt of itemstack.
nbt.setLong("LSB", uuid.getLeastSignificantBits());

 

Getting actual ref:

@Override
public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player)
{
if (!world.isRemote) // UUIDs ONLY exist on server (not counting players)
{
	UUID uuid = getUUID(itemStack); // 1st method in post
	Entity entity = ((WorldServer) world).getEntityFromUuid(uuid);

 

Do note that srcs above are unsafe and need null handling for NBT/entity/uuid.

  Quote

1.7.10 is no longer supported by forge, you are on your own.

Posted
  On 2/4/2016 at 2:54 PM, Ernio said:

No, No, No, No...

 

Minecraft is client-only class. Everything there is a display stuff - You cannot edit it, it won't do shit to actual data on server.

 

public static UUID getUUID(ItemStack stack)
{
    NBTTagCompound nbt = stack.getTagCompound();
    if (nbtTagCompound != null)
    {
        return new UUID(nbt.getLong("MSB"), nbt.getLong("LSB")); // most and least significant bits
    }
    return null;
}

In your Item class you need to write data to NBT on usage:

UUID uuid = entity.getUniqueId(); // entity is some entity you want to save ref to.
nbt.setLong("MSB", uuid.getMostSignificantBits()); // nbt of itemstack.
nbt.setLong("LSB", uuid.getLeastSignificantBits());

 

Getting actual ref:

@Override
public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player)
{
if (!world.isRemote) // UUIDs ONLY exist on server (not counting players)
{
	UUID uuid = getUUID(itemStack); // 1st method in post
	Entity entity = ((WorldServer) world).getEntityFromUuid(uuid);

 

Do note that srcs above are unsafe and need null handling for NBT/entity/uuid.

 

Thanks, i understand what you mean, i'll try that.

"My Crew is World Wide." 「ヤング • エルトウ」

Posted
  On 2/4/2016 at 2:54 PM, Ernio said:

No, No, No, No...

 

Minecraft is client-only class. Everything there is a display stuff - You cannot edit it, it won't do shit to actual data on server.

 

public static UUID getUUID(ItemStack stack)
{
    NBTTagCompound nbt = stack.getTagCompound();
    if (nbtTagCompound != null)
    {
        return new UUID(nbt.getLong("MSB"), nbt.getLong("LSB")); // most and least significant bits
    }
    return null;
}

In your Item class you need to write data to NBT on usage:

UUID uuid = entity.getUniqueId(); // entity is some entity you want to save ref to.
nbt.setLong("MSB", uuid.getMostSignificantBits()); // nbt of itemstack.
nbt.setLong("LSB", uuid.getLeastSignificantBits());

 

Getting actual ref:

@Override
public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player)
{
if (!world.isRemote) // UUIDs ONLY exist on server (not counting players)
{
	UUID uuid = getUUID(itemStack); // 1st method in post
	Entity entity = ((WorldServer) world).getEntityFromUuid(uuid);

 

Do note that srcs above are unsafe and need null handling for NBT/entity/uuid.

 

THANKS ERNIO, it works perfectly!

It wasn't that hard to understand, but im wondering what uuid.getMostSignificantBits() &  uuid.getLeastSignificantBits() means, does a UUID have this 2 long variables? Can anyone explain me that? :)

"My Crew is World Wide." 「ヤング • エルトウ」

Guest
This topic is now closed to further replies.

Announcements



×
×
  • Create New...

Important Information

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