use of io.xol.chunkstories.api.entity.Entity in project chunkstories by Hugobros3.
the class CulledEntitiesRenderer method renderEntities.
public int renderEntities(RenderingInterface renderer) {
((WorldImplementation) world).entitiesLock.readLock().lock();
// Sort them by type
Map<EntityDefinition, List<EntityRenderable>> renderableEntitiesTypes = new HashMap<EntityDefinition, List<EntityRenderable>>();
for (Entity entity : world.getAllLoadedEntities()) {
if (entity instanceof EntityRenderable) {
EntityRenderable entityRenderable = (EntityRenderable) entity;
List<EntityRenderable> entitiesOfThisType = renderableEntitiesTypes.get(entityRenderable.getDefinition());
if (entitiesOfThisType == null) {
renderableEntitiesTypes.put(entityRenderable.getDefinition(), new ArrayList<EntityRenderable>());
entitiesOfThisType = renderableEntitiesTypes.get(entityRenderable.getDefinition());
}
entitiesOfThisType.add(entityRenderable);
}
}
int entitiesRendered = 0;
for (Entry<EntityDefinition, List<EntityRenderable>> entry : renderableEntitiesTypes.entrySet()) {
List<EntityRenderable> entities = entry.getValue();
// Caches entity renderers until we f12
if (!entityRenderers.containsKey(entry.getKey()))
entityRenderers.put(entry.getKey(), entities.get(0).getEntityRenderer());
EntityRenderer<? extends EntityRenderable> entityRenderer = entityRenderers.get(entry.getKey());
if (entityRenderer == null)
continue;
try {
int e = entityRenderer.renderEntities(renderer, new EntitiesRendererIterator<>(renderer, entities));
entitiesRendered += e;
} catch (Throwable e) {
System.out.println("Exception rendering entities " + entities.get(0).getClass().getSimpleName() + " using " + entityRenderer.getClass().getSimpleName());
e.printStackTrace();
}
}
((WorldImplementation) world).entitiesLock.readLock().unlock();
return entitiesRendered;
}
use of io.xol.chunkstories.api.entity.Entity in project chunkstories by Hugobros3.
the class WorldImplementation method tick.
@Override
public void tick() {
// Iterates over every entity
try {
entitiesLock.writeLock().lock();
Iterator<Entity> iter = this.getAllLoadedEntities();
Entity entity;
while (iter.hasNext()) {
entity = iter.next();
// Check entity's region is loaded
if (entity.getChunk() != null)
entity.tick();
else
// Tries to snap the entity to the region if it ends up being loaded
((EntityBase) entity).positionComponent.trySnappingToChunk();
}
} finally {
entitiesLock.writeLock().unlock();
}
// Increase the ticks counter
worldTicksCounter++;
// Time cycle
if (this instanceof WorldMaster && internalData.getBoolean("doTimeCycle", true))
if (worldTicksCounter % 60 == 0)
worldTime++;
}
use of io.xol.chunkstories.api.entity.Entity in project chunkstories by Hugobros3.
the class WorldImplementation method spawnPlayer.
public void spawnPlayer(Player player) {
if (!(this instanceof WorldMaster))
throw new UnsupportedOperationException("Only Master Worlds can do this");
Entity savedEntity = null;
SerializedEntityFile playerEntityFile = new SerializedEntityFile(this.getFolderPath() + "/players/" + player.getName().toLowerCase() + ".csf");
if (playerEntityFile.exists())
savedEntity = playerEntityFile.read(this);
Location previousLocation = null;
if (savedEntity != null)
previousLocation = savedEntity.getLocation();
PlayerSpawnEvent playerSpawnEvent = new PlayerSpawnEvent(player, (WorldMaster) this, savedEntity, previousLocation);
getGameContext().getPluginManager().fireEvent(playerSpawnEvent);
if (!playerSpawnEvent.isCancelled()) {
Entity entity = playerSpawnEvent.getEntity();
Location actualSpawnLocation = playerSpawnEvent.getSpawnLocation();
if (actualSpawnLocation == null)
actualSpawnLocation = this.getDefaultSpawnLocation();
// TODO EntitySimplePlayer ?
if (entity == null || ((entity instanceof EntityLiving) && (((EntityLiving) entity).isDead())))
entity = this.gameContext.getContent().entities().getEntityDefinition("player").create(actualSpawnLocation);
else
// entity = new EntityPlayer(this, 0d, 0d, 0d, player.getName()); //Default entity
entity.setUUID(-1);
// Name your player !
if (entity instanceof EntityNameable)
((EntityNameable) entity).getNameComponent().setName(player.getName());
entity.setLocation(actualSpawnLocation);
addEntity(entity);
if (entity instanceof EntityControllable)
player.setControlledEntity((EntityControllable) entity);
else
System.out.println("Error : entity is not controllable");
}
}
use of io.xol.chunkstories.api.entity.Entity in project chunkstories by Hugobros3.
the class CubicChunk method pokeInternal.
/**
* The 'core' of the core, this private function is responsible for placing and
* keeping everyone up to snuff on block modifications. It all comes back to this really.
*/
private ActualChunkVoxelContext pokeInternal(final int worldX, final int worldY, final int worldZ, Voxel newVoxel, final int sunlight, final int blocklight, final int metadata, int raw_data, final boolean use_raw_data, final boolean update, final boolean return_context, final WorldModificationCause cause) {
int x = sanitizeCoordinate(worldX);
int y = sanitizeCoordinate(worldY);
int z = sanitizeCoordinate(worldZ);
ActualChunkVoxelContext cell_pre = peek(x, y, z);
Voxel formerVoxel = cell_pre.getVoxel();
assert formerVoxel != null;
FreshFutureCell future = new FreshFutureCell(cell_pre);
if (use_raw_data) {
// We need this for voxel placement logic
newVoxel = world.getContentTranslator().getVoxelForId(VoxelFormat.id(raw_data));
// Build the future from parsing the raw data
future.setVoxel(newVoxel);
future.setSunlight(VoxelFormat.sunlight(raw_data));
future.setBlocklight(VoxelFormat.blocklight(raw_data));
future.setMetaData(VoxelFormat.meta(raw_data));
} else {
// Build the raw data from the set parameters by editing the in-place data
// (because we allow only editing some aspects of the cell data)
raw_data = cell_pre.getData();
if (newVoxel != null) {
raw_data = VoxelFormat.changeId(raw_data, world.getContentTranslator().getIdForVoxel(newVoxel));
future.setVoxel(newVoxel);
}
if (sunlight >= 0) {
raw_data = VoxelFormat.changeSunlight(raw_data, sunlight);
future.setSunlight(sunlight);
}
if (blocklight >= 0) {
raw_data = VoxelFormat.changeBlocklight(raw_data, blocklight);
future.setBlocklight(blocklight);
}
if (metadata >= 0) {
raw_data = VoxelFormat.changeMeta(raw_data, metadata);
future.setMetaData(metadata);
}
}
try {
if (newVoxel == null || formerVoxel.equals(newVoxel)) {
formerVoxel.onModification(cell_pre, future, cause);
} else {
formerVoxel.onRemove(cell_pre, cause);
newVoxel.onPlace(future, cause);
}
} catch (WorldException e) {
// Abort !
if (return_context)
return cell_pre;
else
return null;
}
// Allocate if it makes sense
if (chunkVoxelData == null)
chunkVoxelData = atomicalyCreateInternalData();
chunkVoxelData[x * 32 * 32 + y * 32 + z] = raw_data;
if (newVoxel != null && !formerVoxel.equals(newVoxel))
newVoxel.whenPlaced(future);
// Update lightning
if (update)
lightBaker.computeLightSpread(x, y, z, cell_pre.raw_data, raw_data);
// Increment the modifications counter
compr_uncomittedBlockModifications.incrementAndGet();
// Don't spam the thread creation spawn
occlusion.unbakedUpdates.incrementAndGet();
// Update related summary
if (update)
world.getRegionsSummariesHolder().updateOnBlockPlaced(x, y, z, future);
// Mark the nearby chunks to be re-rendered
if (update) {
int sx = chunkX;
int ex = sx;
int sy = chunkY;
int ey = sy;
int sz = chunkZ;
int ez = sz;
if (x == 0)
sx--;
else if (x == 31)
ex++;
if (y == 0)
sy--;
else if (y == 31)
ey++;
if (z == 0)
sz--;
else if (z == 31)
ez++;
for (int ix = sx; ix <= ex; ix++) for (int iy = sy; iy <= ey; iy++) for (int iz = sz; iz <= ez; iz++) {
Chunk chunk = world.getChunk(ix, iy, iz);
if (chunk != null && chunk instanceof ChunkRenderable)
((ChunkRenderable) chunk).meshUpdater().requestMeshUpdate();
}
}
// If this is a 'master' world, notify remote users of the change !
if (update && world instanceof WorldMaster && !(world instanceof WorldTool)) {
PacketVoxelUpdate packet = new PacketVoxelUpdate(new ActualChunkVoxelContext(chunkX * 32 + x, chunkY * 32 + y, chunkZ * 32 + z, raw_data));
Iterator<WorldUser> pi = this.chunkHolder.users.iterator();
while (pi.hasNext()) {
WorldUser user = pi.next();
if (!(user instanceof RemotePlayer))
continue;
RemotePlayer player = (RemotePlayer) user;
Entity clientEntity = player.getControlledEntity();
if (clientEntity == null)
// Ignore clients that aren't playing
continue;
player.pushPacket(packet);
}
}
if (return_context)
return new ActualChunkVoxelContext(chunkX * 32 + x, chunkY * 32 + y, chunkZ * 32 + z, raw_data);
else
return null;
}
use of io.xol.chunkstories.api.entity.Entity in project chunkstories by Hugobros3.
the class CSFRegionFile0x2C method load.
public void load(DataInputStream in) throws IOException {
try {
// First load the compressed chunk data sizes
int[] chunksSizes = new int[8 * 8 * 8];
for (int a = 0; a < 8 * 8 * 8; a++) {
chunksSizes[a] = in.readInt();
}
// Load in the compressed chunks
for (int a = 0; a < 8; a++) for (int b = 0; b < 8; b++) for (int c = 0; c < 8; c++) {
int compressedDataSize = chunksSizes[a * 8 * 8 + b * 8 + c];
// Compressed data was found, load it
if (compressedDataSize > 0) {
byte[] buffer = new byte[compressedDataSize];
in.readFully(buffer, 0, compressedDataSize);
owner.getChunkHolder(a, b, c).setCompressedData(new CompressedData(buffer, null, null));
} else if (compressedDataSize == air_chunk_magic_number) {
owner.getChunkHolder(a, b, c).setCompressedData(new CompressedData(null, null, null));
} else if (compressedDataSize == 0x00000000) {
owner.getChunkHolder(a, b, c).setCompressedData(null);
} else {
throw new RuntimeException("Unexpected negative length for compressed chunk size: " + compressedDataSize);
}
}
// We pretend it's loaded sooner so we can add the entities and they will load their voxel data if needed
owner.setDiskDataLoaded(true);
// don't tick the world entities until we get this straight
owner.world.entitiesLock.writeLock().lock();
// Older version case - TODO write a version mechanism that prevents from checking this
if (in.available() <= 0) {
owner.world.entitiesLock.writeLock().unlock();
return;
}
try {
// Read entities until we hit -1
Entity entity = null;
do {
entity = EntitySerializer.readEntityFromStream(in, this, owner.world);
if (entity != null)
owner.world.addEntity(entity);
} while (entity != null);
} catch (Exception e) {
logger().error("Error while loading " + file);
logger().error("Exception: {}", e);
// e.printStackTrace(logger().getPrintWriter());
// e.printStackTrace();
}
owner.world.entitiesLock.writeLock().unlock();
} finally {
in.close();
}
}
Aggregations