Fixed Vinella mob spawning bug that prevented mobs from spawning on the top most chunk. Added new Block function to determine if a Mob can naturally spawn on the block. Add new hook to allow for special case handeling on natural entity spawn.
This commit is contained in:
parent
33a3f67225
commit
cbc9d73a9a
|
@ -10,6 +10,9 @@ import net.minecraft.src.forge.NetworkMod;
|
||||||
*/
|
*/
|
||||||
public class mod_MinecraftForge extends NetworkMod
|
public class mod_MinecraftForge extends NetworkMod
|
||||||
{
|
{
|
||||||
|
@MLProp(info = "Set to false to reproduce a vinella bug that prevents mobs from spawning on inverted half-slabs and inverted stairs.")
|
||||||
|
public static boolean SPAWNER_ALLOW_ON_INVERTED = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVersion()
|
public String getVersion()
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@ import net.minecraft.src.Chunk;
|
||||||
import net.minecraft.src.ChunkCoordIntPair;
|
import net.minecraft.src.ChunkCoordIntPair;
|
||||||
import net.minecraft.src.Entity;
|
import net.minecraft.src.Entity;
|
||||||
import net.minecraft.src.EntityItem;
|
import net.minecraft.src.EntityItem;
|
||||||
|
import net.minecraft.src.EntityLiving;
|
||||||
import net.minecraft.src.EntityMinecart;
|
import net.minecraft.src.EntityMinecart;
|
||||||
import net.minecraft.src.EntityPlayer;
|
import net.minecraft.src.EntityPlayer;
|
||||||
import net.minecraft.src.IInventory;
|
import net.minecraft.src.IInventory;
|
||||||
|
@ -339,6 +340,19 @@ public class ForgeHooks
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static LinkedList<IFuelHandler> fuelHandlers = new LinkedList<IFuelHandler>();
|
static LinkedList<IFuelHandler> fuelHandlers = new LinkedList<IFuelHandler>();
|
||||||
|
|
||||||
|
public static boolean onEntitySpawnSpecial(EntityLiving entity, World world, float x, float y, float z)
|
||||||
|
{
|
||||||
|
for (ISpecialMobSpawnHandler handler : specialMobSpawnHandlers)
|
||||||
|
{
|
||||||
|
if (handler.onSpecialEntitySpawn(entity, world, x, y, z))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
static LinkedList<ISpecialMobSpawnHandler> specialMobSpawnHandlers = new LinkedList<ISpecialMobSpawnHandler>();
|
||||||
|
|
||||||
// Plant Management
|
// Plant Management
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package net.minecraft.src.forge;
|
||||||
|
|
||||||
|
import net.minecraft.src.EntityLiving;
|
||||||
|
import net.minecraft.src.World;
|
||||||
|
|
||||||
|
public interface ISpecialMobSpawnHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Raised when a Entity is spawned into the world from natural means, meaning
|
||||||
|
* not by command, MobSpawner, cheat, etc.. Just naturally throughout the world.
|
||||||
|
*
|
||||||
|
* This allows the mod to create special functionality that runs on a mob natural
|
||||||
|
* spawn. The Vanilla minecraft mechanic of having 'Spider Jockies', the color of
|
||||||
|
* sheep's wool, and Ocelot's spawning with babies can be canceled by returning
|
||||||
|
* true from this function
|
||||||
|
*
|
||||||
|
* Returning true will indicate that you have performed your special spawning,
|
||||||
|
* and no more handling will be done.
|
||||||
|
*
|
||||||
|
* @param entity The newly spawned entity
|
||||||
|
* @param world The world the entity is in
|
||||||
|
* @param x The Entitie's X Position
|
||||||
|
* @param y The Entitie's Y Position
|
||||||
|
* @param z The Entitie's Z Position
|
||||||
|
* @return True to prevent any further special case handling from executing.
|
||||||
|
*/
|
||||||
|
public boolean onSpecialEntitySpawn(EntityLiving entity, World world, float x, float y, float z);
|
||||||
|
}
|
|
@ -152,6 +152,15 @@ public class MinecraftForge
|
||||||
ForgeHooks.fuelHandlers.add(handler);
|
ForgeHooks.fuelHandlers.add(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new Special Mob Spawn handler
|
||||||
|
* @param handler The handler to be registered
|
||||||
|
*/
|
||||||
|
public static void registerSpecialMobSpawnHandler(ISpecialMobSpawnHandler handler)
|
||||||
|
{
|
||||||
|
ForgeHooks.specialMobSpawnHandlers.add(handler);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is not supposed to be called outside of Minecraft internals.
|
* This is not supposed to be called outside of Minecraft internals.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -11,6 +11,9 @@ import net.minecraft.src.forge.NetworkMod;
|
||||||
*/
|
*/
|
||||||
public class mod_MinecraftForge extends NetworkMod
|
public class mod_MinecraftForge extends NetworkMod
|
||||||
{
|
{
|
||||||
|
@MLProp(info = "Set to false to reproduce a vinella bug that prevents mobs from spawning on inverted half-slabs and inverted stairs.")
|
||||||
|
public static boolean SPAWNER_ALLOW_ON_INVERTED = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVersion()
|
public String getVersion()
|
||||||
{
|
{
|
||||||
|
@ -38,6 +41,5 @@ public class mod_MinecraftForge extends NetworkMod
|
||||||
//Add 131 & 132 to C->S list
|
//Add 131 & 132 to C->S list
|
||||||
((Set)ModLoader.getPrivateValue(Packet.class, null, 3)).add(131);
|
((Set)ModLoader.getPrivateValue(Packet.class, null, 3)).add(131);
|
||||||
((Set)ModLoader.getPrivateValue(Packet.class, null, 3)).add(132);
|
((Set)ModLoader.getPrivateValue(Packet.class, null, 3)).add(132);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
{
|
{
|
||||||
ItemStack var8 = this.createStackedBlock(par6);
|
ItemStack var8 = this.createStackedBlock(par6);
|
||||||
|
|
||||||
@@ -1054,6 +1054,396 @@
|
@@ -1054,6 +1054,435 @@
|
||||||
*/
|
*/
|
||||||
public void onFallenUpon(World par1World, int par2, int par3, int par4, Entity par5Entity, float par6) {}
|
public void onFallenUpon(World par1World, int par2, int par3, int par4, Entity par5Entity, float par6) {}
|
||||||
|
|
||||||
|
@ -473,6 +473,45 @@
|
||||||
+ }
|
+ }
|
||||||
+ return renderAsNormalBlock() && !hasTileEntity(metadata);
|
+ return renderAsNormalBlock() && !hasTileEntity(metadata);
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Determines if a specified mob type can spawn on this block, returning false will
|
||||||
|
+ * prevent any mob from spawning on the block.
|
||||||
|
+ *
|
||||||
|
+ * @param type The Mob Category Type
|
||||||
|
+ * @param world The current world
|
||||||
|
+ * @param x The X Position
|
||||||
|
+ * @param y The Y Position
|
||||||
|
+ * @param z The Z Position
|
||||||
|
+ * @return True to allow a mob of the specified category to spawn, false to prevent it.
|
||||||
|
+ */
|
||||||
|
+ public boolean canCreatureSpawn(EnumCreatureType type, World world, int x, int y, int z)
|
||||||
|
+ {
|
||||||
|
+ int meta = world.getBlockMetadata(x, y, z);
|
||||||
|
+ if (this instanceof BlockStep)
|
||||||
|
+ {
|
||||||
|
+ if (mod_MinecraftForge.SPAWNER_ALLOW_ON_INVERTED)
|
||||||
|
+ {
|
||||||
|
+ return (((meta & 8) == 8) || isOpaqueCube());
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ return isNormalCube(this.blockID);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if (this instanceof BlockStairs)
|
||||||
|
+ {
|
||||||
|
+ if (mod_MinecraftForge.SPAWNER_ALLOW_ON_INVERTED)
|
||||||
|
+ {
|
||||||
|
+ return ((meta & 4) != 0);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ return isNormalCube(this.blockID);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return isBlockSolidOnSide(world, x, y, z, 1);
|
||||||
|
+ }
|
||||||
+
|
+
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,11 +1,42 @@
|
||||||
--- ../src_base/minecraft/net/minecraft/src/SpawnerAnimals.java 0000-00-00 00:00:00.000000000 -0000
|
--- ../src_base/minecraft/net/minecraft/src/SpawnerAnimals.java 0000-00-00 00:00:00.000000000 -0000
|
||||||
+++ ../src_work/minecraft/net/minecraft/src/SpawnerAnimals.java 0000-00-00 00:00:00.000000000 -0000
|
+++ ../src_work/minecraft/net/minecraft/src/SpawnerAnimals.java 0000-00-00 00:00:00.000000000 -0000
|
||||||
@@ -202,7 +202,7 @@
|
@@ -5,6 +5,8 @@
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
+import net.minecraft.src.forge.ForgeHooks;
|
||||||
|
+
|
||||||
|
public final class SpawnerAnimals
|
||||||
|
{
|
||||||
|
/** The 17x17 area around the player where mobs can spawn */
|
||||||
|
@@ -20,7 +22,7 @@
|
||||||
|
{
|
||||||
|
Chunk var3 = par0World.getChunkFromChunkCoords(par1, par2);
|
||||||
|
int var4 = par1 * 16 + par0World.rand.nextInt(16);
|
||||||
|
- int var5 = par0World.rand.nextInt(var3 == null ? 128 : Math.max(128, var3.getTopFilledSegment()));
|
||||||
|
+ int var5 = par0World.rand.nextInt(var3 == null ? 128 : Math.max(128, var3.getTopFilledSegment() + 15)); //Vanilla Bug that causes mobs to not spawn on the topmost chunk with blocks.
|
||||||
|
int var6 = par2 * 16 + par0World.rand.nextInt(16);
|
||||||
|
return new ChunkPosition(var4, var5, var6);
|
||||||
|
}
|
||||||
|
@@ -202,7 +204,8 @@
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int var5 = par1World.getBlockId(par2, par3 - 1, par4);
|
int var5 = par1World.getBlockId(par2, par3 - 1, par4);
|
||||||
- return Block.isNormalCube(var5) && var5 != Block.bedrock.blockID && !par1World.isBlockNormalCube(par2, par3, par4) && !par1World.getBlockMaterial(par2, par3, par4).isLiquid() && !par1World.isBlockNormalCube(par2, par3 + 1, par4);
|
- return Block.isNormalCube(var5) && var5 != Block.bedrock.blockID && !par1World.isBlockNormalCube(par2, par3, par4) && !par1World.getBlockMaterial(par2, par3, par4).isLiquid() && !par1World.isBlockNormalCube(par2, par3 + 1, par4);
|
||||||
+ return par1World.isBlockSolidOnSide(par2, par3 - 1, par4, 1) && var5 != Block.bedrock.blockID && !par1World.isBlockNormalCube(par2, par3, par4) && !par1World.getBlockMaterial(par2, par3, par4).isLiquid() && !par1World.isBlockNormalCube(par2, par3 + 1, par4);
|
+ boolean spawnBlock = (Block.blocksList[var5] != null && Block.blocksList[var5].canCreatureSpawn(par0EnumCreatureType, par1World, par2, par3 - 1, par4));
|
||||||
|
+ return spawnBlock && var5 != Block.bedrock.blockID && !par1World.isBlockNormalCube(par2, par3, par4) && !par1World.getBlockMaterial(par2, par3, par4).isLiquid() && !par1World.isBlockNormalCube(par2, par3 + 1, par4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -211,6 +214,11 @@
|
||||||
|
*/
|
||||||
|
private static void creatureSpecificInit(EntityLiving par0EntityLiving, World par1World, float par2, float par3, float par4)
|
||||||
|
{
|
||||||
|
+ if (ForgeHooks.onEntitySpawnSpecial(par0EntityLiving, par1World, par2, par3, par4))
|
||||||
|
+ {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (par0EntityLiving instanceof EntitySpider && par1World.rand.nextInt(100) == 0)
|
||||||
|
{
|
||||||
|
EntitySkeleton var7 = new EntitySkeleton(par1World);
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
{
|
{
|
||||||
ItemStack var8 = this.createStackedBlock(par6);
|
ItemStack var8 = this.createStackedBlock(par6);
|
||||||
|
|
||||||
@@ -970,6 +972,396 @@
|
@@ -970,6 +972,435 @@
|
||||||
*/
|
*/
|
||||||
public void onFallenUpon(World par1World, int par2, int par3, int par4, Entity par5Entity, float par6) {}
|
public void onFallenUpon(World par1World, int par2, int par3, int par4, Entity par5Entity, float par6) {}
|
||||||
|
|
||||||
|
@ -461,6 +461,45 @@
|
||||||
+ }
|
+ }
|
||||||
+ return renderAsNormalBlock() && !hasTileEntity(metadata);
|
+ return renderAsNormalBlock() && !hasTileEntity(metadata);
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Determines if a specified mob type can spawn on this block, returning false will
|
||||||
|
+ * prevent any mob from spawning on the block.
|
||||||
|
+ *
|
||||||
|
+ * @param type The Mob Category Type
|
||||||
|
+ * @param world The current world
|
||||||
|
+ * @param x The X Position
|
||||||
|
+ * @param y The Y Position
|
||||||
|
+ * @param z The Z Position
|
||||||
|
+ * @return True to allow a mob of the specified category to spawn, false to prevent it.
|
||||||
|
+ */
|
||||||
|
+ public boolean canCreatureSpawn(EnumCreatureType type, World world, int x, int y, int z)
|
||||||
|
+ {
|
||||||
|
+ int meta = world.getBlockMetadata(x, y, z);
|
||||||
|
+ if (this instanceof BlockStep)
|
||||||
|
+ {
|
||||||
|
+ if (mod_MinecraftForge.SPAWNER_ALLOW_ON_INVERTED)
|
||||||
|
+ {
|
||||||
|
+ return (((meta & 8) == 8) || isOpaqueCube());
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ return isNormalCube(this.blockID);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if (this instanceof BlockStairs)
|
||||||
|
+ {
|
||||||
|
+ if (mod_MinecraftForge.SPAWNER_ALLOW_ON_INVERTED)
|
||||||
|
+ {
|
||||||
|
+ return ((meta & 4) != 0);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ return isNormalCube(this.blockID);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return isBlockSolidOnSide(world, x, y, z, 1);
|
||||||
|
+ }
|
||||||
+
|
+
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,11 +1,42 @@
|
||||||
--- ../src_base/minecraft_server/net/minecraft/src/SpawnerAnimals.java 0000-00-00 00:00:00.000000000 -0000
|
--- ../src_base/minecraft_server/net/minecraft/src/SpawnerAnimals.java 0000-00-00 00:00:00.000000000 -0000
|
||||||
+++ ../src_work/minecraft_server/net/minecraft/src/SpawnerAnimals.java 0000-00-00 00:00:00.000000000 -0000
|
+++ ../src_work/minecraft_server/net/minecraft/src/SpawnerAnimals.java 0000-00-00 00:00:00.000000000 -0000
|
||||||
@@ -202,7 +202,7 @@
|
@@ -5,6 +5,8 @@
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
+import net.minecraft.src.forge.ForgeHooks;
|
||||||
|
+
|
||||||
|
public final class SpawnerAnimals
|
||||||
|
{
|
||||||
|
/** The 17x17 area around the player where mobs can spawn */
|
||||||
|
@@ -20,7 +22,7 @@
|
||||||
|
{
|
||||||
|
Chunk var3 = par0World.getChunkFromChunkCoords(par1, par2);
|
||||||
|
int var4 = par1 * 16 + par0World.rand.nextInt(16);
|
||||||
|
- int var5 = par0World.rand.nextInt(var3 == null ? 128 : Math.max(128, var3.getTopFilledSegment()));
|
||||||
|
+ int var5 = par0World.rand.nextInt(var3 == null ? 128 : Math.max(128, var3.getTopFilledSegment() + 15)); //Vanilla Bug that causes mobs to not spawn on the topmost chunk with blocks.
|
||||||
|
int var6 = par2 * 16 + par0World.rand.nextInt(16);
|
||||||
|
return new ChunkPosition(var4, var5, var6);
|
||||||
|
}
|
||||||
|
@@ -202,7 +204,8 @@
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int var5 = par1World.getBlockId(par2, par3 - 1, par4);
|
int var5 = par1World.getBlockId(par2, par3 - 1, par4);
|
||||||
- return Block.isNormalCube(var5) && var5 != Block.bedrock.blockID && !par1World.isBlockNormalCube(par2, par3, par4) && !par1World.getBlockMaterial(par2, par3, par4).isLiquid() && !par1World.isBlockNormalCube(par2, par3 + 1, par4);
|
- return Block.isNormalCube(var5) && var5 != Block.bedrock.blockID && !par1World.isBlockNormalCube(par2, par3, par4) && !par1World.getBlockMaterial(par2, par3, par4).isLiquid() && !par1World.isBlockNormalCube(par2, par3 + 1, par4);
|
||||||
+ return par1World.isBlockSolidOnSide(par2, par3 - 1, par4, 1) && var5 != Block.bedrock.blockID && !par1World.isBlockNormalCube(par2, par3, par4) && !par1World.getBlockMaterial(par2, par3, par4).isLiquid() && !par1World.isBlockNormalCube(par2, par3 + 1, par4);
|
+ boolean spawnBlock = (Block.blocksList[var5] != null && Block.blocksList[var5].canCreatureSpawn(par0EnumCreatureType, par1World, par2, par3 - 1, par4));
|
||||||
|
+ return spawnBlock && var5 != Block.bedrock.blockID && !par1World.isBlockNormalCube(par2, par3, par4) && !par1World.getBlockMaterial(par2, par3, par4).isLiquid() && !par1World.isBlockNormalCube(par2, par3 + 1, par4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -211,6 +214,11 @@
|
||||||
|
*/
|
||||||
|
private static void creatureSpecificInit(EntityLiving par0EntityLiving, World par1World, float par2, float par3, float par4)
|
||||||
|
{
|
||||||
|
+ if (ForgeHooks.onEntitySpawnSpecial(par0EntityLiving, par1World, par2, par3, par4))
|
||||||
|
+ {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (par0EntityLiving instanceof EntitySpider && par1World.rand.nextInt(100) == 0)
|
||||||
|
{
|
||||||
|
EntitySkeleton var7 = new EntitySkeleton(par1World);
|
||||||
|
|
Loading…
Reference in New Issue