Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

Hello,

 

I'm trying to implement i CCTV camera into my mod. So i need a function that checks if a block can see a entity.

I've been looking through the code of EntityLivingBase and found a method called

canEntityBeSeen(Entity par1Entity)

.

So i copied what was in the method and customized it a little bit:

 

return worldObj.clip(worldObj.getWorldVec3Pool().getVecFromPool(xCoord, yCoord, zCoord), worldObj.getWorldVec3Pool().getVecFromPool(entity.posX, entity.posY + (double)entity.getEyeHeight(), entity.posZ)) == null;

 

I have that code in a TileEntity class. But when i call that function and print out the return value it always says

false

.

So i think i have to create a entity that spawns when my block is created, with that i can check if the block can see a entity nearby.

 

But before i do that i wanted to ask if there is a better method with that i can check if the block can see a entity nearby.

(I don't wan't to get all the entity's nearby, i wan't all the entity's that the block can see).

 

Thank you in advance.

 

ss7

You sir are a god damn hero.

It is not null because world#clip(blockVec,entityVec) will give you the block#collisionRayTrace(World,int,int,int,Vec3,Vec3)

 

You are going to need to define some orientation into your block, probably a view distance too, and make your own vectors calculation.

Hi

 

Just to expand on GotoLink's answer-

 

That statement performs a raytrace between the two coordinates you specify and looks for any non-transparent block faces in between the two. If it doesn't find anything, it returns null.

 

If your CCTV block is collideable (Block.canCollideCheck), then the ray trace will always intersect your block and never return null.  But if you make your block non-collideable, the player won't be able to left or right click it.

 

You don't need to spawn an entity.  I'd suggest your algorithm should look something like

(1) find all entities within a given distance of the camera.  RenderGlobal.renderEntities "entities" section is an example of how the vanilla code does it - looks for all entities within a given radius and in the frustrum (where the player "camera" is looking)

(2) for each entity, ray trace from the entity to the camera using the World.clip method you found.  If the returned MovingObjectPosition.[x,y,z] is equal to your block's [x,y,z], then you know that the entity is visible to the camera because the ray made it all the way to your camera block.  It's only a rough approximation since your camera treats the entity as a point - if eg the entity[x,y,z] corresponds to its head the camera will ignore it unless it can see the head, even if it can see the feet.  But this is probably good enough.

 

-TGG

 

BTW I think this method treats glass as collideable, i.e. your camera wouldn't be able to see through glass.  Likewise blocks with torches, redstone wires, etc.

 

 

 

 

 

 

  • Author

Hello,

 

OK, thank you!

I've now got this code in a TileEntity class to get all entities nearby:

 

 

List<Entity> entities = worldObj.getEntitiesWithinAABB(EntityLivingBase.class, AxisAlignedBB.getAABBPool().getAABB(xCoord, yCoord, zCoord, xCoord + 1, yCoord + 1, zCoord + 1).expand(4, 4, 4));

		for (Entity entity : entities)
		{			
			if (entity instanceof EntityLivingBase)
			{			
				System.out.println(canSee(entity));

				return;
			}
		}

 

 

And the canSee() method looks like this (i inverted the order of the arguments, like TheGreyGhost said):

 

 

MovingObjectPosition canSee(Entity entity)
{
	return worldObj.clip(worldObj.getWorldVec3Pool().getVecFromPool(entity.posX, entity.posY, entity.posZ), worldObj.getWorldVec3Pool().getVecFromPool(xCoord, yCoord, zCoord));	
}

 

 

But it always prints out null.

I don't know what is wrong with my code.

 

ss7

You sir are a god damn hero.

Hi

 

Interesting.  Your code looks  roughly right, I don't see anything obviously with the method calls.

 

Why do you have a return in your for loop?  The way it's written, you will only ever check the first living entity in range.

 

You should probably add 0.5 to xCoord, yCoord, and zCoord in your getVecFromPool to put the camera position in the middle of your block, to make sure that the raytrace does actually collide with your camera block.  You do have a Block of some sort at the camera position, yes?

 

What happens if you insert blocks between the camera and your test entity, does the canSee method return non-NULL then?

 

If no luck with those, I would suggest you put a breakpoint in your canSee and step through the clip method to make sure that the [x,y,z] coordinates are what you think they should be.  Otherwise I'm stumped!

 

-TGG

 

 

  • Author

Hello,

 

Thank you very much, now it works!

 

ss7

You sir are a god damn hero.

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...

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.