use of cn.nukkit.entity.Entity in project Nukkit by Nukkit.
the class ItemSpawnEgg method onActivate.
@Override
public boolean onActivate(Level level, Player player, Block block, Block target, BlockFace face, double fx, double fy, double fz) {
FullChunk chunk = level.getChunk((int) block.getX() >> 4, (int) block.getZ() >> 4);
if (chunk == null) {
return false;
}
CompoundTag nbt = new CompoundTag().putList(new ListTag<DoubleTag>("Pos").add(new DoubleTag("", block.getX() + 0.5)).add(new DoubleTag("", block.getY())).add(new DoubleTag("", block.getZ() + 0.5))).putList(new ListTag<DoubleTag>("Motion").add(new DoubleTag("", 0)).add(new DoubleTag("", 0)).add(new DoubleTag("", 0))).putList(new ListTag<FloatTag>("Rotation").add(new FloatTag("", new Random().nextFloat() * 360)).add(new FloatTag("", 0)));
if (this.hasCustomName()) {
nbt.putString("CustomName", this.getCustomName());
}
Entity entity = Entity.createEntity(this.meta, chunk, nbt);
if (entity != null) {
if (player.isSurvival()) {
Item item = player.getInventory().getItemInHand();
item.setCount(item.getCount() - 1);
player.getInventory().setItemInHand(item);
}
entity.spawnToAll();
return true;
}
return false;
}
use of cn.nukkit.entity.Entity in project Nukkit by Nukkit.
the class Level method setChunk.
public void setChunk(int chunkX, int chunkZ, BaseFullChunk chunk, boolean unload) {
if (chunk == null) {
return;
}
long index = Level.chunkHash(chunkX, chunkZ);
FullChunk oldChunk = this.getChunk(chunkX, chunkZ, false);
if (unload && oldChunk != null) {
this.unloadChunk(chunkX, chunkZ, false, false);
this.provider.setChunk(chunkX, chunkZ, chunk);
} else {
Map<Long, Entity> oldEntities = oldChunk != null ? oldChunk.getEntities() : Collections.emptyMap();
Map<Long, BlockEntity> oldBlockEntities = oldChunk != null ? oldChunk.getBlockEntities() : Collections.emptyMap();
if (!oldEntities.isEmpty()) {
Iterator<Map.Entry<Long, Entity>> iter = oldEntities.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<Long, Entity> entry = iter.next();
Entity entity = entry.getValue();
chunk.addEntity(entity);
if (oldChunk != null) {
iter.remove();
oldChunk.removeEntity(entity);
entity.chunk = chunk;
}
}
}
if (!oldBlockEntities.isEmpty()) {
Iterator<Map.Entry<Long, BlockEntity>> iter = oldBlockEntities.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<Long, BlockEntity> entry = iter.next();
BlockEntity blockEntity = entry.getValue();
chunk.addBlockEntity(blockEntity);
if (oldChunk != null) {
iter.remove();
oldChunk.removeBlockEntity(blockEntity);
blockEntity.chunk = chunk;
}
}
}
this.provider.setChunk(chunkX, chunkZ, chunk);
}
chunk.setChanged();
if (!this.isChunkInUse(index)) {
this.unloadChunkRequest(chunkX, chunkZ);
} else {
for (ChunkLoader loader : this.getChunkLoaders(chunkX, chunkZ)) {
loader.onChunkChanged(chunk);
}
}
}
use of cn.nukkit.entity.Entity in project Nukkit by Nukkit.
the class Level method doTick.
public void doTick(int currentTick) {
this.timings.doTick.startTiming();
updateBlockLight(lightQueue);
this.checkTime();
// Tick Weather
this.rainTime--;
if (this.rainTime <= 0) {
if (!this.setRaining(!this.raining)) {
if (this.raining) {
setRainTime(ThreadLocalRandom.current().nextInt(12000) + 12000);
} else {
setRainTime(ThreadLocalRandom.current().nextInt(168000) + 12000);
}
}
}
this.thunderTime--;
if (this.thunderTime <= 0) {
if (!this.setThundering(!this.thundering)) {
if (this.thundering) {
setThunderTime(ThreadLocalRandom.current().nextInt(12000) + 3600);
} else {
setThunderTime(ThreadLocalRandom.current().nextInt(168000) + 12000);
}
}
}
if (this.isThundering()) {
Map<Long, ? extends FullChunk> chunks = getChunks();
if (chunks instanceof Long2ObjectOpenHashMap) {
Long2ObjectOpenHashMap<? extends FullChunk> fastChunks = (Long2ObjectOpenHashMap) chunks;
ObjectIterator<? extends Long2ObjectMap.Entry<? extends FullChunk>> iter = fastChunks.long2ObjectEntrySet().fastIterator();
while (iter.hasNext()) {
Long2ObjectMap.Entry<? extends FullChunk> entry = iter.next();
performThunder(entry.getLongKey(), entry.getValue());
}
} else {
for (Map.Entry<Long, ? extends FullChunk> entry : getChunks().entrySet()) {
performThunder(entry.getKey(), entry.getValue());
}
}
}
this.skyLightSubtracted = this.calculateSkylightSubtracted(1);
this.levelCurrentTick++;
this.unloadChunks();
this.timings.doTickPending.startTiming();
int polled = 0;
this.updateQueue.tick(this.getCurrentTick());
this.timings.doTickPending.stopTiming();
TimingsHistory.entityTicks += this.updateEntities.size();
this.timings.entityTick.startTiming();
if (!this.updateEntities.isEmpty()) {
for (long id : new ArrayList<>(this.updateEntities.keySet())) {
Entity entity = this.updateEntities.get(id);
if (entity.closed || !entity.onUpdate(currentTick)) {
this.updateEntities.remove(id);
}
}
}
this.timings.entityTick.stopTiming();
TimingsHistory.tileEntityTicks += this.updateBlockEntities.size();
this.timings.blockEntityTick.startTiming();
if (!this.updateBlockEntities.isEmpty()) {
for (long id : new ArrayList<>(this.updateBlockEntities.keySet())) {
if (!this.updateBlockEntities.get(id).onUpdate()) {
this.updateBlockEntities.remove(id);
}
}
}
this.timings.blockEntityTick.stopTiming();
this.timings.tickChunks.startTiming();
this.tickChunks();
this.timings.tickChunks.stopTiming();
if (!this.changedBlocks.isEmpty()) {
if (!this.players.isEmpty()) {
ObjectIterator<Long2ObjectMap.Entry<SoftReference<Map<Character, Object>>>> iter = changedBlocks.long2ObjectEntrySet().fastIterator();
while (iter.hasNext()) {
Long2ObjectMap.Entry<SoftReference<Map<Character, Object>>> entry = iter.next();
long index = entry.getKey();
Map<Character, Object> blocks = entry.getValue().get();
int chunkX = Level.getHashX(index);
int chunkZ = Level.getHashZ(index);
if (blocks == null || blocks.size() > MAX_BLOCK_CACHE) {
FullChunk chunk = this.getChunk(chunkX, chunkZ);
for (Player p : this.getChunkPlayers(chunkX, chunkZ).values()) {
p.onChunkChanged(chunk);
}
} else {
Collection<Player> toSend = this.getChunkPlayers(chunkX, chunkZ).values();
Player[] playerArray = toSend.toArray(new Player[toSend.size()]);
Vector3[] blocksArray = new Vector3[blocks.size()];
int i = 0;
for (char blockHash : blocks.keySet()) {
Vector3 hash = getBlockXYZ(index, blockHash);
blocksArray[i++] = hash;
}
this.sendBlocks(playerArray, blocksArray, UpdateBlockPacket.FLAG_ALL);
}
}
}
this.changedBlocks.clear();
}
this.processChunkRequest();
if (this.sleepTicks > 0 && --this.sleepTicks <= 0) {
this.checkSleep();
}
for (long index : this.chunkPackets.keySet()) {
int chunkX = Level.getHashX(index);
int chunkZ = Level.getHashZ(index);
Player[] chunkPlayers = this.getChunkPlayers(chunkX, chunkZ).values().stream().toArray(Player[]::new);
if (chunkPlayers.length > 0) {
for (DataPacket pk : this.chunkPackets.get(index)) {
Server.broadcastPacket(chunkPlayers, pk);
}
}
}
if (gameRules.isStale()) {
GameRulesChangedPacket packet = new GameRulesChangedPacket();
packet.gameRules = gameRules;
Server.broadcastPacket(players.values().toArray(new Player[players.size()]), packet);
gameRules.refresh();
}
this.chunkPackets.clear();
this.timings.doTick.stopTiming();
}
use of cn.nukkit.entity.Entity in project Nukkit by Nukkit.
the class Level method getNearbyEntities.
public Entity[] getNearbyEntities(AxisAlignedBB bb, Entity entity) {
int index = 0;
int minX = NukkitMath.floorDouble((bb.getMinX() - 2) * 0.0625);
int maxX = NukkitMath.ceilDouble((bb.getMaxX() + 2) * 0.0625);
int minZ = NukkitMath.floorDouble((bb.getMinZ() - 2) * 0.0625);
int maxZ = NukkitMath.ceilDouble((bb.getMaxZ() + 2) * 0.0625);
ArrayList<Entity> overflow = null;
for (int x = minX; x <= maxX; ++x) {
for (int z = minZ; z <= maxZ; ++z) {
for (Entity ent : this.getChunkEntities(x, z).values()) {
if (ent != entity && ent.boundingBox.intersectsWith(bb)) {
if (index < ENTITY_BUFFER.length) {
ENTITY_BUFFER[index] = ent;
} else {
if (overflow == null)
overflow = new ArrayList<>(1024);
overflow.add(ent);
}
index++;
}
}
}
}
if (index == 0)
return EMPTY_ENTITY_ARR;
Entity[] copy;
if (overflow == null) {
copy = Arrays.copyOfRange(ENTITY_BUFFER, 0, index);
Arrays.fill(ENTITY_BUFFER, 0, index, null);
} else {
copy = new Entity[ENTITY_BUFFER.length + overflow.size()];
System.arraycopy(ENTITY_BUFFER, 0, copy, 0, ENTITY_BUFFER.length);
for (int i = 0; i < overflow.size(); i++) {
copy[ENTITY_BUFFER.length + i] = overflow.get(i);
}
}
return copy;
}
use of cn.nukkit.entity.Entity in project Nukkit by Nukkit.
the class Level method setBlock.
public boolean setBlock(int x, int y, int z, Block block, boolean direct, boolean update) {
if (y < 0 || y >= 256) {
return false;
}
BaseFullChunk chunk = this.getChunk(x >> 4, z >> 4, true);
Block blockPrevious;
// synchronized (chunk) {
blockPrevious = chunk.getAndSetBlock(x & 0xF, y, z & 0xF, block);
if (blockPrevious.getFullId() == block.getFullId()) {
return false;
}
// }
block.x = x;
block.y = y;
block.z = z;
block.level = this;
int cx = x >> 4;
int cz = z >> 4;
long index = Level.chunkHash(cx, cz);
if (direct) {
this.sendBlocks(this.getChunkPlayers(cx, cz).values().stream().toArray(Player[]::new), new Block[] { block }, UpdateBlockPacket.FLAG_ALL_PRIORITY);
} else {
addBlockChange(index, x, y, z);
}
for (ChunkLoader loader : this.getChunkLoaders(cx, cz)) {
loader.onBlockChanged(block);
}
if (update) {
if (blockPrevious.isTransparent() != block.isTransparent() || blockPrevious.getLightLevel() != block.getLightLevel()) {
addLightUpdate(x, y, z);
}
BlockUpdateEvent ev = new BlockUpdateEvent(block);
this.server.getPluginManager().callEvent(ev);
if (!ev.isCancelled()) {
for (Entity entity : this.getNearbyEntities(new SimpleAxisAlignedBB(x - 1, y - 1, z - 1, x + 1, y + 1, z + 1))) {
entity.scheduleUpdate();
}
block = ev.getBlock();
block.onUpdate(BLOCK_UPDATE_NORMAL);
this.updateAround(x, y, z);
}
}
return true;
}
Aggregations