package com.dynious.biota.event;
import com.dynious.biota.api.IBiotaAPI;
import com.dynious.biota.asm.Hooks;
import com.dynious.biota.biosystem.BioSystem;
import com.dynious.biota.biosystem.BioSystemHandler;
import com.dynious.biota.config.PlantConfig;
import com.dynious.biota.helper.WorldHelper;
import com.dynious.biota.item.ModItems;
import com.dynious.biota.lib.MathLib;
import com.dynious.biota.lib.Settings;
import com.dynious.biota.network.NetworkHandler;
import com.dynious.biota.network.message.MessageBioSystemUpdate;
import cpw.mods.fml.common.eventhandler.Event;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import net.minecraft.block.material.Material;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.event.entity.player.BonemealEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.event.world.ChunkDataEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.ChunkWatchEvent;
import squeek.applecore.api.plants.FertilizationEvent;
import squeek.applecore.api.plants.PlantGrowthEvent;
public class CommonEventHandler
{
@SubscribeEvent
public void onChuckDataLoad(ChunkDataEvent.Load event)
{
//Chunk read from disk
NBTTagCompound compound = event.getData().getCompoundTag("Biota");
BioSystemHandler.onChunkLoaded(event.world, event.getChunk(), compound);
}
@SubscribeEvent
public void onChuckLoad(ChunkEvent.Load event)
{
if (!event.getChunk().worldObj.isRemote)
{
BioSystemHandler.onChunkLoaded(event.world, event.getChunk());
}
}
@SubscribeEvent
public void onChuckDataSave(ChunkDataEvent.Save event)
{
//Chunk saved to disk
BioSystem bioSystem = BioSystemHandler.getBioSystem(event.world, event.getChunk());
if (bioSystem != null)
{
NBTTagCompound compound = new NBTTagCompound();
bioSystem.saveToNBT(compound);
event.getData().setTag("Biota", compound);
}
if (!event.getChunk().isChunkLoaded)
BioSystemHandler.onChunkUnload(event.world, event.getChunk());
}
@SubscribeEvent
public void tick(TickEvent.WorldTickEvent event)
{
if (event.phase == TickEvent.Phase.END)
{
event.world.theProfiler.startSection("bioSystem");
BioSystemHandler handler = BioSystemHandler.get(event.world);
if (handler != null)
handler.update();
event.world.theProfiler.endSection();
}
}
//TODO: Check if loading & unloading works so no memory leaks will happen
@SubscribeEvent
public void onPlayWatchChunk(ChunkWatchEvent.Watch event)
{
Chunk chunk = event.player.worldObj.getChunkFromChunkCoords(event.chunk.chunkXPos, event.chunk.chunkZPos);
BioSystem bioSystem = BioSystemHandler.getBioSystem(event.player.worldObj, chunk);
if (bioSystem != null)
{
NetworkHandler.INSTANCE.sendTo(new MessageBioSystemUpdate(bioSystem), event.player);
}
}
@SubscribeEvent
public void allowPlantGrowth(PlantGrowthEvent.AllowGrowthTick event)
{
Chunk chunk = event.world.getChunkFromBlockCoords(event.x, event.z);
BioSystem bioSystem = BioSystemHandler.getBioSystem(event.world, chunk);
if (bioSystem != null)
{
int meta = event.world.getBlockMetadata(event.x, event.y, event.z);
float lowestNutrientPart = PlantConfig.getLowestNutrientPart(event.block, meta, bioSystem.getPhosphorus(), bioSystem.getPotassium(), bioSystem.getNitrogen());
float nutrientGrowChance = MathLib.getFittedValue(lowestNutrientPart, Settings.NUTRIENT_AMOUNT_FOR_STOP_GROWTH, Settings.NUTRIENT_AMOUNT_FOR_NORMAL_GROWTH, Settings.NUTRIENT_AMOUNT_FOR_MAX_GROWTH);
int lightValue = event.block.isOpaqueCube() ? WorldHelper.getLightValue(event.world, event.x, event.y + 1, event.z) : WorldHelper.getLightValue(event.world, event.x, event.y, event.z);
float lightGrowChance = MathLib.getFittedValue(lightValue, Settings.LIGHT_VALUE_FOR_STOP_GROWTH, Settings.LIGHT_VALUE_FOR_NORMAL_GROWTH, Settings.LIGHT_VALUE_FOR_MAX_GROWTH);
if (Math.min(nutrientGrowChance, lightGrowChance) < event.world.rand.nextFloat())
{
event.setResult(Event.Result.DENY);
}
}
}
@SubscribeEvent
public void onPlantGrowth(PlantGrowthEvent.GrowthTick event)
{
Chunk chunk = event.world.getChunkFromBlockCoords(event.x, event.z);
BioSystem bioSystem = BioSystemHandler.getBioSystem(event.world, chunk);
if (bioSystem != null)
{
int newMeta = event.world.getBlockMetadata(event.x, event.y, event.z);
float biomassChange = PlantConfig.getPlantBlockBiomassValue(event.block, newMeta) - PlantConfig.getPlantBlockBiomassValue(event.block, event.previousMetadata);
bioSystem.onGrowth(biomassChange, true);
}
}
@SubscribeEvent
public void onBockPlaceEvent(BlockEvent.PlaceEvent event)
{
//Fix Forge (bug?) where onBlockAdded is called twice when a player places a block. This will also make sure
//that if the block place event is cancelled no biomass will be added.
//This basically just reverses one of the onBlockPlace events.
Hooks.onPlantBlockRemoved(event.placedBlock, event.world, event.x, event.y, event.z);
}
@SubscribeEvent
public void onBonemealUsedEvent(BonemealEvent event)
{
Chunk chunk = event.world.getChunkFromBlockCoords(event.x, event.z);
if (IBiotaAPI.API.addNutrientsToBioSystem(event.world, chunk, Settings.BONEMEAL_PHOSPHORUS, Settings.BONEMEAL_POTASSIUM, Settings.BONEMEAL_NITROGEN))
event.setResult(Event.Result.ALLOW);
else
event.setCanceled(true);
}
@SubscribeEvent
public void allowFertilization(FertilizationEvent.Fertilize event)
{
event.setResult(Event.Result.DENY);
}
@SubscribeEvent
public void onFertilization(FertilizationEvent.Fertilized event)
{
Chunk chunk = event.world.getChunkFromBlockCoords(event.x, event.z);
BioSystem bioSystem = BioSystemHandler.getBioSystem(event.world, chunk);
if (bioSystem != null)
{
int newMeta = event.world.getBlockMetadata(event.x, event.y, event.z);
float biomassChange = PlantConfig.getPlantBlockBiomassValue(event.block, newMeta) - PlantConfig.getPlantBlockBiomassValue(event.block, event.previousMetadata);
bioSystem.onGrowth(biomassChange, true);
}
}
@SubscribeEvent
public void onBlockDrops(BlockEvent.HarvestDropsEvent event)
{
if (event.block == Blocks.clay && !event.isSilkTouching)
{
for (int x = event.x - 1; x < event.x + 1; x++)
{
for (int y = event.y - 1; y < event.y + 1; y++)
{
for (int z = event.z - 1; z < event.z + 1; z++)
{
if (event.world.getBlock(x, y, z).getMaterial() == Material.water)
{
int fortune = event.fortuneLevel;
if (fortune > 3)
fortune = 3;
if (event.world.rand.nextInt(10 - fortune * 3) == 0)
event.drops.add(new ItemStack(ModItems.potash));
return;
}
}
}
}
}
}
}