package org.terasology.componentSystem.block; import org.terasology.asset.AssetType; import org.terasology.asset.AssetUri; import org.terasology.components.BlockParticleEffectComponent; import org.terasology.components.HealthComponent; import org.terasology.components.ItemComponent; import org.terasology.components.world.BlockComponent; import org.terasology.components.world.LocationComponent; import org.terasology.entityFactory.BlockItemFactory; import org.terasology.entitySystem.EntityManager; import org.terasology.entitySystem.EntityRef; import org.terasology.entitySystem.EventHandlerSystem; import org.terasology.entitySystem.EventPriority; import org.terasology.entitySystem.PrefabManager; import org.terasology.entitySystem.ReceiveEvent; import org.terasology.entitySystem.RegisterComponentSystem; import org.terasology.events.DamageEvent; import org.terasology.events.FullHealthEvent; import org.terasology.events.NoHealthEvent; import org.terasology.events.inventory.ReceiveItemEvent; import org.terasology.game.CoreRegistry; import org.terasology.logic.manager.AudioManager; import org.terasology.logic.world.WorldProvider; import org.terasology.rendering.physics.BulletPhysicsRenderer; import org.terasology.teraspout.TeraBlock; /** * Event handler for events affecting block entities * * @author Immortius <immortius@gmail.com> */ @RegisterComponentSystem public class BlockEntitySystem implements EventHandlerSystem { private WorldProvider worldProvider; private EntityManager entityManager; private BlockItemFactory blockItemFactory; @Override public void initialise() { entityManager = CoreRegistry.get(EntityManager.class); worldProvider = CoreRegistry.get(WorldProvider.class); blockItemFactory = new BlockItemFactory(entityManager, CoreRegistry.get(PrefabManager.class)); } @Override public void shutdown() { } @ReceiveEvent(components = {BlockComponent.class}) public void onDestroyed(NoHealthEvent event, EntityRef entity) { if (worldProvider == null) return; BlockComponent blockComp = entity.getComponent(BlockComponent.class); TeraBlock oldBlock = worldProvider.getBlock(blockComp.getPosition()); // worldProvider.setBlock(blockComp.getPosition(), BlockManager.getInstance().getAir(), oldBlock); TODO fixme // TODO: This should be driven by block attachment info, and not be billboard specific // Remove the upper block if it's a billboard TeraBlock upperBlock = worldProvider.getBlock(blockComp.getPosition().x, blockComp.getPosition().y + 1, blockComp.getPosition().z); if (upperBlock.getBlockForm() == TeraBlock.BLOCK_FORM.BILLBOARD) { // worldProvider.setBlock(blockComp.getPosition().x, blockComp.getPosition().y + 1, blockComp.getPosition().z, BlockManager.getInstance().getAir(), upperBlock); } // TODO: Configurable via block definition AudioManager.play(new AssetUri(AssetType.SOUND, "engine:RemoveBlock"), 0.6f); if ((oldBlock.isStraightToInventory() || !oldBlock.isEntityTemporary()) && event.getInstigator().exists()) { EntityRef item = blockItemFactory.newInstance(oldBlock.getBlockFamily(), entity); if (!oldBlock.isEntityTemporary()) { entity.removeComponent(HealthComponent.class); entity.removeComponent(BlockComponent.class); } event.getInstigator().send(new ReceiveItemEvent(item)); ItemComponent itemComp = item.getComponent(ItemComponent.class); if (itemComp != null && !itemComp.container.exists()) { // TODO: Fix this - entity needs to be added to lootable block or destroyed item.destroy(); CoreRegistry.get(BulletPhysicsRenderer.class).addLootableBlocks(blockComp.getPosition().toVector3f(), oldBlock); } } else { /* PHYSICS */ CoreRegistry.get(BulletPhysicsRenderer.class).addLootableBlocks(blockComp.getPosition().toVector3f(), oldBlock); } if (oldBlock.isEntityTemporary()) { entity.destroy(); } } // TODO: Need a occasionally scan for and remove temporary block entities that were never damaged? @ReceiveEvent(components = {BlockComponent.class}) public void onRepaired(FullHealthEvent event, EntityRef entity) { BlockComponent blockComp = entity.getComponent(BlockComponent.class); if (blockComp.temporary) { entity.destroy(); } } @ReceiveEvent(components = {BlockComponent.class}, priority = EventPriority.PRIORITY_HIGH) public void onDamaged(DamageEvent event, EntityRef entity) { BlockComponent blockComp = entity.getComponent(BlockComponent.class); EntityRef particlesEntity = entityManager.create(); particlesEntity.addComponent(new LocationComponent(blockComp.getPosition().toVector3f())); BlockParticleEffectComponent particleEffect = new BlockParticleEffectComponent(); particleEffect.spawnCount = 64; particleEffect.blockType = worldProvider.getBlock(blockComp.getPosition()).getBlockFamily(); particleEffect.initialVelocityRange.set(4, 4, 4); particleEffect.spawnRange.set(0.3f, 0.3f, 0.3f); particleEffect.destroyEntityOnCompletion = true; particleEffect.minSize = 0.05f; particleEffect.maxSize = 0.1f; particleEffect.minLifespan = 1f; particleEffect.maxLifespan = 1.5f; particleEffect.targetVelocity.set(0, -5, 0); particleEffect.acceleration.set(2f, 2f, 2f); particleEffect.collideWithBlocks = true; particlesEntity.addComponent(particleEffect); // TODO: Don't play this if destroyed? // TODO: Configurable via block definition AudioManager.play(new AssetUri(AssetType.SOUND, "engine:Dig"), 1.0f); } }