private EntityRef createBlockEntity(Vector3i blockPosition, Block block) { EntityBuilder builder = entityManager.newBuilder(block.getPrefab().orElse(null)); builder.addComponent(new LocationComponent(blockPosition.toVector3f())); builder.addComponent(new BlockComponent(block, blockPosition)); if (block.isDestructible() && !builder.hasComponent(HealthComponent.class)) { // Block regen should always take the same amount of time, regardless of its hardness builder.addComponent( new HealthComponent( block.getHardness(), block.getHardness() / BLOCK_REGEN_SECONDS, 1.0f)); } boolean isTemporary = isTemporaryBlock(builder, block); if (!isTemporary && !builder.hasComponent(NetworkComponent.class)) { builder.addComponent(new NetworkComponent()); } EntityRef blockEntity; if (isTemporary) { blockEntity = builder.buildWithoutLifecycleEvents(); temporaryBlockEntities.add(blockEntity); } else { blockEntity = builder.build(); } blockEntityLookup.put(new Vector3i(blockPosition), blockEntity); return blockEntity; }
/** * Transforms a block entity with the change of block type. This is driven from the delta between * the old and new block type prefabs, but takes into account changes made to the block entity. * * @param blockEntity The entity to update * @param oldType The previous type of the block * @param type The new type of the block */ private void updateBlockEntityComponents( EntityRef blockEntity, Block oldType, Block type, Set<Class<? extends Component>> retainComponents) { BlockComponent blockComponent = blockEntity.getComponent(BlockComponent.class); Optional<Prefab> oldPrefab = oldType.getPrefab(); EntityBuilder oldEntityBuilder = entityManager.newBuilder(oldPrefab.orElse(null)); oldEntityBuilder.addComponent( new BlockComponent(oldType, new Vector3i(blockComponent.getPosition()))); BeforeEntityCreated oldEntityEvent = new BeforeEntityCreated(oldPrefab.orElse(null), oldEntityBuilder.iterateComponents()); blockEntity.send(oldEntityEvent); for (Component comp : oldEntityEvent.getResultComponents()) { oldEntityBuilder.addComponent(comp); } Optional<Prefab> newPrefab = type.getPrefab(); EntityBuilder newEntityBuilder = entityManager.newBuilder(newPrefab.orElse(null)); newEntityBuilder.addComponent( new BlockComponent(type, new Vector3i(blockComponent.getPosition()))); BeforeEntityCreated newEntityEvent = new BeforeEntityCreated(newPrefab.orElse(null), newEntityBuilder.iterateComponents()); blockEntity.send(newEntityEvent); for (Component comp : newEntityEvent.getResultComponents()) { newEntityBuilder.addComponent(comp); } for (Component component : blockEntity.iterateComponents()) { if (!COMMON_BLOCK_COMPONENTS.contains(component.getClass()) && !entityManager .getComponentLibrary() .getMetadata(component.getClass()) .isRetainUnalteredOnBlockChange() && !newEntityBuilder.hasComponent(component.getClass()) && !retainComponents.contains(component.getClass())) { blockEntity.removeComponent(component.getClass()); } } blockComponent.setBlock(type); blockEntity.saveComponent(blockComponent); HealthComponent health = blockEntity.getComponent(HealthComponent.class); if (health == null && type.isDestructible()) { blockEntity.addComponent( new HealthComponent(type.getHardness(), type.getHardness() / BLOCK_REGEN_SECONDS, 1.0f)); } else if (health != null && !type.isDestructible()) { blockEntity.removeComponent(HealthComponent.class); } else if (health != null && type.isDestructible()) { health.maxHealth = type.getHardness(); health.currentHealth = Math.min(health.currentHealth, health.maxHealth); blockEntity.saveComponent(health); } for (Component comp : newEntityBuilder.iterateComponents()) { copyIntoPrefab(blockEntity, comp, retainComponents); } }