Jump to content

[Solved]ChatMessage not always displaying


Glistre

Recommended Posts

Want the chat message to display to any players within X # of blocks from a custom mob ...

 

trouble is, it only seems to display when you quit the game and re-enter the game

 

Any ideas?  I've seen this happens a few other times on events but never was sure what caused the problem

Link to comment
Share on other sites

public boolean generate4(World world, Random rand, int i, int j, int k) {
	 if (!(world.isRemote)){

        	//spawn Tobie King  on tower
        	EntityTobieKing entity = new EntityTobieKing(world);	
    		entity.setPosition(i + 20, j + 34, k + 11);	
    		entity.setLocationAndAngles(i + 20, j + 34, k + 11, 0.0F , 0.0F);
    		world.spawnEntityInWorld(entity); 
    		entity.onUpdate();
    		
    		//gets list of players within 155 blocks - -very large radius
//	    		int r = 35; //radius   

    			List<EntityPlayer> playerList = world.getEntitiesWithinAABB(EntityPlayer.class, entity.boundingBox.expand(155.0D, 95.0D,155.0D));
    			Iterator<EntityPlayer> i1 = playerList.iterator();
    			EntityPlayer entityplayer;
                      while (i1.hasNext())
                      {
                            entityplayer = (EntityPlayer)i1.next();  			

                      if(!(world.isRemote))
                            entityplayer.addChatComponentMessage(
                            		new ChatComponentText(EnumChatFormatting.DARK_GREEN + "Toby King in Tower location" 
                            + EnumChatFormatting.DARK_RED + " X: " + (int)Math.round(entity.posX) 
                            + EnumChatFormatting.GOLD + " | Y: " + (int)Math.round(entity.posY) 
                            + EnumChatFormatting.DARK_AQUA +" | Z: " + (int)Math.round(entity.posZ)));
    			}
    			//DEBUG this below just tells me if its generating or not 
            System.out.println("Toby King spawned in Tower in Freon Biome location X: " + (int)Math.round(entity.posX) + " | Y: " + (int)Math.round(entity.posY) + " | Z: " + (int)Math.round(entity.posZ));
        	}
    			return true;

}

 

 

Link to comment
Share on other sites

You are adding the chat message in world generation. This will only show to players who are in the radius at the time the world is generated...

 

Do you know how the distance from the entity to the player would be measured?

I wonder if my y component could be a problem as well?  I have it x = 155, y = 95, z = 155  ...would that be 47 1/2 blocks above the player, and 155 blocks in any direction when generated?

Link to comment
Share on other sites

You are adding the chat message in world generation. This will only show to players who are in the radius at the time the world is generated...

I am able to get it to work reliably by overriding #updateEntity in my tileentitychest class but I still have two questions:

1) the chat message spams the console and the chat instead of just playing just one time;

and 2) how would I just detect my custom mob  ... outside of worldgen that is, so I don't have the probably of only showing when the world is generated?

 

Edit:  I tried a different way of doing this I used #onUpdate in my custom mob class.  That works, but again spams the chat and console.  Should I try to limit the chatmessage to display only once in chat or should I try using a different message? Maybe I should just create a custom item like a compass and call #getCurrentEquippedItem?

 

