package jas.spawner.modern.command; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import net.minecraft.command.ICommandSender; import net.minecraft.command.WrongUsageException; import net.minecraft.entity.Entity; import net.minecraft.util.ChatComponentText; import net.minecraft.util.MathHelper; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.World; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; public class CommandEntityStats extends CommandJasBase { public String getCommandName() { return "entitystats"; } private static class StatsTabulator { public float chunksMean; public float chunksMedian; public float chunksMode; public float distanceMean; public float distanceMedian; public float distanceMode; public StatsTabulator(StatsCounter counter) { chunksMean = mean(counter.entitiesInChunks); chunksMedian = median(counter.entitiesInChunks); chunksMode = mode(counter.entitiesInChunks); distanceMean = mean(counter.entitiesDistances); distanceMedian = median(counter.entitiesDistances); distanceMode = mode(counter.entitiesDistances); } private float mean(List<Float> numbers) { float sum = 0; for (Float number : numbers) { sum += number; } return sum / numbers.size(); } private float mode(List<Float> numbers) { Collections.sort(numbers); Integer longestRepeated = null; float longestValue = 0; int currentRepeated = 0; int currentValue = 0; for (Float number : numbers) { int value = (int) (number * 10000); // 10000 Chosen for 4 sig digits of accuracy if (currentValue == value) { currentRepeated++; if (longestRepeated == null || longestRepeated < currentRepeated) { longestValue = currentValue / 10000; longestRepeated = currentRepeated; } } else { currentRepeated = 0; currentValue = value; } } return longestRepeated == 1 ? -1 : longestValue; } private float median(List<Float> numbers) { Collections.sort(numbers); return numbers.get(numbers.size() / 2); } } private static class StatsCounter { private final List<Float> entitiesInChunks = new ArrayList<Float>(); private final List<Float> entitiesDistances = new ArrayList<Float>(); private final static int maxDistance = 1000000; public void addEntitiesFromChunk(Collection<Entity> collection) { entitiesInChunks.add((float)collection.size()); for (Entity entity : collection) { World world = entity.worldObj; Entity closestEntity = world.getClosestPlayerToEntity(entity, maxDistance); entitiesDistances.add(closestEntity != null ? entity.getDistanceToEntity(closestEntity) : maxDistance); } } } /** * Return the required permission level for this command. */ public int getRequiredPermissionLevel() { return 2; } @Override public String getCommandUsage(ICommandSender commandSender) { return "commands.jasentitystats.usage"; } @Override public void process(ICommandSender commandSender, String[] stringArgs) { if (stringArgs.length > 0) { throw new WrongUsageException("commands.jasentitystats.usage", new Object[0]); } World world = commandSender.getEntityWorld(); Multimap<ChunkCoordIntPair, Entity> entitiesPerChunk = ArrayListMultimap.create(); for (Object object : world.getLoadedEntityList()) { Entity entity = (Entity) object; entitiesPerChunk.put( new ChunkCoordIntPair(MathHelper.floor_double(entity.posX / 16.0D), MathHelper .floor_double(entity.posZ / 16.0D)), entity); } StatsCounter counter = new StatsCounter(); for (ChunkCoordIntPair chunkCoord : entitiesPerChunk.keySet()) { counter.addEntitiesFromChunk(entitiesPerChunk.get(chunkCoord)); } StatsTabulator tabulator = new StatsTabulator(counter); StringBuilder disMsg = new StringBuilder(); disMsg.append("Entity Density: "); disMsg.append("Mean [").append(String.format("%.2f", tabulator.chunksMean)).append("], "); disMsg.append("Median [").append(String.format("%.2f", tabulator.chunksMedian)).append("], "); disMsg.append("Mode [").append(String.format("%.2f", tabulator.chunksMode)).append("]"); commandSender.addChatMessage(new ChatComponentText(disMsg.toString())); disMsg = new StringBuilder(); disMsg.append("Distance To Player: "); disMsg.append("Mean [").append(String.format("%.2f", tabulator.distanceMean)).append("], "); disMsg.append("Median [").append(String.format("%.2f", tabulator.distanceMedian)).append("], "); disMsg.append("Mode [").append(String.format("%.2f", tabulator.distanceMode)).append("]"); commandSender.addChatMessage(new ChatComponentText(disMsg.toString())); } /** * Adds the strings available in this command to the given list of tab completion options. */ @Override public List<String> getTabCompletions(ICommandSender commandSender, String[] stringArgs) { return Collections.emptyList(); } }