public OnChangedBlock(Vector3i pos, Block newType, Block oldType) { this.blockPosition = new Vector3i(pos); this.oldType = oldType; this.newType = newType; }
private static void generateMockChunkCubeWithSideWidthAround(final Vector3i position, final int sideWidth, final ChunkCache chunkCache) { for (int x = position.getX() - sideWidth; x <= position.getX() + sideWidth; x++) { for (int y = position.getY() - sideWidth; y <= position.getY() + sideWidth; y++) { for (int z = position.getZ() - sideWidth; z <= position.getZ() + sideWidth; z++) { if (x == position.getX() && y == position.getY() && z == position.getZ()) { //dont override the inner chunk continue; } chunkCache.put(new Vector3i(x, y, z), mockChunkAt(x, y, z)); } } } }
@Test public void testManhattanDistance() { assertEquals(0, Vector3i.zero().gridDistance(Vector3i.zero())); assertEquals(1, Vector3i.zero().gridDistance(Vector3i.west())); assertEquals(1, Vector3i.zero().gridDistance(Vector3i.up())); assertEquals(1, Vector3i.zero().gridDistance(Vector3i.north())); assertEquals(3, Vector3i.zero().gridDistance(Vector3i.one())); assertEquals(3, Vector3i.zero().gridDistance(new Vector3i(1, -1, 1))); }
static Region3i getChunkRegionAbove(Vector3f location) { Vector3i charecterPos = new Vector3i(location); Vector3i chunkAboveCharacter = ChunkMath.calcChunkPos(charecterPos); chunkAboveCharacter.addY(1); Vector3i chunkRelativePos = ChunkMath.calcBlockPos(charecterPos); Vector3i characterChunkOriginPos = new Vector3i(charecterPos); characterChunkOriginPos.sub(chunkRelativePos); Vector3i chunkAboveOrigin = new Vector3i(characterChunkOriginPos); chunkAboveOrigin.addY(ChunkConstants.CHUNK_SIZE.getY()); return ChunkConstants.CHUNK_REGION.move(chunkAboveOrigin); }
private void renderOverlayForOneBlockSelection(BlockSelectionComponent blockSelectionComponent, BlockSelectionRenderer selectionRenderer) { selectionRenderer.beginRenderOverlay(); if (blockSelectionComponent.currentSelection == null) { if (blockSelectionComponent.startPosition != null) { selectionRenderer.renderMark(blockSelectionComponent.startPosition); } } else { Vector3i size = blockSelectionComponent.currentSelection.size(); Vector3i block = new Vector3i(); for (int z = 0; z < size.z; z++) { for (int y = 0; y < size.y; y++) { for (int x = 0; x < size.x; x++) { block.set(x, y, z); block.add(blockSelectionComponent.currentSelection.min()); selectionRenderer.renderMark(block); } } } } selectionRenderer.endRenderOverlay(); }
private void propagateDepth(LitChunk adjChunk, Side side, boolean propagateExternal, IndexProvider indexProvider, Region3i edgeRegion, int[] depths) { Vector3i adjPos = new Vector3i(); int adjacentDepth = adjDepth[depthIndex]; for (int i = adjacentDepth; i < depths[depthIndex]; ++i) { adjPos.set(side.getVector3i()); adjPos.mul(i + 1); adjPos.add(pos); adjPos.add(chunkEdgeDeltas.get(side)); byte value = rules.getValue(adjChunk, adjPos); if (value > 1) {
@Test public void testTwoDistanceIteration() { Set<Vector3i> iter = Sets.newHashSet(Diamond3iIterator.iterate(Vector3i.zero(), 2)); assertEquals(25, iter.size()); for (Vector3i pos : iter) { assertTrue(pos.gridDistance(new Vector3i()) <= 2); } }
private void checkBlockEntry(EntityRef entity, Vector3i oldPosition, Vector3i newPosition, float characterHeight) { // TODO: This will only work for tall mobs/players and single block mobs // is this a different position than previously if (!oldPosition.equals(newPosition)) { Biome oldBiome = worldProvider.getBiome(oldPosition); Biome newBiome = worldProvider.getBiome(newPosition); if (oldBiome != newBiome) { entity.send(new OnEnterBiomeEvent(oldPosition, newPosition, oldBiome, newBiome)); } // get the old position's blocks Block[] oldBlocks = new Block[(int) Math.ceil(characterHeight)]; Vector3i currentPosition = new Vector3i(oldPosition); for (int currentHeight = 0; currentHeight < oldBlocks.length; currentHeight++) { oldBlocks[currentHeight] = worldProvider.getBlock(currentPosition); currentPosition.add(0, 1, 0); } // get the new position's blocks Block[] newBlocks = new Block[(int) Math.ceil(characterHeight)]; currentPosition = new Vector3i(newPosition); for (int currentHeight = 0; currentHeight < characterHeight; currentHeight++) { newBlocks[currentHeight] = worldProvider.getBlock(currentPosition); currentPosition.add(0, 1, 0); } for (int i = 0; i < characterHeight; i++) { // send a block enter/leave event for this character entity.send(new OnEnterBlockEvent(oldBlocks[i], newBlocks[i], new Vector3i(0, i, 0))); } } }
@Test public void testHash() { // k = 59 // j = k+1 = 60 // i = (k+k^2)(1+k)^2 = not important for collision // hash = (k+k^2)(1+k)^2 + x(1+k)^2 + (1+k)y + z // hash = i + xj^2 + jy + z // with x := 0 // hash = i + jy + z // set i + jy + z = i + jy' + z' // jy + z = jy' + z' // set z' := z + j -> z'-z = j // jy = jy' + j -> y' = y - 1 Vector3i a = new Vector3i(0, 10, 10); Vector3i b = new Vector3i(0, 9, 70); assertFalse(a.hashCode() == b.hashCode()); assertTrue(new Vector3i(0, 10, 10).hashCode() == new Vector3i(0, 10, 10).hashCode()); assertTrue(new Vector3i(-100, 10, 10).hashCode() == new Vector3i(-100, 10, 10).hashCode()); assertTrue(new Vector3i(0, -5, -5).hashCode() == new Vector3i(0, -5, -5).hashCode()); assertFalse(new Vector3i(1, 10, 10).hashCode() == new Vector3i(0, 10, 10).hashCode()); assertFalse(new Vector3i(-101, 10, 10).hashCode() == new Vector3i(-100, 10, 10).hashCode()); assertFalse(new Vector3i(0, -1, -5).hashCode() == new Vector3i(0, -5, -5).hashCode()); }
if (!newChunkPos.equals(chunkPos) || force || pendingChunks) { Vector3i viewingDistance = config.getRendering().getViewDistance().getChunkDistance(); Region3i viewRegion = Region3i.createFromCenterExtents(newChunkPos, new Vector3i(viewingDistance.x / 2, viewingDistance.y / 2, viewingDistance.z / 2)); if (chunksInProximity.size() == 0 || force || pendingChunks) { Region3i oldRegion = Region3i.createFromCenterExtents(chunkPos, new Vector3i(viewingDistance.x / 2, viewingDistance.y / 2, viewingDistance.z / 2)); chunkPos.set(newChunkPos); pendingChunks = chunksCurrentlyPending;
public void setChunkSize(Vector3i chunkSize) { this.chunkFilterSize = new Vector3i(TeraMath.ceilPowerOfTwo(chunkSize.x) - 1, TeraMath.ceilPowerOfTwo(chunkSize.y) - 1, TeraMath.ceilPowerOfTwo(chunkSize.z) - 1); this.chunkPower = new Vector3i(TeraMath.sizeOfPower(chunkSize.x), TeraMath.sizeOfPower(chunkSize.y), TeraMath.sizeOfPower(chunkSize.z)); Vector3i blockMin = new Vector3i(); blockMin.sub(offset); blockMin.mul(chunkSize.x, chunkSize.y, chunkSize.z); Vector3i blockSize = chunkRegion.size(); blockSize.mul(chunkSize.x, chunkSize.y, chunkSize.z); this.blockRegion = Region3i.createFromMinAndSize(blockMin, blockSize); }
void doExplosion(ExplosionActionComponent explosionComp, Vector3f origin, EntityRef instigatingBlockEntity) { EntityBuilder builder = entityManager.newBuilder("core:smokeExplosion"); builder.getComponent(LocationComponent.class).setWorldPosition(origin); EntityRef smokeEntity = builder.build(); smokeEntity.send(new PlaySoundEvent(getRandomExplosionSound(), 1f)); Vector3i blockPos = new Vector3i(); for (int i = 0; i < explosionComp.maxRange; i++) { Vector3f direction = random.nextVector3f(1.0f); for (int j = 0; j < 4; j++) { Vector3f target = new Vector3f(origin); target.x += direction.x * j; target.y += direction.y * j; target.z += direction.z * j; blockPos.set((int) target.x, (int) target.y, (int) target.z); Block currentBlock = worldProvider.getBlock(blockPos); /* PHYSICS */ if (currentBlock.isDestructible()) { EntityRef blockEntity = blockEntityRegistry.getEntityAt(blockPos); // allow explosions to chain together, but do not chain on the instigating block if (!blockEntity.equals(instigatingBlockEntity) && blockEntity.hasComponent(ExplosionActionComponent.class)) { doExplosion(blockEntity.getComponent(ExplosionActionComponent.class), blockPos.toVector3f(), blockEntity); } else { blockEntity.send(new DoDamageEvent(explosionComp.damageAmount, explosionComp.damageType)); } } } } }
/** * find a spot above the surface that is big enough for this character * @param spawnPos the position to check * @param height the height of the entity to spawn * @return the topmost solid block <code>null</code> if none was found */ private Vector3i findOpenVerticalPosition(Vector3i spawnPos, float height) { int consecutiveAirBlocks = 0; Vector3i newSpawnPos = new Vector3i(spawnPos); // TODO: also start looking downwards if initial spawn pos is in the air for (int i = 1; i < 20; i++) { if (worldProvider.isBlockRelevant(newSpawnPos)) { if (worldProvider.getBlock(newSpawnPos).isPenetrable()) { consecutiveAirBlocks++; } else { consecutiveAirBlocks = 0; } if (consecutiveAirBlocks >= height) { newSpawnPos.subY(consecutiveAirBlocks); return newSpawnPos; } newSpawnPos.add(0, 1, 0); } } return null; } }
offset.sub(targetBlockComp.position.toVector3f()); Side offsetDir = Side.inDirection(offset); Vector3i primePos = new Vector3i(targetBlockComp.position); primePos.add(offsetDir.getVector3i()); Block primeBlock = worldProvider.getBlock(primePos); if (!primeBlock.isReplacementAllowed()) { Vector3i topBlockPos; if (belowBlock.isReplacementAllowed()) { bottomBlockPos = new Vector3i(primePos.x, primePos.y - 1, primePos.z); topBlockPos = primePos; } else if (aboveBlock.isReplacementAllowed()) { bottomBlockPos = primePos; topBlockPos = new Vector3i(primePos.x, primePos.y + 1, primePos.z); } else { event.consume(); entity.removeComponent(MeshComponent.class); newDoor.addComponent(new BlockRegionComponent(Region3i.createBounded(bottomBlockPos, topBlockPos))); Vector3f doorCenter = bottomBlockPos.toVector3f(); doorCenter.y += 0.5f; newDoor.addComponent(new LocationComponent(doorCenter));
private void sendNewChunks(NetData.NetMessage.Builder message) { if (!readyChunks.isEmpty()) { chunkSendCounter += chunkSendRate * NET_TICK_RATE * networkSystem.getBandwidthPerClient(); if (chunkSendCounter > 1.0f) { chunkSendCounter -= 1.0f; Vector3i center = new Vector3i(); LocationComponent loc = getEntity().getComponent(ClientComponent.class).character.getComponent(LocationComponent.class); if (loc != null) { center.set(ChunkMath.calcChunkPos(new Vector3i(loc.getWorldPosition(), RoundingMode.HALF_UP))); } Vector3i pos = null; int distance = Integer.MAX_VALUE; for (Vector3i chunkPos : readyChunks.keySet()) { int chunkDistance = chunkPos.distanceSquared(center); if (pos == null || chunkDistance < distance) { pos = chunkPos; distance = chunkDistance; } } Chunk chunk = readyChunks.remove(pos); relevantChunks.add(pos); message.addChunkInfo(chunk.encode()); } } else { chunkSendCounter = 1.0f; } }
@Test public void testPrefabUpdatedWhenBlockChanged() { worldProvider.setBlock(Vector3i.zero(), blockWithString); assertEquals(blockWithString.getPrefab().get().getName(), worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0)).getParentPrefab().getName()); worldProvider.setBlock(Vector3i.zero(), blockWithDifferentString); assertEquals(blockWithDifferentString.getPrefab().get().getName(), worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0)).getParentPrefab().getName()); }