package jas.spawner.legacy.command; import jas.spawner.legacy.TAGProfile; import jas.spawner.legacy.spawner.biome.group.BiomeHelper; import jas.spawner.legacy.spawner.biome.structure.StructureHandler; import jas.spawner.legacy.spawner.creature.entry.BiomeSpawnListRegistry; import jas.spawner.legacy.spawner.creature.entry.SpawnListEntry; import jas.spawner.legacy.spawner.creature.handler.LivingGroupRegistry; import jas.spawner.legacy.spawner.creature.handler.LivingHandler; import jas.spawner.legacy.spawner.creature.handler.LivingHelper; import jas.spawner.legacy.spawner.creature.type.CreatureType; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import net.minecraft.command.ICommandSender; import net.minecraft.command.WrongUsageException; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ChatComponentText; import net.minecraft.world.biome.BiomeGenBase; import com.google.common.collect.ImmutableCollection; public class CommandCanSpawnHere extends CommandJasBase { /* * Number of trials to run canSpawnHere to rule out random chance of success/failure. * * This was chosen such that to give a ~95% accuracy to the minimum accepted deviation in chance which is 1%. Any * entity that spawns at least 1% of the time should be detected properly >=95% of the time. * * CHANCE_OF_SUCCESS = 0.95 >= = 1-(1-TRIAL_CHANCE/100)^SIMULATION_TRIALS. TRIAL_CHANCE is chance out of 100 that * the entity would spawn. */ private static final int SIMULATION_TRIALS = 300; public String getCommandName() { return "canspawnhere"; } /** * Return the required permission level for this command. */ public int getRequiredPermissionLevel() { return 2; } @Override public String getCommandUsage(ICommandSender commandSender) { return "commands.jascanspawnhere.usage"; } @Override public void process(ICommandSender commandSender, String[] stringArgs) { if (stringArgs.length == 0 || stringArgs.length > 2) { throw new WrongUsageException("commands.jascanspawnhere.usage", new Object[0]); } EntityPlayer targetPlayer = stringArgs.length == 1 ? getPlayer(commandSender, commandSender.getCommandSenderName()) : getPlayer(commandSender, stringArgs[0]); String entityName = stringArgs.length == 1 ? stringArgs[0] : stringArgs[1]; if (!isValidEntityName(entityName)) { throw new WrongUsageException("commands.jascanspawnhere.entitynotfound", new Object[0]); } EntityLiving entity = getTargetEntity(entityName, targetPlayer); LivingGroupRegistry groupRegistry = TAGProfile.worldSettings().livingGroupRegistry(); ImmutableCollection<String> groupIDs = groupRegistry.getGroupsWithEntity(groupRegistry.EntityClasstoJASName .get(entity.getClass())); if(groupIDs.isEmpty()) { throw new WrongUsageException("commands.jascanspawnhere.entityhasnogroups", new Object[0]); } for (String groupID : groupIDs) { LivingHandler livingHandler = TAGProfile.worldSettings().livingHandlerRegistry() .getLivingHandler(groupID); CreatureType livingType = TAGProfile.worldSettings().creatureTypeRegistry() .getCreatureType(livingHandler.creatureTypeID); if (livingType == null) { commandSender.addChatMessage(new ChatComponentText(String.format( "Entity %s is of type NONE and thus will never spawn.", entityName))); return; } /* Get local spawnlist. Reminder: Biomes are only used when a structure is absent or empty */ boolean isBiome = false; List<SpawnListEntry> spawnlistentries = new ArrayList<SpawnListEntry>(3); String locationName = getMatchingStructureSpawnListEntries(groupID, entity, spawnlistentries); String structureName = locationName; if (spawnlistentries.isEmpty()) { isBiome = true; locationName = getMatchingBiomeSpawnListEntries(groupID, entity, livingType, spawnlistentries); } if (spawnlistentries.isEmpty()) { spawnlistentries.add(null); } StringBuilder resultMessage = new StringBuilder(); if (groupIDs.size() > 1) { resultMessage.append("{Group ").append(groupID).append(": "); } Iterator<SpawnListEntry> iterator = spawnlistentries.iterator(); while (iterator.hasNext()) { SpawnListEntry spawnListEntry = iterator.next(); if (spawnlistentries.size() > 1) { resultMessage.append("{"); } resultMessage .append(canEntitySpawnHere(targetPlayer, entity, livingHandler, livingType, spawnListEntry, entityName)).append(": "); resultMessage.append(canEntityTypeSpawnHere(targetPlayer, entity, livingType)).append(" "); resultMessage.append(canLivingHandlerSpawnHere(targetPlayer, entity, livingHandler)).append(" "); if (!isBiome) { resultMessage.append(canSpawnListSpawnHere(targetPlayer, entity, livingHandler, spawnListEntry, locationName, false)); } else { /* If structureName is !null a structure is present but the spawnlist was empty so default to biome */ if (structureName != null) { resultMessage.append("\u00A7b").append("Empty S: ").append(structureName) .append(" spawnlist defaults to biome. ").append("\u00A7r"); } resultMessage.append(canSpawnListSpawnHere(targetPlayer, entity, livingHandler, spawnListEntry, locationName, true)); } if (spawnlistentries.size() > 1) { resultMessage.append("}"); if (iterator.hasNext()) { resultMessage.append(" "); } } } if (groupIDs.size() > 1) { resultMessage.append("}"); } commandSender.addChatMessage(new ChatComponentText(resultMessage.toString())); } } private boolean isValidEntityName(String entityName) { LivingGroupRegistry livingGroupRegistry = TAGProfile.worldSettings().livingGroupRegistry(); for (String mapping : livingGroupRegistry.JASNametoEntityClass.keySet()) { if (entityName.equals(mapping)) { return true; } } return false; } private EntityLiving getTargetEntity(String entityName, EntityPlayer targetPlayer) { EntityLiving entity; try { LivingGroupRegistry livingGroupRegistry = TAGProfile.worldSettings().livingGroupRegistry(); @SuppressWarnings("unchecked") Class<? extends EntityLiving> entityClass = livingGroupRegistry.JASNametoEntityClass.get(entityName); entity = (EntityLiving) LivingHelper.instantiateEntity(entityClass, targetPlayer.worldObj); } catch (Exception exception) { throw new WrongUsageException("commands.jascanspawnhere.cannotinstantiateentity", new Object[0]); } entity.setLocationAndAngles(targetPlayer.posX, targetPlayer.posY, targetPlayer.posZ, targetPlayer.rotationYaw, targetPlayer.rotationPitch); return entity; } private String getMatchingStructureSpawnListEntries(String livingGroupID, EntityLiving entity, Collection<SpawnListEntry> matchingSpawnListEntries) { String structureName; for (StructureHandler StructureHandler : TAGProfile.worldSettings().structureHandlerRegistry() .handlers()) { structureName = StructureHandler.getStructure(entity.worldObj, (int) entity.posX, (int) entity.posY, (int) entity.posZ); if (structureName != null) { for (String structureKey : StructureHandler.getStructureKeys()) { if (structureName.equals(structureKey)) { for (SpawnListEntry entry : StructureHandler.getStructureSpawnList(structureKey)) { if (livingGroupID.equals(entry.livingGroupID)) { matchingSpawnListEntries.add(entry); } } return structureKey; } } } } return null; } private String getMatchingBiomeSpawnListEntries(String livingGroupID, Entity entity, CreatureType livingType, Collection<SpawnListEntry> matchingSpawnListEntries) { BiomeGenBase biome = entity.worldObj.getBiomeGenForCoords((int) entity.posX, (int) entity.posZ); String packageBiome = BiomeHelper.getPackageName(biome); BiomeSpawnListRegistry biomeSpawnListRegistry = TAGProfile.worldSettings().biomeSpawnListRegistry(); for (SpawnListEntry spawnListEntry : biomeSpawnListRegistry.getSpawnListFor(livingType.typeID, packageBiome)) { if (spawnListEntry.livingGroupID.equals(livingGroupID)) { matchingSpawnListEntries.add(spawnListEntry); } } String shortName = TAGProfile.worldSettings().biomeGroupRegistry().biomePckgToMapping().get(packageBiome); return shortName == null ? biome.biomeName : shortName; } private String canEntitySpawnHere(EntityPlayer targetPlayer, EntityLiving entity, LivingHandler livingHandler, CreatureType livingType, SpawnListEntry spawnListEntry, String entityName) { String successMessage = "\u00A7a".concat(entityName).concat(" can spawn").concat("\u00A7r"); String failureMessage = "\u00A7c".concat(entityName).concat(" cannot spawn").concat("\u00A7r"); /* Check Entity Type */ { boolean tempSpawning = targetPlayer.preventEntitySpawning; targetPlayer.preventEntitySpawning = false; boolean canTypeSpawn = livingType.canSpawnAtLocation(entity.worldObj, (int) entity.posX, (int) entity.posY, (int) entity.posZ); targetPlayer.preventEntitySpawning = tempSpawning; if (canTypeSpawn == false) { return failureMessage; } } boolean tempSpawning = targetPlayer.preventEntitySpawning; targetPlayer.preventEntitySpawning = false; boolean canSpawn = false; if (spawnListEntry != null) { for (int i = 0; i < SIMULATION_TRIALS; i++) { if (livingHandler.getCanSpawnHere(entity, spawnListEntry)) { canSpawn = true; break; } } } targetPlayer.preventEntitySpawning = tempSpawning; if (canSpawn) { return successMessage; } else { return failureMessage; } } private String canEntityTypeSpawnHere(EntityPlayer targetPlayer, EntityLiving entity, CreatureType livingType) { boolean tempSpawning = targetPlayer.preventEntitySpawning; targetPlayer.preventEntitySpawning = false; boolean canSpawn = false; for (int i = 0; i < SIMULATION_TRIALS; i++) { if (livingType.canSpawnAtLocation(entity.worldObj, (int) entity.posX, (int) entity.posY, (int) entity.posZ)) { canSpawn = true; break; } } targetPlayer.preventEntitySpawning = tempSpawning; if (canSpawn) { return "\u00A7a".concat(livingType.typeID).concat(" can spawn.").concat("\u00A7r"); } else { return "\u00A7c".concat(livingType.typeID).concat(" cannot spawn.").concat("\u00A7r"); } } private String canLivingHandlerSpawnHere(EntityPlayer targetPlayer, EntityLiving entity, LivingHandler livingHandler) { boolean tempSpawning = targetPlayer.preventEntitySpawning; targetPlayer.preventEntitySpawning = false; boolean canSpawn = false; for (int i = 0; i < SIMULATION_TRIALS; i++) { if (livingHandler.isValidLiving(entity)) { canSpawn = true; break; } } targetPlayer.preventEntitySpawning = tempSpawning; if (canSpawn) { return "\u00A7a".concat("Livinghandler can spawn.").concat("\u00A7r"); } else { return "\u00A7c".concat("Livinghandler cannot spawn.").concat("\u00A7r"); } } private String canSpawnListSpawnHere(EntityPlayer targetPlayer, EntityLiving entity, LivingHandler livingHandler, SpawnListEntry spawnListEntry, String locationName, boolean isBiome) { if (spawnListEntry == null) { return "\u00A7c".concat("Entity not in B:").concat(locationName).concat(" spawnlist").concat("\u00A7r"); } if (!spawnListEntry.getOptionalSpawning().isOptionalEnabled()) { return "\u00A7a".concat("No ").concat(isBiome ? "B:" : "S:").concat(locationName).concat(" tags.") .concat("\u00A7r"); } boolean tempSpawning = targetPlayer.preventEntitySpawning; targetPlayer.preventEntitySpawning = false; boolean canSpawn = false; for (int i = 0; i < SIMULATION_TRIALS; i++) { if (livingHandler.isValidSpawnList(entity, spawnListEntry)) { canSpawn = true; break; } } targetPlayer.preventEntitySpawning = tempSpawning; if (canSpawn) { return "\u00A7a".concat("Can spawn in ").concat(isBiome ? "B:" : "S:").concat(locationName).concat(".") .concat("\u00A7r"); } else { return "\u00A7c".concat("Cannot spawn in ").concat(isBiome ? "B:" : "S:").concat(locationName).concat(".") .concat("\u00A7r"); } } /** * Adds the strings available in this command to the given list of tab completion options. */ @Override public List<String> getTabCompletions(ICommandSender commandSender, String[] stringArgs) { stringArgs = correctedParseArgs(stringArgs, false); List<String> tabCompletions = new ArrayList<String>(); if (stringArgs.length == 1) { addPlayerUsernames(tabCompletions); addEntityNames(tabCompletions); } else if (stringArgs.length == 2) { addEntityNames(tabCompletions); } if (!tabCompletions.isEmpty()) { return getStringsMatchingLastWord(stringArgs, tabCompletions); } else { return tabCompletions; } } }