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
9 changed files with 203 additions and 7 deletions
|
@ -10,6 +10,9 @@ import net.minecraft.src.forge.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
|
||||
public String getVersion()
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@ import net.minecraft.src.Chunk;
|
|||
import net.minecraft.src.ChunkCoordIntPair;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityItem;
|
||||
import net.minecraft.src.EntityLiving;
|
||||
import net.minecraft.src.EntityMinecart;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.IInventory;
|
||||
|
@ -339,6 +340,19 @@ public class ForgeHooks
|
|||
return 0;
|
||||
}
|
||||
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
|
||||
// ------------------------------------------------------------
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
|
|
@ -11,6 +11,9 @@ import net.minecraft.src.forge.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
|
||||
public String getVersion()
|
||||
{
|
||||
|
@ -38,6 +41,5 @@ public class mod_MinecraftForge extends NetworkMod
|
|||
//Add 131 & 132 to C->S list
|
||||
((Set)ModLoader.getPrivateValue(Packet.class, null, 3)).add(131);
|
||||
((Set)ModLoader.getPrivateValue(Packet.class, null, 3)).add(132);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
{
|
||||
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) {}
|
||||
|
||||
|
@ -473,6 +473,45 @@
|
|||
+ }
|
||||
+ 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
|
||||
{
|
||||
|
|
|
@ -1,11 +1,42 @@
|
|||
--- ../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
|
||||
@@ -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
|
||||
{
|
||||
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 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);
|
||||
|
||||
@@ -970,6 +972,396 @@
|
||||
@@ -970,6 +972,435 @@
|
||||
*/
|
||||
public void onFallenUpon(World par1World, int par2, int par3, int par4, Entity par5Entity, float par6) {}
|
||||
|
||||
|
@ -461,6 +461,45 @@
|
|||
+ }
|
||||
+ 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
|
||||
{
|
||||
|
|
|
@ -1,11 +1,42 @@
|
|||
--- ../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
|
||||
@@ -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
|
||||
{
|
||||
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 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 a new issue