This is what I tried:

    @Override
    public void onUpdate(){
    	super.onUpdate();

    	//gets list of players within 55 euclidian distance blocks - -very large radius
	List<EntityPlayer> playerList = worldObj.getEntitiesWithinAABB(EntityPlayer.class, this.getEntityBoundingBox().expand(55.0D, 25.0D, 55.0D));


	Iterator<EntityPlayer> i1 = playerList.iterator();
	EntityPlayer entityplayer;
              while (i1.hasNext())
              {
                    entityplayer = (EntityPlayer)i1.next();  			

// 			if(!(world.isRemote && entityplayer.getCurrentEquippedItem() !=null && entityplayer.getCurrentEquippedItem().isItemEqual)))	
              if(!(worldObj.isRemote && entityplayer !=null))
                    entityplayer.addChatComponentMessage(
                    		new ChatComponentText(EnumChatFormatting.DARK_GREEN + "Toby King in Tower location" 
                    + EnumChatFormatting.DARK_RED + " X: " + (int)Math.round(this.posX) 
                    + EnumChatFormatting.GOLD + " | Y: " + (int)Math.round(this.posY) 
                    + EnumChatFormatting.DARK_AQUA +" | Z: " + (int)Math.round(this.posZ)));
	}
	//DEBUG this below just tells me if its generating or not 
              //get and print location of Toby king when it spawns in world
   //     System.out.println("Toby King spawned in Tower in Freon Biome location X: " + (int)Math.round(this.posX) + " | Y: " + (int)Math.round(this.posY) + " | Z: " + (int)Math.round(this.posZ));
    		
    }

Link to comment
Share on other sites

Do you want it to display once per spawned entity for every player? If so, you need a capability on the player to remember which mob's messages they have already seen (a set of UUIDs).

 

Not exactly sure where to start ...would that be player.capabilities. some code?

 

Also, I thought that adding a check for a player held item might work to turn off the message so I added this but nothing happened:

		if(!(worldObj.isRemote && entityplayer.getCurrentEquippedItem() !=null && entityplayer.getHeldItem().getItem() == (ItemRegistry.compass)));	

 

Link to comment
Share on other sites

Instead of generating UUIDS and assigning them to player entities, you could use just their nickname since there can only be one with the same nickname. So, you make an ArrayList of type String, for example, and then in the event when you are going to send the message to the player, you first check if the player's name  exists in the previous mentioned list. If so, you don't send the message, and if it is not in the list, you send the message and add the name to the list.

Link to comment
Share on other sites

Instead of generating UUIDS and assigning them to player entities, you could use just their nickname since there can only be one with the same nickname. So, you make an ArrayList of type String, for example, and then in the event when you are going to send the message to the player, you first check if the player's name  exists in the previous mentioned list. If so, you don't send the message, and if it is not in the list, you send the message and add the name to the list.

 

I already have a playerList that I iterate through ... is there a way to just change what I have so it won't send the message if it already sent?

 

I added a range which at least stops the spamming in chat and console of the message, but seems to add lag to the game

		double inRange = this.getDistanceSqToEntity(entityplayer);

		if ( inRange < 1000.0D & inRange > 900.0D){

Link to comment
Share on other sites

Instead of generating UUIDS and assigning them to player entities, you could use just their nickname since there can only be one with the same nickname. So, you make an ArrayList of type String, for example, and then in the event when you are going to send the message to the player, you first check if the player's name  exists in the previous mentioned list. If so, you don't send the message, and if it is not in the list, you send the message and add the name to the list.

 

I already have a playerList that I iterate through ... is there a way to just change what I have so it won't send the message if it already sent?

 

I added a range which at least stops the spamming in chat and console of the message, but seems to add lag to the game

		double inRange = this.getDistanceSqToEntity(entityplayer);

		if ( inRange < 1000.0D & inRange > 900.0D){

You want to send a message when your entity spawns but only once it spawns, create a boolean value on the entity and save it to NBT.

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.

Link to comment
Share on other sites

You want to send a message when your entity spawns but only once it spawns, create a boolean value on the entity and save it to NBT.

 

Could you possibly help me out a bit with the nbt saving? I sometimes have trouble with that

 

Here's what I have: (moved this to an event):

@SubscribeEvent
public void onEntitySpawnsTobieKing(LivingSpawnEvent event) {
	if (event.entity instanceof EntityTobieKing)  {

	List<EntityPlayer> playerList = event.entity.worldObj.getEntitiesWithinAABB(EntityPlayer.class, event.entity.getEntityBoundingBox().expand(155.0D, 75.0D, 155.0D));
	Iterator<EntityPlayer> i1 = playerList.iterator();
	EntityPlayer player;

              while (i1.hasNext())
              {
            	     player = (EntityPlayer)i1.next();	

        	NBTTagCompound nbt = event.entity.getEntityData();
        //	NBTTagCompound nbt = new NBTTagCompound();
        	nbt.setBoolean("spawned", true);
			if(nbt.hasKey("spawned")){

	        			player.addChatComponentMessage(
                    		new ChatComponentText(EnumChatFormatting.DARK_GREEN + "Toby King in Range, location" 
                    + EnumChatFormatting.DARK_RED + " X: " + (int)Math.round(event.entity.posX) 
                    + EnumChatFormatting.GOLD + " | Y: " + (int)Math.round(event.entity.posY) 
                    + EnumChatFormatting.DARK_AQUA +" | Z: " + (int)Math.round(event.entity.posZ)));
			}
              }
              }
	}

 

So the spamming the console slowed down a bit but it still continues to cycle over and over every couple of  seconds .  What I trying to do is 1) get the entity that spawns when it spawns; 2) check for players close to the entity; 3) add a chat message one time to the player.

 

 

