/** Updates the status if the entity is currently swimming (in water). */ private void updateSwimStatus() { ArrayList<BlockPosition> blockPositions = gatherAdjacentBlockPositions(getPosition()); boolean swimming = false, headUnderWater = false; for (int i = 0; i < blockPositions.size(); i++) { BlockPosition p = blockPositions.get(i); byte blockType = _parent.getWorldProvider().getBlockAtPosition(new Vector3d(p.x, p.y, p.z)); AABB blockAABB = Block.AABBForBlockAt(p.x, p.y, p.z); if (BlockManager.getInstance().getBlock(blockType).isLiquid() && getAABB().overlaps(blockAABB)) { swimming = true; } Vector3d eyePos = calcEyePosition(); eyePos.y += 0.25; if (BlockManager.getInstance().getBlock(blockType).isLiquid() && blockAABB.contains(eyePos)) { headUnderWater = true; } } _headUnderWater = headUnderWater; _isSwimming = swimming; }
/** Draw the icon. */ public void render() { if (_blockFamily == null) { _element.renderTransformed(); } else { GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glPushMatrix(); glTranslatef(4f, 0f, 0f); GL11.glScalef(20f, 20f, 20f); GL11.glRotatef(170f, 1f, 0f, 0f); GL11.glRotatef(-16f, 0f, 1f, 0f); TextureManager.getInstance().bindTexture("terrain"); Block block = _blockFamily.getArchetypeBlock(); block.render(); GL11.glPopMatrix(); GL11.glDisable(GL11.GL_TEXTURE_2D); } }
public FloatBuffer calcCoordinatesForWavingBlocks() { FloatBuffer buffer = BufferUtils.createFloatBuffer(32); int counter = 0; for (Block b : _blocksByTitle.values()) { if (b.isWaving()) { Vector2f pos = b.getTextureAtlasPos(Side.TOP); buffer.put(pos.x * Block.TEXTURE_OFFSET); buffer.put(pos.y * Block.TEXTURE_OFFSET); counter++; } } while (counter < 16) { buffer.put(-1); buffer.put(-1); counter++; } buffer.flip(); return buffer; }
public void render() { FloatBuffer mBuffer = BufferUtils.createFloatBuffer(16); float[] mFloat = new float[16]; GL11.glPushMatrix(); Vector3d cameraPosition = _parent.getActiveCamera().getPosition(); GL11.glTranslated(-cameraPosition.x, -cameraPosition.y, -cameraPosition.z); List<CollisionObject> collisionObjects = _discreteDynamicsWorld.getCollisionObjectArray(); for (CollisionObject co : collisionObjects) { if (co.getClass().equals(BlockRigidBody.class)) { BlockRigidBody br = (BlockRigidBody) co; Block block = BlockManager.getInstance().getBlock(br.getType()); Transform t = new Transform(); br.getMotionState().getWorldTransform(t); t.getOpenGLMatrix(mFloat); mBuffer.put(mFloat); mBuffer.flip(); GL11.glPushMatrix(); GL11.glMultMatrix(mBuffer); if (br.getCollisionShape() == _blockShapeHalf) GL11.glScalef(0.5f, 0.5f, 0.5f); else if (br.getCollisionShape() == _blockShapeQuarter) GL11.glScalef(0.25f, 0.25f, 0.25f); block.renderWithLightValue(_parent.getRenderingLightValueAt(new Vector3d(t.origin))); GL11.glPopMatrix(); } } GL11.glPopMatrix(); }
public BlockRigidBody[] addLootableBlocks(Vector3f position, Block block) { BlockRigidBody result[] = new BlockRigidBody[8]; for (int i = 0; i < block.getLootAmount(); i++) { // Position the smaller blocks Vector3f offsetPossition = new Vector3f( (float) _random.randomDouble() * 0.5f, (float) _random.randomDouble() * 0.5f, (float) _random.randomDouble() * 0.5f); offsetPossition.add(position); result[i] = addBlock( offsetPossition, block.getId(), new Vector3f(0.0f, 4000f, 0.0f), BLOCK_SIZE.QUARTER_SIZE, false); } return result; }
/** * Adds a new physics block to be rendered as a rigid body. Translucent blocks are ignored. * * @param position The position * @param type The block type * @param impulse An impulse * @param size The size of the block * @return The created rigid body (if any) */ public synchronized BlockRigidBody addBlock( Vector3f position, byte type, Vector3f impulse, BLOCK_SIZE size, boolean temporary) { if (temporary && _blocks.size() > MAX_TEMP_BLOCKS) return null; BoxShape shape = _blockShape; Block block = BlockManager.getInstance().getBlock(type); if (block.isTranslucent()) return null; if (size == BLOCK_SIZE.HALF_SIZE) shape = _blockShapeHalf; else if (size == BLOCK_SIZE.QUARTER_SIZE) shape = _blockShapeQuarter; Matrix3f rot = new Matrix3f(); rot.setIdentity(); DefaultMotionState blockMotionState = new DefaultMotionState(new Transform(new Matrix4f(rot, position, 1.0f))); Vector3f fallInertia = new Vector3f(); shape.calculateLocalInertia(block.getMass(), fallInertia); RigidBodyConstructionInfo blockCI = new RigidBodyConstructionInfo(block.getMass(), blockMotionState, shape, fallInertia); BlockRigidBody rigidBlock = new BlockRigidBody(blockCI, type); rigidBlock.setRestitution(0.0f); rigidBlock.setAngularFactor(0.5f); rigidBlock.setFriction(0.5f); rigidBlock._temporary = temporary; // Apply impulse rigidBlock.applyImpulse(impulse, new Vector3f(0.0f, 0.0f, 0.0f)); _insertionQueue.add(rigidBlock); return rigidBlock; }
/** * Checks for blocks around the entity. * * @param origin The original position of the entity * @return True if the entity is colliding horizontally */ private boolean horizontalHitTest(Vector3d origin) { boolean result = false; ArrayList<BlockPosition> blockPositions = gatherAdjacentBlockPositions(origin); // Check each block position for collision for (int i = 0; i < blockPositions.size(); i++) { BlockPosition p = blockPositions.get(i); byte blockType = _parent.getWorldProvider().getBlockAtPosition(new Vector3d(p.x, p.y, p.z)); AABB blockAABB = Block.AABBForBlockAt(p.x, p.y, p.z); if (!BlockManager.getInstance().getBlock(blockType).isPenetrable()) { if (getAABB().overlaps(blockAABB)) { result = true; // Calculate the direction from the origin to the current position Vector3d direction = new Vector3d(getPosition().x, 0f, getPosition().z); direction.x -= origin.x; direction.z -= origin.z; // Calculate the point of intersection on the block's AABB Vector3d blockPoi = blockAABB.closestPointOnAABBToPoint(origin); Vector3d entityPoi = generateAABBForPosition(origin).closestPointOnAABBToPoint(blockPoi); Vector3d planeNormal = blockAABB.normalForPlaneClosestToOrigin(blockPoi, origin, true, false, true); // Find a vector parallel to the surface normal Vector3d slideVector = new Vector3d(planeNormal.z, 0, -planeNormal.x); Vector3d pushBack = new Vector3d(); pushBack.sub(blockPoi, entityPoi); // Calculate the intensity of the diversion alongside the block double length = slideVector.dot(direction); Vector3d newPosition = new Vector3d(); newPosition.z = origin.z + pushBack.z * 0.2 + length * slideVector.z; newPosition.x = origin.x + pushBack.x * 0.2 + length * slideVector.x; newPosition.y = origin.y; // Update the position getPosition().set(newPosition); } } } return result; }
public void render() { // Update the viewing direction setViewingDirection(_yaw, _pitch); if ((Boolean) ConfigurationManager.getInstance().getConfig().get("System.Debug.debugCollision")) { getAABB().render(2f); ArrayList<BlockPosition> blocks = gatherAdjacentBlockPositions(getPosition()); for (int i = 0; i < blocks.size(); i++) { BlockPosition p = blocks.get(i); AABB blockAABB = Block.AABBForBlockAt(p.x, p.y, p.z); blockAABB.render(2f); } } }
/** * Checks for blocks below and above the entity. * * @param origin The origin position of the entity * @return True if a vertical collision was detected */ private boolean verticalHitTest(Vector3d origin) { ArrayList<BlockPosition> blockPositions = gatherAdjacentBlockPositions(origin); for (int i = 0; i < blockPositions.size(); i++) { BlockPosition p = blockPositions.get(i); byte blockType1 = _parent.getWorldProvider().getBlockAtPosition(new Vector3d(p.x, p.y, p.z)); AABB entityAABB = getAABB(); if (BlockManager.getInstance().getBlock(blockType1).isPenetrable() || !entityAABB.overlaps(Block.AABBForBlockAt(p.x, p.y, p.z))) continue; double direction = origin.y - getPosition().y; if (direction >= 0) getPosition().y = p.y + 0.50001f + entityAABB.getDimensions().y; else getPosition().y = p.y - 0.50001f - entityAABB.getDimensions().y; return true; } return false; }
public void addAllBlocks(Map<Byte, Block> blocks) { _blocksById.putAll(blocks); for (Block b : blocks.values()) { _blocksByTitle.put(b.getTitle(), b); } }
public void removeBlock(Block block) { _blocksById.remove(block.getId()); _blocksByTitle.remove(block.getTitle()); }
public void addBlock(Block block) { _blocksById.put(block.getId(), block); _blocksByTitle.put(block.getTitle(), block); }
private void checkForLootedBlocks() { LocalPlayer player = CoreRegistry.get(LocalPlayer.class); // to send blocks to minions, some needed classes EntityRef playerent = player.getEntity(); LocalPlayerComponent localPlayerComp = playerent.getComponent(LocalPlayerComponent.class); MinionBarComponent inventory = null; EntityRef closestminion = null; if (localPlayerComp.minionMode) { inventory = playerent.getComponent(MinionBarComponent.class); } for (int i = _blocks.size() - 1; i >= 0; i--) { BlockRigidBody b = _blocks.get(i); if (b._temporary) continue; float closestDist = 99999; if (inventory != null) { // check for the closest minion Iterator<EntityRef> it = inventory.MinionSlots.iterator(); while (it.hasNext()) { EntityRef minion = it.next(); if (b.distanceToEntity(minion) < closestDist) { closestDist = b.distanceToEntity(minion); closestminion = minion; } } } if (localPlayerComp.minionMode) { if (closestDist < 8 && !b._picked) { b._picked = true; } } else { closestDist = b.distanceToPlayer(); // Check if the block is close enough to the player if (b.distanceToPlayer() < 8.0f && !b._picked) { // Mark it as picked and remove it from the simulation b._picked = true; } } // Block was marked as being picked if (b._picked && closestDist < 32.0f) { // Animate the movement in direction of the player if (closestDist > 1.0) { Transform t = new Transform(); b.getMotionState().getWorldTransform(t); Matrix4f tMatrix = new Matrix4f(); t.getMatrix(tMatrix); Vector3f blockPlayer = new Vector3f(); tMatrix.get(blockPlayer); if (localPlayerComp.minionMode && closestminion != null) { LocationComponent minionloc = closestminion.getComponent(LocationComponent.class); if (minionloc != null) blockPlayer.sub(minionloc.getWorldPosition()); else blockPlayer.sub(new Vector3f()); } else { blockPlayer.sub(new Vector3f(player.getPosition())); } blockPlayer.normalize(); blockPlayer.scale(-16000f); b.applyCentralImpulse(blockPlayer); } else { // TODO: Handle full inventories // TODO: Loot blocks should be entities // Block was looted (and reached the player) Block block = BlockManager.getInstance().getBlock(b.getType()); EntityRef blockItem = _blockItemFactory.newInstance(block.getBlockFamily()); if (localPlayerComp.minionMode) { if (closestminion != null) { closestminion.send(new ReceiveItemEvent(blockItem)); } } else { playerent.send(new ReceiveItemEvent(blockItem)); } ItemComponent itemComp = blockItem.getComponent(ItemComponent.class); if (itemComp != null && !itemComp.container.exists()) { blockItem.destroy(); } AudioManager.play(new AssetUri(AssetType.SOUND, "engine:Loot")); _blocks.remove(i); _discreteDynamicsWorld.removeRigidBody(b); } } } }