private Block createRawBlock(String defaultName, SectionDefinitionData def) { Block block = new Block(); block.setLiquid(def.isLiquid()); block.setWater(def.isWater()); block.setLava(def.isLava()); block.setGrass(def.isGrass()); block.setIce(def.isIce()); block.setHardness(def.getHardness()); block.setAttachmentAllowed(def.isAttachmentAllowed()); block.setReplacementAllowed(def.isReplacementAllowed()); block.setSupportRequired(def.isSupportRequired()); block.setPenetrable(def.isPenetrable()); block.setTargetable(def.isTargetable()); block.setClimbable(def.isClimbable()); block.setTranslucent(def.isTranslucent()); block.setDoubleSided(def.isDoubleSided()); block.setShadowCasting(def.isShadowCasting()); block.setWaving(def.isWaving()); block.setLuminance(def.getLuminance()); block.setTint(def.getTint()); if (Strings.isNullOrEmpty(def.getDisplayName())) { block.setDisplayName(properCase(defaultName)); } else { block.setDisplayName(def.getDisplayName()); block.setSounds(def.getSounds()); block.setMass(def.getMass()); block.setDebrisOnDestroy(def.isDebrisOnDestroy()); block.setFriction(def.getFriction());
if (!centerBlock.isAttachmentAllowed()) { return false; if (!adjBlock.isReplacementAllowed() || adjBlock.isTargetable()) { return false; if (block.getBlockFamily().equals(adjBlock.getBlockFamily())) { return false; if (!block.isPenetrable()) { Physics physics = CoreRegistry.get(Physics.class); AABB blockBounds = block.getBounds(blockPos); Vector3f min = new Vector3f(blockBounds.getMin()); Vector3f max = new Vector3f(blockBounds.getMax());
@ReceiveEvent public void beforeDamagedEnsureHealthPresent(BeforeDamagedEvent event, EntityRef blockEntity, BlockComponent blockComponent) { if (!blockEntity.hasComponent(HealthComponent.class)) { Block type = blockComponent.block; if (type.isDestructible()) { HealthComponent healthComponent = new HealthComponent(type.getHardness(), type.getHardness() / BLOCK_REGEN_SECONDS, 1.0f); healthComponent.destroyEntityOnNoHealth = true; blockEntity.addComponent(healthComponent); } } } }
/** * Light can spread out of a block if * - it has luminance (ie, glows), * - it is translucent * - or the side isn't full * <p> * {@inheritDoc} */ @Override public boolean canSpreadOutOf(Block block, Side side) { return block.getLuminance() > 0 || block.isTranslucent() || !block.isFullSide(side); }
/** * Returns true if the side should be rendered adjacent to the second side provided. * * @param blockToCheck The block to check * @param currentBlock The current block * @return True if the side is visible for the given block types */ private boolean isSideVisibleForBlockTypes(Block blockToCheck, Block currentBlock, Side side) { // Liquids can be transparent but there should be no visible adjacent faces if (currentBlock.isLiquid() && blockToCheck.isLiquid()) { return false; } return currentBlock.isWaving() != blockToCheck.isWaving() || blockToCheck.getMeshGenerator() == null || !blockToCheck.isFullSide(side.reverse()) || (!currentBlock.isTranslucent() && blockToCheck.isTranslucent()); }
/** * Any luminance from the block is a constant * <p> * {@inheritDoc} */ @Override public byte getFixedValue(Block block, Vector3i pos) { return block.getLuminance(); }
private void updateBlock(Block block) { Optional<Prefab> prefab = block.getPrefab(); boolean keepActive = block.isKeepActive(); boolean requiresLifecycleEvents = false; if (prefab.isPresent()) { for (Component comp : prefab.get().iterateComponents()) { ComponentMetadata<?> metadata = entityManager.getComponentLibrary().getMetadata(comp.getClass()); if (metadata.isForceBlockActive()) { keepActive = true; break; } if (metadata.isBlockLifecycleEventsRequired()) { requiresLifecycleEvents = true; } } } block.setKeepActive(keepActive); block.setLifecycleEventsRequired(requiresLifecycleEvents && !keepActive); } }
private void updateBlockEntity(EntityRef blockEntity, Vector3i pos, Block oldType, Block type, boolean forceEntityUpdate, Set<Class<? extends Component>> retainComponents) { if (type.isKeepActive()) { temporaryBlockEntities.remove(blockEntity); } else if (oldType.isKeepActive() && isTemporaryBlock(blockEntity, type)) { temporaryBlockEntities.add(blockEntity); } if (forceEntityUpdate || !(Objects.equal(oldType.getBlockFamily(), type.getBlockFamily()) && Objects.equal(oldType.getPrefab(), type.getPrefab()))) { updateBlockEntityComponents(blockEntity, oldType, type, retainComponents); } EntityRef regionEntity = blockRegionLookup.get(pos); if (regionEntity != null) { regionEntity.send(new OnChangedBlock(pos, type, oldType)); } blockEntity.send(new OnChangedBlock(new Vector3i(pos), type, oldType)); }
public static void addOrUpdateBlockMeshComponent(BlockItemComponent blockItemComponent, MutableComponentContainer entity) { if (blockItemComponent != null) { MeshComponent meshComponent = null; if (entity.hasComponent(MeshComponent.class)) { meshComponent = entity.getComponent(MeshComponent.class); } else { meshComponent = new MeshComponent(); } BlockFamily blockFamily = blockItemComponent.blockFamily; if (blockFamily == null) { return; } meshComponent.mesh = blockFamily.getArchetypeBlock().getMeshGenerator().getStandaloneMesh(); meshComponent.material = Assets.getMaterial("engine:terrain").get(); meshComponent.translucent = blockFamily.getArchetypeBlock().isTranslucent(); float luminance = blockFamily.getArchetypeBlock().getLuminance() / 15f; meshComponent.selfLuminance = luminance; if (luminance > 0 && !entity.hasComponent(LightComponent.class)) { LightComponent lightComponent = entity.addComponent(new LightComponent()); //scale the light back if it is a less bright block lightComponent.lightAttenuationRange *= luminance; } entity.addOrSaveComponent(meshComponent); } } }
if (blockFamily.getArchetypeBlock().getLuminance() > 0) { builder.addComponent(new LightComponent()); Optional<Prefab> prefab = blockFamily.getArchetypeBlock().getPrefab(); if (prefab.isPresent()) { for (Component component : prefab.get().iterateComponents()) { if (blockFamily.getArchetypeBlock().isStackable()) { item.stackId = "block:" + blockFamily.getURI().toString(); item.stackCount = (byte) quantity;
private void beforeDamageCommon(BeforeDamagedEvent event, Block block) { if (event.getDamageType() != null) { BlockDamageModifierComponent blockDamage = event.getDamageType().getComponent(BlockDamageModifierComponent.class); if (blockDamage != null) { BlockFamily blockFamily = block.getBlockFamily(); for (String category : blockFamily.getCategories()) { if (blockDamage.materialDamageMultiplier.containsKey(category)) { event.multiply(blockDamage.materialDamageMultiplier.get(category)); } } } } }
BlockComponent blockComponent = blockEntity.getComponent(BlockComponent.class); Optional<Prefab> oldPrefab = oldType.getPrefab(); EntityBuilder oldEntityBuilder = entityManager.newBuilder(oldPrefab.orElse(null)); oldEntityBuilder.addComponent(new BlockComponent(oldType, blockComponent.position)); Optional<Prefab> newPrefab = type.getPrefab(); EntityBuilder newEntityBuilder = entityManager.newBuilder(newPrefab.orElse(null)); newEntityBuilder.addComponent(new BlockComponent(type, blockComponent.position));
private void generateMesh() { Tessellator tessellator = new Tessellator(); for (BlockPart dir : BlockPart.values()) { BlockMeshPart part = block.getPrimaryAppearance().getPart(dir); if (part != null) { if (block.isDoubleSided()) { tessellator.addMeshPartDoubleSided(part); } else { tessellator.addMeshPart(part); } } } mesh = tessellator.generateMesh(new ResourceUrn("engine", "blockmesh", block.getURI().toString())); } }
private void generateBlockTypeEntity(Block block) { EntityBuilder builder = entityManager.newBuilder(blockTypePrefab); builder.getComponent(BlockTypeComponent.class).block = block; // TODO: Copy across settings as necessary Optional<Prefab> prefab = block.getPrefab(); if (prefab.isPresent()) { for (Component comp : prefab.get().iterateComponents()) { if (!(comp instanceof NetworkComponent)) { builder.addComponent(entityManager.getComponentLibrary().copy(comp)); } } } block.setEntity(builder.build()); } }
@Test public void testActiveBlockNotCleanedUp() { Block testBlock = new Block(); testBlock.setKeepActive(true); // BlockFamily blockFamily = new SymmetricFamily(new BlockUri("test:keepActive"), testBlock); //blockManager.addBlockFamily(blockFamily, true); worldStub.setBlock(Vector3i.zero(), testBlock); BlockEventChecker checker = new BlockEventChecker(); entityManager.getEventSystem().registerEventHandler(checker); EntityRef blockEntity = worldProvider.getBlockEntityAt(new Vector3i(0, 0, 0)); worldProvider.update(1.0f); assertTrue(blockEntity.exists()); assertTrue(blockEntity.isActive()); assertTrue(checker.addedReceived); assertTrue(checker.activateReceived); }
@Override public boolean step() { if (blockFamilyIterator.hasNext()) { BlockFamily family = blockFamilyIterator.next(); family.getArchetypeBlock().getMeshGenerator(); stepDone(); } return !blockFamilyIterator.hasNext(); }
@ReceiveEvent public void onFootstep(FootstepEvent event, EntityRef entity, LocationComponent locationComponent, CharacterSoundComponent characterSounds) { List<StaticSound> footstepSounds = characterSounds.footstepSounds; // Check if the block the character is standing on has footstep sounds Vector3i blockPos = new Vector3i(locationComponent.getLocalPosition()); blockPos.y--; // The block *below* the character's feet is interesting to us Block block = worldProvider.getBlock(blockPos); if (block != null) { if (block.getSounds() == null) { logger.error("Block '{}' has no sounds", block.getURI()); } else if (!block.getSounds().getStepSounds().isEmpty()) { footstepSounds = block.getSounds().getStepSounds(); } } if (footstepSounds.size() > 0 && characterSounds.lastSoundTime + MIN_TIME < time.getGameTimeInMs()) { StaticSound sound = random.nextItem(footstepSounds); entity.send(new PlaySoundEvent(entity, sound, characterSounds.footstepVolume)); characterSounds.lastSoundTime = time.getGameTimeInMs(); entity.saveComponent(characterSounds); } }
if (blockFamily.getArchetypeBlock().getLuminance() > 0) { builder.addComponent(new LightComponent()); if (blockFamily.getArchetypeBlock().isStackable()) { item.stackId = "block:" + blockFamily.getURI().toString(); item.stackCount = (byte) 1;
private void commonDestroyed(DoDestroyEvent event, EntityRef entity, Block block) { entity.send(new CreateBlockDropsEvent(event.getInstigator(), event.getDirectCause(), event.getDamageType())); BlockDamageModifierComponent blockDamageModifierComponent = event.getDamageType().getComponent(BlockDamageModifierComponent.class); // TODO: Configurable via block definition if (blockDamageModifierComponent == null || !blockDamageModifierComponent.skipPerBlockEffects) { // dust particle effect if (entity.hasComponent(LocationComponent.class) && block.isDebrisOnDestroy()) { EntityBuilder dustBuilder = entityManager.newBuilder("core:dustEffect"); // TODO: particle system stuff should be split out better - this is effectively a stealth dependency on Core from the engine if (dustBuilder.hasComponent(LocationComponent.class)) { dustBuilder.getComponent(LocationComponent.class).setWorldPosition(entity.getComponent(LocationComponent.class).getWorldPosition()); dustBuilder.build(); } } // sound to play for destroyed block BlockSounds sounds = block.getSounds(); if (!sounds.getDestroySounds().isEmpty()) { StaticSound sound = random.nextItem(sounds.getDestroySounds()); entity.send(new PlaySoundEvent(sound, 0.6f)); } } }