package crazypants.enderio.item.darksteel;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.client.event.sound.PlaySoundSourceEvent;
import net.minecraftforge.event.entity.PlaySoundAtEntityEvent;
import com.enderio.core.common.util.Util;
import com.enderio.core.common.vecmath.Vector3d;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import crazypants.enderio.config.Config;
public class SoundDetector {
private static final int MAX_ENTITIES = 64;
public static SoundDetector instance = new SoundDetector();
private List<SoundSource> sounds;
private ArrayBlockingQueue<SoundSource> soundQueue = new ArrayBlockingQueue<SoundSource>(MAX_ENTITIES);
private Minecraft mc = Minecraft.getMinecraft();
boolean enabled = false;
double maxRangeSq = Config.darkSteelSoundLocatorRange * Config.darkSteelSoundLocatorRange;
@SubscribeEvent
public void onSound(PlaySoundAtEntityEvent evt) {
if(enabled && evt.entity != null && evt.entity != Minecraft.getMinecraft().thePlayer && soundQueue.size() < MAX_ENTITIES) {
soundQueue.offer(new SoundSource(evt.entity, evt.volume));
}
}
@SubscribeEvent
public void onSound(PlaySoundSourceEvent evt) {
if(enabled && soundQueue.size() < MAX_ENTITIES) {
soundQueue.offer(new SoundSource(evt.sound.getXPosF(), evt.sound.getYPosF(), evt.sound.getZPosF(), evt.sound.getVolume()));
}
}
@SideOnly(Side.CLIENT)
@SubscribeEvent
public void onClientTick(TickEvent.ClientTickEvent event) {
if(!enabled || mc.thePlayer == null || mc.thePlayer.worldObj == null) {
return;
}
sounds = new ArrayList<SoundSource>(MAX_ENTITIES);
soundQueue.drainTo(sounds);
try {
Vector3d eye = Util.getEyePositionEio(mc.thePlayer);
for (SoundSource ss : sounds) {
double distSq = ss.pos.distanceSquared(eye);
int minDist = ss.isEntity ? 4 : 49;
if(distSq > minDist && distSq <= maxRangeSq) {
mc.thePlayer.worldObj.spawnEntityInWorld(new SoundEntity(mc.thePlayer.worldObj, ss.pos, ss.volume));
}
}
} catch (Exception ex) {
//Probably not necessary anymore but saftey first!
}
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
private static class SoundSource {
Vector3d pos;
float volume;
boolean isEntity;
public SoundSource(Entity ent, float volume) {
AxisAlignedBB bb = ent.boundingBox;
if(bb != null) {
pos = new Vector3d(bb.minX + (bb.maxX - bb.minX) / 2, bb.minY + (bb.maxY - bb.minY) / 2, bb.minZ + (bb.maxZ - bb.minZ) / 2);
} else {
pos = new Vector3d(ent.posX, ent.posY, ent.posZ);
}
this.volume = volume;
isEntity = true;
}
public SoundSource(double x, double y, double z, float volume) {
pos = new Vector3d(x, y, z);
this.volume = volume;
isEntity = false;
}
}
}