package mods.eln.sixnode.electricalentitysensor; import mods.eln.generic.GenericItemUsingDamageDescriptor; import mods.eln.item.EntitySensorFilterDescriptor; import mods.eln.misc.Coordonate; import mods.eln.misc.INBTTReady; import mods.eln.misc.RcInterpolator; import mods.eln.misc.Utils; import mods.eln.sim.IProcess; import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.Vec3; import net.minecraft.world.World; import java.util.HashMap; import java.util.List; public class ElectricalEntitySensorSlowProcess implements IProcess, INBTTReady { ElectricalEntitySensorElement element; double timeCounter = 0; static final double refreshPeriode = 0.2; RcInterpolator rc1 = new RcInterpolator(0.4f); RcInterpolator rc2 = new RcInterpolator(0.4f); boolean oldState = false; boolean state = false; HashMap<Object, Vec3> lastEPos = new HashMap<Object, Vec3>(); public ElectricalEntitySensorSlowProcess(ElectricalEntitySensorElement element) { this.element = element; } @Override public void process(double time) { timeCounter += time; if (timeCounter > refreshPeriode) { timeCounter -= refreshPeriode; boolean useSpeed = element.descriptor.useEntitySpeed; double speedFactor = element.descriptor.speedFactor; Coordonate coord = element.sixNode.coordonate; ItemStack filterStack = element.getInventory().getStackInSlot(ElectricalEntitySensorContainer.filterId); Class filterClass = EntityLivingBase.class; if (filterStack != null) { GenericItemUsingDamageDescriptor gen = EntitySensorFilterDescriptor.getDescriptor(filterStack); if (gen != null && gen instanceof EntitySensorFilterDescriptor) { EntitySensorFilterDescriptor filter = (EntitySensorFilterDescriptor) gen; filterClass = filter.entityClass; } } World world = coord.world(); double rayMax = element.descriptor.maxRange; AxisAlignedBB bb = coord.getAxisAlignedBB((int) rayMax); List list = world.getEntitiesWithinAABB(filterClass, bb); double output = 0; for (Object o : list) { Entity e = (Entity) o; Vec3 lastPos; if ((lastPos = lastEPos.get(e)) != null) { double weight = 0.4; List<Block> blockList = Utils.traceRay(world, coord.x + 0.5, coord.y + 0.5, coord.z + 0.5, e.posX, e.posY + e.getEyeHeight(), e.posZ); boolean view = true; for (Block b : blockList) { if (b.isOpaqueCube()) { view = false; break; } } if (view) { if (e instanceof EntityPlayerMP) weight *= 2.0; double distance = Utils.getLength(coord.x + 0.5, coord.y + 0.5, coord.z + 0.5, e.posX, e.posY + e.getEyeHeight(), e.posZ); if (distance < rayMax) { double sf = 1; if (useSpeed) { sf = speedFactor * Utils.getLength(e.posX, e.posY, e.posZ, lastPos.xCoord, lastPos.yCoord, lastPos.zCoord); //Math.sqrt(e.motionX * e.motionX + e.motionY * e.motionY + e.motionZ * e.motionZ); // Utils.println(sf); } output += sf * weight * (rayMax - distance) / rayMax; } } } output = Math.min(1, output); lastEPos.put(e, Vec3.createVectorHelper(e.posX, e.posY, e.posZ)); } //Utils.println(output); rc1.setTarget((float) output); } rc1.step((float) time); rc2.setTarget(rc1.get()); rc2.step((float) time); element.outputGateProcess.setOutputNormalized(rc2.get()); state = element.outputGateProcess.getOutputNormalized() > 0.6; if (state != oldState) element.needPublish(); oldState = state; } @Override public void readFromNBT(NBTTagCompound nbt, String str) { rc1.readFromNBT(nbt, str + "rc1"); rc2.readFromNBT(nbt, str + "rc2"); } @Override public void writeToNBT(NBTTagCompound nbt, String str) { rc1.writeToNBT(nbt, str + "rc1"); rc2.writeToNBT(nbt, str + "rc2"); } }