use of org.lanternpowered.server.entity.LanternEntity in project LanternServer by LanternPowered.
the class LanternWorld method pulseEntities.
private void pulseEntities() {
// Pulse the entities
for (LanternEntity entity : new ArrayList<>(this.entitiesByUniqueId.values())) {
if (entity.isRemoved()) {
final Vector3i lastChunk = entity.getLastChunkSectionCoords();
if (lastChunk != null && entity.getRemoveState() == LanternEntity.RemoveState.DESTROYED) {
final LanternChunk chunk = this.chunkManager.getChunkIfLoaded(lastChunk.getX(), lastChunk.getZ());
if (chunk != null) {
chunk.removeEntity(entity, lastChunk.getY());
}
}
this.entityProtocolManager.remove(entity);
this.entitiesByUniqueId.remove(entity.getUniqueId());
} else {
final Vector3i lastChunkSection = entity.getLastChunkSectionCoords();
entity.pulse();
final Vector3i pos = entity.getPosition().toInt();
final Vector3i newChunk = new Vector3i(pos.getX() >> 4, fixEntityYSection(pos.getY() >> 4), pos.getZ() >> 4);
if (lastChunkSection == null || !lastChunkSection.equals(newChunk)) {
LanternChunk chunk;
if (lastChunkSection != null && (chunk = this.chunkManager.getChunkIfLoaded(lastChunkSection.getX(), lastChunkSection.getZ())) != null) {
chunk.removeEntity(entity, lastChunkSection.getY());
}
chunk = this.chunkManager.getOrLoadChunk(newChunk.getX(), newChunk.getZ());
chunk.addEntity(entity, newChunk.getY());
entity.setLastChunkCoords(newChunk);
}
}
}
}
use of org.lanternpowered.server.entity.LanternEntity in project LanternServer by LanternPowered.
the class LanternWorld method addEntity.
@Nullable
private LanternEntity addEntity(LanternEntity entity) {
final LanternEntity entity1 = this.entitiesByUniqueId.putIfAbsent(entity.getUniqueId(), entity);
if (entity1 != null) {
return entity1;
}
final EntityProtocolType entityProtocolType = entity.getEntityProtocolType();
if (entityProtocolType != null) {
this.entityProtocolManager.add(entity, entityProtocolType);
}
entity.setPositionAndWorld(this, entity.getPosition());
return null;
}
use of org.lanternpowered.server.entity.LanternEntity in project LanternServer by LanternPowered.
the class LanternChunk method createEntity.
@SuppressWarnings("unchecked")
@Override
public Entity createEntity(EntityType type, Vector3d position) {
checkNotNull(position, "position");
final LanternEntityType entityType = (LanternEntityType) checkNotNull(type, "type");
checkVolumeBounds(position.getFloorX(), position.getFloorY(), position.getFloorZ());
// noinspection unchecked
final LanternEntity entity = (LanternEntity) entityType.getEntityConstructor().apply(UUID.randomUUID());
entity.setPositionAndWorld(this.world, position);
return entity;
}
use of org.lanternpowered.server.entity.LanternEntity in project LanternServer by LanternPowered.
the class AnvilChunkIOService method write.
@Override
public void write(LanternChunk chunk) throws IOException {
final int x = chunk.getX();
final int z = chunk.getZ();
final RegionFile region = this.cache.getRegionFileByChunk(x, z);
final int regionX = x & REGION_MASK;
final int regionZ = z & REGION_MASK;
final DataContainer rootView = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
final DataView levelDataView = rootView.createView(LEVEL);
// Core properties
levelDataView.set(VERSION, (byte) 1);
levelDataView.set(X, chunk.getX());
levelDataView.set(Z, chunk.getZ());
levelDataView.set(TERRAIN_POPULATED, (byte) (chunk.isPopulated() ? 1 : 0));
levelDataView.set(LIGHT_POPULATED, (byte) (chunk.isLightPopulated() ? 1 : 0));
levelDataView.set(LAST_UPDATE, 0L);
levelDataView.set(INHABITED_TIME, chunk.getLongInhabitedTime());
// Chunk sections
final ChunkSectionSnapshot[] sections = chunk.getSectionSnapshots(true);
final List<DataView> sectionDataViews = new ArrayList<>();
final List<DataView> tileEntityDataViews = new ArrayList<>();
for (byte i = 0; i < sections.length; ++i) {
final ChunkSectionSnapshot section = sections[i];
if (section == null) {
continue;
}
final DataContainer sectionDataView = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
sectionDataView.set(Y, i);
final byte[] rawTypes = new byte[section.types.length];
final short[] types = section.types;
NibbleArray extTypes = null;
final NibbleArray data = new NibbleArray(rawTypes.length);
for (int j = 0; j < rawTypes.length; j++) {
rawTypes[j] = (byte) ((types[j] >> 4) & 0xff);
byte extType = (byte) (types[j] >> 12);
if (extType != 0) {
if (extTypes == null) {
extTypes = new NibbleArray(rawTypes.length);
}
extTypes.set(j, extType);
}
data.set(j, (byte) (types[j] & 0xf));
}
sectionDataView.set(BLOCKS, rawTypes);
if (extTypes != null) {
sectionDataView.set(BLOCKS_EXTRA, extTypes.getPackedArray());
}
sectionDataView.set(DATA, data.getPackedArray());
sectionDataView.set(BLOCK_LIGHT, section.lightFromBlock);
final byte[] lightFromSky = section.lightFromSky;
if (lightFromSky != null) {
sectionDataView.set(SKY_LIGHT, lightFromSky);
}
sectionDataViews.add(sectionDataView);
// noinspection unchecked
final ObjectSerializer<LanternTileEntity> tileEntitySerializer = ObjectSerializerRegistry.get().get(LanternTileEntity.class).get();
// Serialize the tile entities
for (Short2ObjectMap.Entry<LanternTileEntity> tileEntityEntry : section.tileEntities.short2ObjectEntrySet()) {
if (!tileEntityEntry.getValue().isValid()) {
continue;
}
final DataView dataView = tileEntitySerializer.serialize(tileEntityEntry.getValue());
final short pos = tileEntityEntry.getShortKey();
dataView.set(TILE_ENTITY_X, x * 16 + (pos & 0xf));
dataView.set(TILE_ENTITY_Y, (i << 4) | (pos >> 8));
dataView.set(TILE_ENTITY_Z, z * 16 + ((pos >> 4) & 0xf));
tileEntityDataViews.add(dataView);
}
}
levelDataView.set(TILE_ENTITIES, tileEntityDataViews);
levelDataView.set(SECTIONS, sectionDataViews);
levelDataView.set(HEIGHT_MAP, chunk.getHeightMap());
// noinspection unchecked
final Short2ObjectMap<LanternChunk.TrackerData>[] trackerData = chunk.getTrackerData().getRawObjects();
final List<DataView> trackerDataViews = new ArrayList<>();
for (int i = 0; i < trackerData.length; i++) {
final Short2ObjectMap<LanternChunk.TrackerData> trackerDataSection = trackerData[i];
for (Short2ObjectMap.Entry<LanternChunk.TrackerData> entry : trackerDataSection.short2ObjectEntrySet()) {
// index = y << 8 | z << 4 | x
int index = entry.getShortKey() & 0xffff;
// Convert the index to the column based system
// index = z << 12 | y << 4 | x
index = ((index >> 4) & 0xf) << 12 | i << 8 | (index >> 4) & 0xf0 | index & 0xf;
final DataView trackerDataView = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
trackerDataView.set(TRACKER_BLOCK_POS, (short) index);
trackerDataView.set(TRACKER_ENTRY_NOTIFIER, entry.getValue().getNotifierId());
trackerDataView.set(TRACKER_ENTRY_CREATOR, entry.getValue().getCreatorId());
trackerDataViews.add(trackerDataView);
}
}
if (!trackerDataViews.isEmpty()) {
levelDataView.createView(DataQueries.SPONGE_DATA).set(TRACKER_DATA_TABLE, trackerDataViews);
}
final short[] biomes = chunk.getBiomes();
final byte[] biomes0 = new byte[biomes.length];
byte[] biomes1 = null;
for (int i = 0; i < biomes.length; i++) {
biomes0[i] = (byte) (biomes[i] & 0xff);
byte value = (byte) ((biomes[i] >> 4) & 0xff);
if (value != 0) {
if (biomes1 == null) {
biomes1 = new byte[biomes0.length];
}
biomes1[i] = value;
}
}
levelDataView.set(BIOMES, biomes0);
if (biomes1 != null) {
levelDataView.set(BIOMES_EXTRA, biomes1);
}
// noinspection unchecked
final List<LanternEntity> entities = new ArrayList(chunk.getEntities(entity -> !(entity instanceof Player)));
final ObjectSerializer<LanternEntity> entitySerializer = ObjectSerializerRegistry.get().get(LanternEntity.class).get();
final List<DataView> entityViews = new ArrayList<>();
for (LanternEntity entity : entities) {
if (entity.getRemoveState() == LanternEntity.RemoveState.DESTROYED) {
continue;
}
final DataView entityView = entitySerializer.serialize(entity);
entityViews.add(entityView);
}
levelDataView.set(ENTITIES, entityViews);
try (NbtDataContainerOutputStream nbt = new NbtDataContainerOutputStream(region.getChunkDataOutputStream(regionX, regionZ))) {
nbt.write(rootView);
nbt.flush();
}
}
use of org.lanternpowered.server.entity.LanternEntity in project LanternServer by LanternPowered.
the class EntitySerializer method deserialize.
@Override
public LanternEntity deserialize(DataView dataView) throws InvalidDataException {
String id0 = dataView.getString(ID).get();
final String id;
// Fast fail if the data isn't old
if (dataView.getInt(DATA_VERSION).orElse(0) < 704) {
id = fixEntityId(dataView, id0);
} else {
id = id0;
}
dataView.remove(ID);
final LanternEntityType entityType = (LanternEntityType) Sponge.getRegistry().getType(EntityType.class, id).orElseThrow(() -> new InvalidDataException("Unknown entity id: " + id));
// noinspection unchecked
final ObjectStore<LanternEntity> store = (ObjectStore) ObjectStoreRegistry.get().get(entityType.getEntityClass()).get();
final UUID uniqueId;
if (store instanceof IdentifiableObjectStore) {
uniqueId = ((IdentifiableObjectStore) store).deserializeUniqueId(dataView);
} else {
uniqueId = UUID.randomUUID();
}
// noinspection unchecked
final LanternEntity entity = (LanternEntity) entityType.getEntityConstructor().apply(uniqueId);
store.deserialize(entity, dataView);
return entity;
}
Aggregations