package mcjty.rftools; import cpw.mods.fml.common.eventhandler.Event; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import mcjty.lib.preferences.PlayerPreferencesProperties; import mcjty.lib.varia.Coordinate; import mcjty.lib.varia.GlobalCoordinate; import mcjty.lib.varia.Logging; import mcjty.lib.varia.WrenchChecker; import mcjty.rftools.blocks.blockprotector.BlockProtectorTileEntity; import mcjty.rftools.blocks.blockprotector.BlockProtectors; import mcjty.rftools.blocks.dimlets.DimletConfiguration; import mcjty.rftools.blocks.environmental.PeacefulAreaManager; import mcjty.rftools.dimension.DimensionInformation; import mcjty.rftools.dimension.DimensionStorage; import mcjty.rftools.dimension.RfToolsDimensionManager; import mcjty.rftools.dimension.world.types.EffectType; import mcjty.rftools.dimension.world.types.FeatureType; import mcjty.rftools.playerprops.PlayerExtendedProperties; import net.minecraft.block.Block; import net.minecraft.block.BlockBed; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.IAttributeInstance; import net.minecraft.entity.monster.IMob; import net.minecraft.entity.passive.IAnimals; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Vec3; import net.minecraft.world.ChunkPosition; import net.minecraft.world.Explosion; import net.minecraft.world.World; import net.minecraftforge.event.entity.EntityEvent; import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.event.entity.living.LivingFallEvent; import net.minecraftforge.event.entity.living.LivingSpawnEvent; import net.minecraftforge.event.entity.player.AttackEntityEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.terraingen.ChunkProviderEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.ExplosionEvent; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; public class ForgeEventHandlers { private Collection<GlobalCoordinate> getProtectors(World world, int x, int y, int z) { Collection<GlobalCoordinate> protectors; BlockProtectors blockProtectors = BlockProtectors.getProtectors(world); if (blockProtectors == null) { protectors = Collections.emptyList(); } else { int id = world.provider.dimensionId; protectors = blockProtectors.findProtectors(x, y, z, id, 2); } return protectors; } @SubscribeEvent public void onPlayerInteractEvent(PlayerInteractEvent event) { ItemStack heldItem = event.entityPlayer.getHeldItem(); if (heldItem == null || heldItem.getItem() == null) { return; } if (event.entityPlayer.isSneaking() && WrenchChecker.isAWrench(heldItem.getItem())) { // If the block is protected we prevent sneak-wrenching it. World world = event.world; int x = event.x; int y = event.y; int z = event.z; Collection<GlobalCoordinate> protectors = getProtectors(world, x, y, z); checkHarvestProtection(event, x, y, z, world, protectors); } } @SubscribeEvent public void onBlockBreakEvent(BlockEvent.BreakEvent event) { int x = event.x; int y = event.y; int z = event.z; World world = event.world; Collection<GlobalCoordinate> protectors = getProtectors(world, x, y, z); checkHarvestProtection(event, x, y, z, world, protectors); } private void checkHarvestProtection(Event event, int x, int y, int z, World world, Collection<GlobalCoordinate> protectors) { for (GlobalCoordinate protector : protectors) { int cx = protector.getCoordinate().getX(); int cy = protector.getCoordinate().getY(); int cz = protector.getCoordinate().getZ(); TileEntity te = world.getTileEntity(cx, cy, cz); if (te instanceof BlockProtectorTileEntity) { BlockProtectorTileEntity blockProtectorTileEntity = (BlockProtectorTileEntity) te; Coordinate relative = blockProtectorTileEntity.absoluteToRelative(x, y, z); boolean b = blockProtectorTileEntity.isProtected(relative); if (b) { if (blockProtectorTileEntity.attemptHarvestProtection()) { event.setCanceled(true); } else { blockProtectorTileEntity.removeProtection(relative); } return; } } } } @SubscribeEvent public void onDetonate(ExplosionEvent.Detonate event) { Explosion explosion = event.explosion; Collection<GlobalCoordinate> protectors = getProtectors(event.world, (int) explosion.explosionX, (int) explosion.explosionY, (int) explosion.explosionZ); if (protectors.isEmpty()) { return; } List<ChunkPosition> affectedBlocks = event.getAffectedBlocks(); List<ChunkPosition> toremove = new ArrayList<ChunkPosition>(); Vec3 explosionVector = Vec3.createVectorHelper(explosion.explosionX, explosion.explosionY, explosion.explosionZ); int rf = 0; for (GlobalCoordinate protector : protectors) { int cx = protector.getCoordinate().getX(); int cy = protector.getCoordinate().getY(); int cz = protector.getCoordinate().getZ(); TileEntity te = event.world.getTileEntity(cx, cy, cz); if (te instanceof BlockProtectorTileEntity) { BlockProtectorTileEntity blockProtectorTileEntity = (BlockProtectorTileEntity) te; for (ChunkPosition block : affectedBlocks) { Coordinate relative = blockProtectorTileEntity.absoluteToRelative(block.chunkPosX, block.chunkPosY, block.chunkPosZ); boolean b = blockProtectorTileEntity.isProtected(relative); if (b) { Vec3 blockVector = Vec3.createVectorHelper(block.chunkPosX, block.chunkPosY, block.chunkPosZ); double distanceTo = explosionVector.distanceTo(blockVector); int rfneeded = blockProtectorTileEntity.attemptExplosionProtection((float) (distanceTo / explosion.explosionSize), explosion.explosionSize); if (rfneeded > 0) { toremove.add(block); rf += rfneeded; } else { blockProtectorTileEntity.removeProtection(relative); } } } } } for (ChunkPosition block : toremove) { affectedBlocks.remove(block); } Logging.logDebug("RF Needed for one explosion:" + rf); } @SubscribeEvent public void onAttackEntityEvent(AttackEntityEvent event) { World world = event.entityPlayer.getEntityWorld(); int id = world.provider.dimensionId; RfToolsDimensionManager dimensionManager = RfToolsDimensionManager.getDimensionManager(world); if (dimensionManager.getDimensionInformation(id) != null) { // RFTools dimension. DimensionStorage storage = DimensionStorage.getDimensionStorage(world); int energy = storage.getEnergyLevel(id); if (energy <= 0) { event.setCanceled(true); } } } @SubscribeEvent public void onEntityConstructingEvent(EntityEvent.EntityConstructing event) { if (event.entity instanceof EntityPlayer) { PlayerExtendedProperties properties = new PlayerExtendedProperties(); event.entity.registerExtendedProperties(PlayerExtendedProperties.ID, properties); PlayerPreferencesProperties preferencesProperties = (PlayerPreferencesProperties) event.entity.getExtendedProperties(PlayerPreferencesProperties.ID); if (preferencesProperties == null) { preferencesProperties = new PlayerPreferencesProperties(); event.entity.registerExtendedProperties(PlayerPreferencesProperties.ID, preferencesProperties); } } } @SubscribeEvent public void onPlayerInterractEvent(PlayerInteractEvent event) { if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) { World world = event.world; if (!world.isRemote) { Block block = world.getBlock(event.x, event.y, event.z); if (block instanceof BlockBed) { RfToolsDimensionManager dimensionManager = RfToolsDimensionManager.getDimensionManager(world); if (dimensionManager.getDimensionInformation(world.provider.dimensionId) != null) { // We are in an RFTools dimension. switch (DimletConfiguration.bedBehaviour) { case 0: event.setCanceled(true); Logging.message(event.entityPlayer, "You cannot sleep in this dimension!"); break; case 1: // Just do the usual thing (this typically mean explosion). break; case 2: event.setCanceled(true); int meta = BedControl.getBedMeta(world, event.x, event.y, event.z); if (meta != -1) { BedControl.trySleep(world, event.entityPlayer, event.x, event.y, event.z, meta); } break; } } } } } } @SubscribeEvent public void onEntityJoinWorldEvent(EntityJoinWorldEvent event) { World world = event.world; if (world.isRemote) { return; } int id = world.provider.dimensionId; RfToolsDimensionManager dimensionManager = RfToolsDimensionManager.getDimensionManager(world); DimensionInformation dimensionInformation = dimensionManager.getDimensionInformation(id); if (dimensionInformation != null && dimensionInformation.isNoanimals()) { if (event.entity instanceof IAnimals && !(event.entity instanceof IMob)) { event.setCanceled(true); Logging.logDebug("Noanimals dimension: Prevented a spawn of " + event.entity.getClass().getName()); } } } @SubscribeEvent public void onEntitySpawnEvent(LivingSpawnEvent.CheckSpawn event) { World world = event.world; int id = world.provider.dimensionId; RfToolsDimensionManager dimensionManager = RfToolsDimensionManager.getDimensionManager(world); DimensionInformation dimensionInformation = dimensionManager.getDimensionInformation(id); if (DimletConfiguration.preventSpawnUnpowered) { if (dimensionInformation != null) { // RFTools dimension. DimensionStorage storage = DimensionStorage.getDimensionStorage(world); int energy = storage.getEnergyLevel(id); if (energy <= 0) { event.setResult(Event.Result.DENY); Logging.logDebug("Dimension power low: Prevented a spawn of " + event.entity.getClass().getName()); } } } if (dimensionInformation != null) { if (dimensionInformation.hasEffectType(EffectType.EFFECT_STRONGMOBS) || dimensionInformation.hasEffectType(EffectType.EFFECT_BRUTALMOBS)) { if (event.entity instanceof EntityLivingBase) { EntityLivingBase entityLivingBase = (EntityLivingBase) event.entity; IAttributeInstance entityAttribute = entityLivingBase.getEntityAttribute(SharedMonsterAttributes.maxHealth); double newMax; if (dimensionInformation.hasEffectType(EffectType.EFFECT_BRUTALMOBS)) { newMax = entityAttribute.getBaseValue() * DimletConfiguration.brutalMobsFactor; } else { newMax = entityAttribute.getBaseValue() * DimletConfiguration.strongMobsFactor; } entityAttribute.setBaseValue(newMax); entityLivingBase.setHealth((float) newMax); } } } if (event.entity instanceof IMob) { Coordinate coordinate = new Coordinate((int) event.entity.posX, (int) event.entity.posY, (int) event.entity.posZ); if (PeacefulAreaManager.isPeaceful(new GlobalCoordinate(coordinate, id))) { event.setResult(Event.Result.DENY); Logging.logDebug("Peaceful manager: Prevented a spawn of " + event.entity.getClass().getName()); } else if (dimensionInformation != null && dimensionInformation.isPeaceful()) { // RFTools dimension. event.setResult(Event.Result.DENY); Logging.logDebug("Peaceful dimension: Prevented a spawn of " + event.entity.getClass().getName()); } } else if (event.entity instanceof IAnimals) { if (dimensionInformation != null && dimensionInformation.isNoanimals()) { // RFTools dimension. event.setResult(Event.Result.DENY); Logging.logDebug("Noanimals dimension: Prevented a spawn of " + event.entity.getClass().getName()); } } } @SubscribeEvent public void onLivingFallEvent(LivingFallEvent event) { if (event.entity instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer) event.entity; PlayerExtendedProperties playerExtendedProperties = PlayerExtendedProperties.getProperties(player); if (!player.worldObj.isRemote) { if (playerExtendedProperties.getBuffProperties().hasBuff(PlayerBuff.BUFF_FEATHERFALLING)) { event.distance /= 2.0f; } else if (playerExtendedProperties.getBuffProperties().hasBuff(PlayerBuff.BUFF_FEATHERFALLINGPLUS)) { event.distance /= 8.0f; } } } } @SubscribeEvent public void onReplaceBiomeBlocks(ChunkProviderEvent.ReplaceBiomeBlocks event) { World world = event.world; if (world == null) { return; } int id = world.provider.dimensionId; RfToolsDimensionManager dimensionManager = RfToolsDimensionManager.getDimensionManager(world); DimensionInformation information = dimensionManager.getDimensionInformation(id); if (information != null && information.hasFeatureType(FeatureType.FEATURE_CLEAN)) { event.setResult(Event.Result.DENY); } } }