Link to comment
Share on other sites

Why are you using

LivingSpawnEvent

? It's your entity class, you can do this without events.

Also do not use

getEntityData

. For your own entities create a field in the entity class to hold whatever data you want (a boolean in this case) and save it to NBT using the NBT serialization methods as you can see in vanilla entities. For other entities you would use a capability.

 

I don't understand how to check for the actual spawning of the entity, so I thought I had to use an event :(

Link to comment
Share on other sites

First update tick should work fine.

 

I got a bit confused trying to do that  . .  .but I added #ticksExisted%400 and seems to give me the desired effect of only showing in chat & console every 20 seconds or so.

 

I also added this to only when the player has an item in hand and that helps, so I think it would be best to make a custom compass and only display when the Player has the item in inventory  ....even though I never completed the nbt part and the tick method I am going to mark this solved. 

 

Thanks for the help

 

Here's what I came up with for my EntityTobieKing class if anyone else is curious:

   @Override
    public void onUpdate(){
    	super.onUpdate();
    	if (!(worldObj.isRemote && this.ticksExisted < 400)){
   /*     	NBTTagCompound nbt = new NBTTagCompound();
        	nbt.setBoolean("spawned", true);
        	if (nbt.getBoolean("spawned") == true && nbt.hasKey("spawned") ){*/
    	//gets list of players within 55 blocks - -very large radius
//		int r = 35; //radius   
	List<EntityPlayer> playerList = worldObj.getEntitiesWithinAABB(EntityPlayer.class, this.getEntityBoundingBox().expand(155.0D, 75.0D, 155.0D));
	Iterator<EntityPlayer> i1 = playerList.iterator();
	EntityPlayer entityplayer;

              while (i1.hasNext())
              {
            	     entityplayer = (EntityPlayer)i1.next();				

		double inRange = this.getDistanceSqToEntity(entityplayer);

			//	 && !nbt.getTagCompound().getBoolean(KEY))
		if ( inRange < 1600.0D & inRange > 1580.0D)

			if(entityplayer.getHeldItem() !=null &&  entityplayer.getHeldItem().getItem() == ItemRegistry.mighty_sword){

	        			entityplayer.addChatComponentMessage(
                    		new ChatComponentText(EnumChatFormatting.DARK_GREEN + "Toby King in Range, Tower location" 
                    + EnumChatFormatting.DARK_RED + " X: " + (int)Math.round(this.posX) 
                    + EnumChatFormatting.GOLD + " | Y: " + (int)Math.round(this.posY) 
                    + EnumChatFormatting.DARK_AQUA +" | Z: " + (int)Math.round(this.posZ)));
		}

              }
    	}
	//DEBUG this below just tells me if its generating or not 
              //get and print location of Toby king when it spawns in world
   //     System.out.println("Toby King spawned in Tower in Freon Biome location X: " + (int)Math.round(this.posX) + " | Y: " + (int)Math.round(this.posY) + " | Z: " + (int)Math.round(this.posZ));
    			
    }

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.



×
×
  • Create New...

Important Information

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