package drzhark.customspawner; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.logging.Logger; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.passive.EntityBat; import net.minecraft.entity.passive.EntityChicken; import net.minecraft.entity.passive.EntityCow; import net.minecraft.entity.passive.EntityOcelot; import net.minecraft.entity.passive.EntityPig; import net.minecraft.entity.passive.EntitySheep; import net.minecraft.entity.passive.EntitySquid; import net.minecraft.entity.passive.EntityWolf; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.util.WeightedRandom; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.ChunkPosition; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraft.world.biome.BiomeGenBase; import net.minecraft.world.biome.BiomeGenEnd; import net.minecraft.world.biome.BiomeGenHell; import net.minecraft.world.biome.SpawnListEntry; import net.minecraft.world.chunk.Chunk; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.Event.Result; import cpw.mods.fml.common.FMLLog; //import net.minecraftforge.event.entity.living.LivingSpecialSpawnEvent; import cpw.mods.fml.common.Mod; import drzhark.mocreatures.MoCreatures; @Mod(modid = "CustomSpawner", name = "DrZhark's CustomSpawner", version = "1.12.5") public final class CustomSpawner { private int maxAnimals = 40; private int maxMobs = 60; private int maxAquatic = 10; private int maxAmbient = 10; public List<BiomeGenBase> biomeList; public List[] entityClasses; protected List[] customMobSpawnList; protected List[] customAmbientSpawnList; protected List[] customCreatureSpawnList; protected List[] customAquaticSpawnList; private List<Class> vanillaClassList; private static Logger log = Logger.getLogger("CustomSpawner"); private static HashMap eligibleChunksForSpawning = new HashMap(); public CustomSpawner() { biomeList = new ArrayList<BiomeGenBase>(); log.setParent(FMLLog.getLogger()); try { for (BiomeGenBase biomegenbase : BiomeGenBase.biomeList) { if (biomegenbase == null) { continue; } biomeList.add(biomegenbase); } customCreatureSpawnList = new List[biomeList.size()]; customMobSpawnList = new List[biomeList.size()]; customAmbientSpawnList = new List[biomeList.size()]; customAquaticSpawnList = new List[biomeList.size()]; entityClasses = new List[4]; vanillaClassList = new ArrayList<Class>(); vanillaClassList.add(EntityChicken.class); vanillaClassList.add(EntityCow.class); vanillaClassList.add(EntityPig.class); vanillaClassList.add(EntitySheep.class); vanillaClassList.add(EntityWolf.class); vanillaClassList.add(EntitySquid.class); vanillaClassList.add(EntityOcelot.class); vanillaClassList.add(EntityBat.class); clearLists(); } catch (Exception ex) { throw new RuntimeException(ex); } } protected static ChunkPosition getRandomSpawningPointInChunk(World worldObj, int par1, int par2) { Chunk chunk = worldObj.getChunkFromChunkCoords(par1, par2); int i = par1 * 16 + worldObj.rand.nextInt(16); int j = worldObj.rand.nextInt(chunk == null ? worldObj.getActualHeight() : chunk.getTopFilledSegment() + 16 - 1); int k = par2 * 16 + worldObj.rand.nextInt(16); return new ChunkPosition(i, j, k); } public void clearLists() { for (int x = 0; x < biomeList.size(); x++) { customCreatureSpawnList[x] = new ArrayList(); customMobSpawnList[x] = new ArrayList(); customAmbientSpawnList[x] = new ArrayList(); customAquaticSpawnList[x] = new ArrayList(); } for (int x = 0; x < 4; x++) { entityClasses[x] = new ArrayList(); } } //this one spawns a single mob up to max times public final int doSpecificSpawning(WorldServer worldObj, Class myClass, int max, EnumCreatureType enumcreaturetype) { //this initialises chunks for spawning eligibleChunksForSpawning.clear(); int countTotal; int var6; for (countTotal = 0; countTotal < worldObj.playerEntities.size(); ++countTotal) { EntityPlayer entityplayer = (EntityPlayer) worldObj.playerEntities.get(countTotal); int var5 = MathHelper.floor_double(entityplayer.posX / 16.0D); var6 = MathHelper.floor_double(entityplayer.posZ / 16.0D); byte var7 = 8; for (int var8 = -var7; var8 <= var7; ++var8) { for (int var9 = -var7; var9 <= var7; ++var9) { boolean var10 = var8 == -var7 || var8 == var7 || var9 == -var7 || var9 == var7; ChunkCoordIntPair var11 = new ChunkCoordIntPair(var8 + var5, var9 + var6); if (!var10) { eligibleChunksForSpawning.put(var11, Boolean.valueOf(false)); } else if (!eligibleChunksForSpawning.containsKey(var11)) { eligibleChunksForSpawning.put(var11, Boolean.valueOf(true)); } } } } countTotal = 0; ChunkCoordinates chunkcoordspawn = worldObj.getSpawnPoint(); Iterator iterator = eligibleChunksForSpawning.keySet().iterator(); label113: while (iterator.hasNext()) { ChunkCoordIntPair var10 = (ChunkCoordIntPair) iterator.next(); ChunkPosition chunkpos = getRandomSpawningPointInChunk(worldObj, var10.chunkXPos * 16, var10.chunkZPos * 16); int chunkX = chunkpos.x; int chunkY = chunkpos.y; int chunkZ = chunkpos.z; if (!worldObj.isBlockNormalCube(chunkX, chunkY, chunkZ) && worldObj.getBlockMaterial(chunkX, chunkY, chunkZ) == enumcreaturetype.getCreatureMaterial()) { int countSpawn = 0; for (int var21 = 0; var21 < 3; ++var21) { int tempPosX = chunkX; int tempPosY = chunkY; int tempPosZ = chunkZ; byte var25 = 6; for (int var26 = 0; var26 < 4; ++var26) { tempPosX += worldObj.rand.nextInt(var25) - worldObj.rand.nextInt(var25); tempPosY += worldObj.rand.nextInt(1) - worldObj.rand.nextInt(1); tempPosZ += worldObj.rand.nextInt(var25) - worldObj.rand.nextInt(var25); if (canCreatureTypeSpawnAtLocation(enumcreaturetype, worldObj, tempPosX, tempPosY, tempPosZ)) { float finalPosX = (float) tempPosX + 0.5F; float finalPosY = (float) tempPosY; float finalPosZ = (float) tempPosZ + 0.5F; if (worldObj.getClosestPlayer((double) finalPosX, (double) finalPosY, (double) finalPosZ, 24.0D) == null) { float distSpawnX = finalPosX - (float) chunkcoordspawn.posX; float distSpawnY = finalPosY - (float) chunkcoordspawn.posY; float distSpawnZ = finalPosZ - (float) chunkcoordspawn.posZ; float sqDist = distSpawnX * distSpawnX + distSpawnY * distSpawnY + distSpawnZ * distSpawnZ; if (sqDist >= 576.0F) { EntityLiving entityliving; try { entityliving = (EntityLiving) myClass.getConstructor(new Class[] { World.class }).newInstance(new Object[] { worldObj }); } catch (Exception exception) { exception.printStackTrace(); return countTotal; } entityliving.setLocationAndAngles((double) finalPosX, (double) finalPosY, (double) finalPosZ, worldObj.rand.nextFloat() * 360.0F, 0.0F); if (entityliving.getCanSpawnHere()) { ++countSpawn; countTotal += countSpawn; if (countTotal > max) { return countTotal; } worldObj.spawnEntityInWorld(entityliving); if (countSpawn >= entityliving.getMaxSpawnedInChunk()) { continue label113; } } } } } } } } } return countTotal; } /** * New customSpawner * * */ public final int doCustomSpawning(WorldServer worldObj, boolean spawnMobs, boolean spawnAnmls) { if (!spawnMobs && !spawnAnmls) { return 0; } else { eligibleChunksForSpawning.clear(); int countTotal; int var6; for (countTotal = 0; countTotal < worldObj.playerEntities.size(); ++countTotal) { EntityPlayer entityplayer = (EntityPlayer) worldObj.playerEntities.get(countTotal); int var5 = MathHelper.floor_double(entityplayer.posX / 16.0D); var6 = MathHelper.floor_double(entityplayer.posZ / 16.0D); byte var7 = 8; for (int var8 = -var7; var8 <= var7; ++var8) { for (int var9 = -var7; var9 <= var7; ++var9) { boolean var10 = var8 == -var7 || var8 == var7 || var9 == -var7 || var9 == var7; ChunkCoordIntPair var11 = new ChunkCoordIntPair(var8 + var5, var9 + var6); if (!var10) { eligibleChunksForSpawning.put(var11, Boolean.valueOf(false)); } else if (!eligibleChunksForSpawning.containsKey(var11)) { eligibleChunksForSpawning.put(var11, Boolean.valueOf(true)); } } } } countTotal = 0; ChunkCoordinates chunkcoordspawn = worldObj.getSpawnPoint(); EnumCreatureType[] enumcreaturevalues = EnumCreatureType.values(); var6 = enumcreaturevalues.length; //0 = monster, 1 = creature, 2 = ambient, 3 = watercreature for (int enumType = 0; enumType < var6; ++enumType) { EnumCreatureType enumcreaturetype = enumcreaturevalues[enumType]; int enumC = countSpawnedEntities(worldObj, enumcreaturetype); //modified to allow custom creature counts instead of vanillas if ((!enumcreaturetype.getPeacefulCreature() || spawnAnmls) && (enumcreaturetype.getPeacefulCreature() || spawnMobs) && (enumC <= getMax(enumcreaturetype) * eligibleChunksForSpawning.size() / 256)) { Iterator iterator = eligibleChunksForSpawning.keySet().iterator(); ArrayList<ChunkCoordIntPair> tmp = new ArrayList(eligibleChunksForSpawning.keySet()); Collections.shuffle(tmp); iterator = tmp.iterator(); label108: while (iterator.hasNext()) { ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next(); if (eligibleChunksForSpawning.get(chunkcoordintpair) != null && !((Boolean) eligibleChunksForSpawning.get(chunkcoordintpair)).booleanValue()) // blood - added null check to avoid crashing during SSP spawning { ChunkPosition chunkpos = getRandomSpawningPointInChunk(worldObj, chunkcoordintpair.chunkXPos, chunkcoordintpair.chunkZPos); int posX = chunkpos.x; int posY = chunkpos.y; int posZ = chunkpos.z; if (!worldObj.isBlockNormalCube(posX, posY, posZ) && worldObj.getBlockMaterial(posX, posY, posZ) == enumcreaturetype.getCreatureMaterial()) { int spawnedMob = 0; int spawnCount = 0; while (spawnCount < 3) { int tempX = posX; int tempY = posY; int tempZ = posZ; byte var20 = 6; SpawnListEntry spawnlistentry = null; int spawnAttempt = 0; while (true) { if (spawnAttempt < 4) { label101: { tempX += worldObj.rand.nextInt(var20) - worldObj.rand.nextInt(var20); tempY += worldObj.rand.nextInt(1) - worldObj.rand.nextInt(1); tempZ += worldObj.rand.nextInt(var20) - worldObj.rand.nextInt(var20); //if(canCreatureTypeSpawnAtLocation(enumcreaturetype, worldObj, tempPosX, tempPosY, tempPosZ)) if (canCreatureTypeSpawnAtLocation(enumcreaturetype, worldObj, tempX, tempY, tempZ)) { float spawnX = (float) tempX + 0.5F; float spawnY = (float) tempY; float spawnZ = (float) tempZ + 0.5F; //changed so creatures spawn closer if (worldObj.getClosestPlayer((double) spawnX, (double) spawnY, (double) spawnZ, 24.0D) == null) { float var26 = spawnX - (float) chunkcoordspawn.posX; float var27 = spawnY - (float) chunkcoordspawn.posY; float var28 = spawnZ - (float) chunkcoordspawn.posZ; float spawnDist = var26 * var26 + var27 * var27 + var28 * var28; //changed as well to make creatures spawn closer if (spawnDist >= 256.0F) { if (spawnlistentry == null) { //this is where it has to be changed to include the custom list //spawnlistentry = worldObj.getRandomMob(enumcreaturetype, tempX, tempY, tempZ); spawnlistentry = getRandomCustomMob(worldObj, enumcreaturetype, tempX, tempY, tempZ); if (spawnlistentry == null) { break label101; } } EntityLiving entityliving; try { entityliving = (EntityLiving) spawnlistentry.entityClass.getConstructor(new Class[] { World.class }).newInstance(new Object[] { worldObj }); } catch (Exception exception) { exception.printStackTrace(); return countTotal; } entityliving.setLocationAndAngles((double) spawnX, (double) spawnY, (double) spawnZ, worldObj.rand.nextFloat() * 360.0F, 0.0F); if (entityliving.getCanSpawnHere()) { ++spawnedMob; worldObj.spawnEntityInWorld(entityliving); creatureSpecificInit(entityliving, worldObj, spawnX, spawnY, spawnZ); // changed check from maxSpawnedInChunk to maxGroupCount. if (MoCreatures.proxy.debugLogging) log.info("spawned " + entityliving + ", spawnedMob = " + spawnedMob + ", maxGroupCount = " + spawnlistentry.maxGroupCount); if (spawnedMob >= spawnlistentry.maxGroupCount) { continue label108; } } else { if (MoCreatures.proxy.debugLogging) log.info("unable to spawn " + entityliving + " at coords " + var26 + ", " + var27 + ", " + var28); } countTotal += spawnedMob; } } } ++spawnAttempt; continue; } } ++spawnCount; break; } } } } } } } return countTotal; } } public void AddCustomSpawn(Class class1, int i, int max, EnumCreatureType enumcreaturetype) { AddCustomSpawn(class1, i, 4, max, enumcreaturetype, null); } public void AddCustomSpawn(Class class1, int i, EnumCreatureType enumcreaturetype) { AddCustomSpawn(class1, i, 4, 5, enumcreaturetype, null); } public void AddCustomSpawn(Class class1, int i, int max, EnumCreatureType enumcreaturetype, BiomeGenBase abiomegenbase[]) { AddCustomSpawn(class1, i, 4, max, enumcreaturetype, abiomegenbase); } public void AddCustomSpawn(Class class1, int i, EnumCreatureType enumcreaturetype, BiomeGenBase abiomegenbase[]) { AddCustomSpawn(class1, i, 4, 5, enumcreaturetype, abiomegenbase); } //this one adds spawn where biome is not specified public void AddCustomSpawn(Class class1, int i, int j, int k, EnumCreatureType enumcreaturetype) { AddCustomSpawn(class1, i, j, k, enumcreaturetype, null); } public void AddCustomSpawn(Class class1, int i, int j, int k, EnumCreatureType enumcreaturetype, BiomeGenBase abiomegenbase[]) { if (MoCreatures.proxy.debugLogging) log.info("AddCustomSpawn class " + class1 + ", at coords " + i + ", " + j + ", " + k + " type = " + enumcreaturetype); if (class1 == null) { throw new IllegalArgumentException("entityClass cannot be null"); } if (enumcreaturetype == null) { throw new IllegalArgumentException("spawnList cannot be null"); } if (abiomegenbase == null) { abiomegenbase = new BiomeGenBase[biomeList.size()]; abiomegenbase = biomeList.toArray(abiomegenbase); } int x1 = getEnumIndex(enumcreaturetype); { boolean flag = false; for (Iterator iterator = entityClasses[x1].iterator(); iterator.hasNext();) { if (iterator != null) { Class class2 = (Class) iterator.next(); if (class2 == class1) { flag = true; break; } } } if (!flag) { entityClasses[x1].add(class1); } } for (BiomeGenBase element : abiomegenbase) { List[] fulllist = getCustomSpawnableList(enumcreaturetype); if (fulllist != null) { int x = biomeList.indexOf(element); if (x < 0) { continue; } boolean flag = false; for (Iterator iterator = fulllist[x].iterator(); iterator.hasNext();) { if (iterator != null) { SpawnListEntry spawnlistentry = (SpawnListEntry) iterator.next(); if (spawnlistentry.entityClass == class1) { spawnlistentry.itemWeight = i; spawnlistentry.minGroupCount = j; spawnlistentry.maxGroupCount = k; flag = true; break; } } } if (!flag) { fulllist[x].add(new SpawnListEntry(class1, i, j, k)); } } } } public void RemoveCustomSpawn(Class class1, EnumCreatureType enumcreaturetype) { RemoveCustomSpawn(class1, enumcreaturetype, null); } public void RemoveCustomSpawn(Class class1, EnumCreatureType enumcreaturetype, BiomeGenBase abiomegenbase[]) { if (class1 == null) { throw new IllegalArgumentException("entityClass cannot be null"); } if (enumcreaturetype == null) { throw new IllegalArgumentException("spawnList cannot be null"); } if (abiomegenbase == null) { abiomegenbase = new BiomeGenBase[biomeList.size()]; abiomegenbase = biomeList.toArray(abiomegenbase); } for (BiomeGenBase element : abiomegenbase) { List[] fulllist = getCustomSpawnableList(enumcreaturetype); if (fulllist != null) { int x = biomeList.indexOf(element.biomeName); for (Iterator iterator = fulllist[x].iterator(); iterator.hasNext();) { if (iterator != null) { SpawnListEntry spawnlistentry = (SpawnListEntry) iterator.next(); if (spawnlistentry.entityClass == class1) { iterator.remove(); } } } } } } private int getEnumIndex(EnumCreatureType enumcreaturetype) { if (enumcreaturetype == EnumCreatureType.monster) { return 0; } if (enumcreaturetype == EnumCreatureType.creature) { return 1; } if (enumcreaturetype == EnumCreatureType.waterCreature) { return 3; } if (enumcreaturetype == EnumCreatureType.ambient) { return 2; } return 0; } public int countSpawnedEntities(World world, EnumCreatureType enumcreaturetype) { int i = getEnumIndex(enumcreaturetype); int finalcount = 0; { boolean flag = false; for (Iterator iterator = entityClasses[i].iterator(); iterator.hasNext();) { try { if (iterator != null) { Class class1 = (Class) iterator.next(); if (class1 != null) { finalcount += world.countEntities(class1); } } } catch (Exception e) { } } } return finalcount; } private List[] getCustomSpawnableList(EnumCreatureType enumcreaturetype) { if (enumcreaturetype == EnumCreatureType.monster) { return customMobSpawnList; } if (enumcreaturetype == EnumCreatureType.creature) { return customCreatureSpawnList; } if (enumcreaturetype == EnumCreatureType.waterCreature) { return customAquaticSpawnList; } if (enumcreaturetype == EnumCreatureType.ambient) { return customAmbientSpawnList; } return null; } private List getCustomBiomeSpawnList(List[] fulllist, BiomeGenBase biomegenbase) { int x = biomeList.indexOf(biomegenbase); if (x >= 0) { return fulllist[x]; } return null; } public List getCustomBiomeSpawnList(BiomeGenBase biome) { int x = biomeList.indexOf(biome); if (x >= 0) { return this.customCreatureSpawnList[x]; } return null; } private int getMax(EnumCreatureType enumcreaturetype) { if (enumcreaturetype == EnumCreatureType.monster) { return getMaxMobs(); } if (enumcreaturetype == EnumCreatureType.creature) { return getMaxAnimals(); } if (enumcreaturetype == EnumCreatureType.waterCreature) { return getMaxAquatic(); } if (enumcreaturetype == EnumCreatureType.ambient) { return getMaxAmbient(); } return 30; } public int getMaxAnimals() { return maxAnimals; } public void setMaxAnimals(int max) { maxAnimals = max; } public int getMaxMobs() { return maxMobs; } public void setMaxMobs(int max) { maxMobs = max; } public int getMaxAquatic() { return maxAquatic; } public void setMaxAquatic(int max) { maxAquatic = max; } public int getMaxAmbient() { return maxAmbient; } public void setMaxAmbient(int max) { maxAmbient = max; } /*public int getMaxSpawnsPerChunk() { return maxSpawnsPerChunk; } public void setMaxSpawnsPerChunk(int max) { maxSpawnsPerChunk = max; }*/ private static boolean canCreatureTypeSpawnAtLocation(EnumCreatureType enumcreaturetype, World world, int i, int j, int k) { if (enumcreaturetype.getCreatureMaterial() == Material.water) { return world.getBlockMaterial(i, j, k).isLiquid() && !world.isBlockNormalCube(i, j + 1, k); } else { return world.isBlockNormalCube(i, j - 1, k) && !world.isBlockNormalCube(i, j, k) && !world.getBlockMaterial(i, j, k).isLiquid() && !world.isBlockNormalCube(i, j + 1, k); } } //New DesPawner stuff protected final int entityDespawnCheck(WorldServer worldObj, EntityLiving entityliving) { if (entityliving instanceof EntityWolf && ((EntityWolf) entityliving).isTamed()) { return 0; } if (isNearTorch(entityliving, 8D, worldObj)) { return 0; } /*if (!(entityliving instanceof EntityCow || entityliving instanceof EntitySheep || entityliving instanceof EntityChicken || entityliving instanceof EntityPig || entityliving instanceof EntityOcelot || entityliving instanceof EntitySquid )) { return 0; }*/ EntityPlayer entityplayer = worldObj.getClosestPlayerToEntity(entityliving, -1D); if (entityplayer != null) //entityliving.canDespawn() && { double d = ((Entity) (entityplayer)).posX - entityliving.posX; double d1 = ((Entity) (entityplayer)).posY - entityliving.posY; double d2 = ((Entity) (entityplayer)).posZ - entityliving.posZ; double d3 = d * d + d1 * d1 + d2 * d2; if (d3 > 16384D) { entityliving.setDead(); return 1; } if (entityliving.getAge() > 600 && worldObj.rand.nextInt(800) == 0) { if (d3 < 1024D) { //entityliving.attackEntityFrom(DamageSource.generic, 0); } else { entityliving.setDead(); return 1; } } } return 0; } public final int countEntities(Class class1, World worldObj) { int i = 0; for (int j = 0; j < worldObj.loadedEntityList.size(); j++) { Entity entity = (Entity) worldObj.loadedEntityList.get(j); if (class1.isAssignableFrom(entity.getClass())) { i++; } } return i; } public final int despawnVanillaAnimals(WorldServer worldObj) { int count = 0; for (int j = 0; j < worldObj.loadedEntityList.size(); j++) { Entity entity = (Entity) worldObj.loadedEntityList.get(j); if (!(entity instanceof EntityLiving)) { continue; } if ((entity instanceof EntityCow || entity instanceof EntitySheep || entity instanceof EntityPig || entity instanceof EntityOcelot || entity instanceof EntityChicken || entity instanceof EntitySquid || entity instanceof EntityWolf)) { count += entityDespawnCheck(worldObj, (EntityLiving) entity); } } return count; } public final int despawnMob(WorldServer worldObj) { List<Class> myNullList = null; return despawnMob(worldObj, myNullList); } public final int despawnMob(WorldServer worldObj, Class... classList) { List<Class> myList = new ArrayList(); for (Class element : classList) { myList.add(element); } return despawnMob(worldObj, myList); } public final int despawnMob(WorldServer worldObj, List<Class> classList) { int count = 0; if (classList == null) { classList = vanillaClassList; } for (int j = 0; j < worldObj.loadedEntityList.size(); j++) { Entity entity = (Entity) worldObj.loadedEntityList.get(j); if (!(entity instanceof EntityLiving)) { continue; } for (Iterator iterator = classList.iterator(); iterator.hasNext();) { if (iterator != null) { Class class2 = (Class) iterator.next(); if (class2 == entity.getClass()) { count += entityDespawnCheck(worldObj, (EntityLiving) entity); } } } } return count; } public final int despawnMobWithMinimum(WorldServer worldObj, Class class1, int minimum) { int killedcount = 0; int mobcount = countEntities(class1, worldObj); for (int j = 0; j < worldObj.loadedEntityList.size(); j++) { if ((mobcount - killedcount) <= minimum) { worldObj.updateEntities(); return killedcount; } Entity entity = (Entity) worldObj.loadedEntityList.get(j); if (!(entity instanceof EntityLiving)) { continue; } if (class1 == entity.getClass()) { killedcount += entityDespawnCheck(worldObj, (EntityLiving) entity); } } worldObj.updateEntities(); return killedcount; } /** * Gets a random custom mob for spawning based on XYZ coordinates */ public SpawnListEntry getRandomCustomMob(World worldObj, EnumCreatureType enumCreatureType, int pX, int pY, int pZ) { List list = getPossibleCustomCreatures(worldObj, enumCreatureType, pX, pY, pZ); if (list == null || list.isEmpty()) { //System.out.println("list = NULL!! for type " + enumCreatureType.name()); return null; } else { return (SpawnListEntry) WeightedRandom.getRandomItem(worldObj.rand, list); } } /** * Returns a list of creatures of the specified type (mob/aquatic/animal) * that can spawn at the given XYZ location, based on biomes. */ public List getPossibleCustomCreatures(World worldObj, EnumCreatureType enumcreaturetype, int pX, int pY, int pZ) { BiomeGenBase biomegenbase = worldObj.getBiomeGenForCoords(pX, pZ); if (biomegenbase == null) { //System.out.println("null biome"); return null; } else { return getCustomBiomeSpawnList(getCustomSpawnableList(enumcreaturetype), biomegenbase); } } public static boolean isNearTorch(Entity entity, Double dist, World worldObj) { AxisAlignedBB axisalignedbb = entity.boundingBox.expand(dist, 2D, dist); int i = MathHelper.floor_double(axisalignedbb.minX); int j = MathHelper.floor_double(axisalignedbb.maxX + 1.0D); int k = MathHelper.floor_double(axisalignedbb.minY); int l = MathHelper.floor_double(axisalignedbb.maxY + 1.0D); int i1 = MathHelper.floor_double(axisalignedbb.minZ); int j1 = MathHelper.floor_double(axisalignedbb.maxZ + 1.0D); for (int k1 = i; k1 < j; k1++) { for (int l1 = k; l1 < l; l1++) { for (int i2 = i1; i2 < j1; i2++) { int j2 = worldObj.getBlockId(k1, l1, i2); if (j2 != 0) { String nameToCheck = ""; nameToCheck = Block.blocksList[j2].getUnlocalizedName();//.getBlockName(); if (nameToCheck != null && nameToCheck != "" && nameToCheck.equals("tile.fence")) { //System.out.println("fence! @ " + entity); return true; //if (nameToCheck.equals("tile.torch") || nameToCheck.equals("tile.lightgem") || nameToCheck.equals("tile.redstoneLight") || nameToCheck.equals("tile.litpumpkin")) { return true; } } } } } } return false; } /** * determines if a skeleton spawns on a spider, and if a sheep is a different color */ private static void creatureSpecificInit(EntityLiving par0EntityLiving, World par1World, float par2, float par3, float par4) { if (ForgeEventFactory.doSpecialSpawn(par0EntityLiving, par1World, par2, par3, par4)) { return; } par0EntityLiving.initCreature(); } /** * Called during chunk generation to spawn initial creatures. */ public static void performWorldGenSpawning(World worldObj, BiomeGenBase par1BiomeGenBase, int par2, int par3, int par4, int par5, Random par6Random, List customSpawnList) { if (!customSpawnList.isEmpty() && MoCreatures.proxy.worldGenCreatureSpawning) { while (par6Random.nextFloat() < par1BiomeGenBase.getSpawningChance()) { //this is where it has to be changed to include the custom list //spawnlistentry = worldObj.getRandomMob(enumcreaturetype, tempX, tempY, tempZ); SpawnListEntry spawnlistentry = (SpawnListEntry)WeightedRandom.getRandomItem(worldObj.rand, customSpawnList); int i1 = spawnlistentry.minGroupCount + par6Random.nextInt(1 + spawnlistentry.maxGroupCount - spawnlistentry.minGroupCount); int j1 = par2 + par6Random.nextInt(par4); int k1 = par3 + par6Random.nextInt(par5); int l1 = j1; int i2 = k1; for (int j2 = 0; j2 < i1; ++j2) { boolean flag = false; for (int k2 = 0; !flag && k2 < 4; ++k2) { int l2 = worldObj.getTopSolidOrLiquidBlock(j1, k1); if (canCreatureTypeSpawnAtLocation(EnumCreatureType.creature, worldObj, j1, l2, k1)) { float f = (float)j1 + 0.5F; float f1 = (float)l2; float f2 = (float)k1 + 0.5F; EntityLiving entityliving; try { entityliving = (EntityLiving)spawnlistentry.entityClass.getConstructor(new Class[] {World.class}).newInstance(new Object[] {worldObj}); } catch (Exception exception) { exception.printStackTrace(); continue; } entityliving.setLocationAndAngles((double)f, (double)f1, (double)f2, par6Random.nextFloat() * 360.0F, 0.0F); worldObj.spawnEntityInWorld(entityliving); if (MoCreatures.proxy.debugLogging) log.info("worldgen spawned " + entityliving); creatureSpecificInit(entityliving, worldObj, f, f1, f2); flag = true; } j1 += par6Random.nextInt(5) - par6Random.nextInt(5); for (k1 += par6Random.nextInt(5) - par6Random.nextInt(5); j1 < par2 || j1 >= par2 + par4 || k1 < par3 || k1 >= par3 + par4; k1 = i2 + par6Random.nextInt(5) - par6Random.nextInt(5)) { j1 = l1 + par6Random.nextInt(5) - par6Random.nextInt(5); } } } } } } }