From 3a9c7b4532240b70dac5f72082cbcedc0dd41335 Mon Sep 17 00:00:00 2001 From: LexManos Date: Tue, 1 Jan 2013 22:20:30 -0800 Subject: [PATCH] Added event hooks to control to allow mod control of mob spawning. PR: #337 Deprecated LivingSpecialSpawnEvent in favor of new LivingSpawnEvent.SpecialSpawn --- .../event/ForgeEventFactory.java | 26 ++++++++++ .../event/entity/living/LivingSpawnEvent.java | 50 +++++++++++++++++++ .../living/LivingSpecialSpawnEvent.java | 1 + .../minecraft/world/SpawnerAnimals.java.patch | 22 ++++++-- 4 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 common/net/minecraftforge/event/entity/living/LivingSpawnEvent.java diff --git a/common/net/minecraftforge/event/ForgeEventFactory.java b/common/net/minecraftforge/event/ForgeEventFactory.java index 34dfacd1e..0210321f5 100644 --- a/common/net/minecraftforge/event/ForgeEventFactory.java +++ b/common/net/minecraftforge/event/ForgeEventFactory.java @@ -1,12 +1,18 @@ package net.minecraftforge.event; import net.minecraft.block.Block; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; +import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.Event.Result; +import net.minecraftforge.event.entity.living.LivingSpawnEvent; +import net.minecraftforge.event.entity.living.LivingSpecialSpawnEvent; import net.minecraftforge.event.entity.player.*; import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; +@SuppressWarnings("deprecation") public class ForgeEventFactory { public static boolean doPlayerHarvestCheck(EntityPlayer player, Block block, boolean success) @@ -33,4 +39,24 @@ public class ForgeEventFactory { MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(player, stack)); } + + public static Result canEntitySpawn(EntityLiving entity, World world, float x, float y, float z) + { + LivingSpawnEvent.CheckSpawn event = new LivingSpawnEvent.CheckSpawn(entity, world, x, y, z); + MinecraftForge.EVENT_BUS.post(event); + return event.getResult(); + } + + public static boolean doSpecialSpawn(EntityLiving entity, World world, float x, float y, float z) + { + boolean result = MinecraftForge.EVENT_BUS.post(new LivingSpecialSpawnEvent(entity, world, x, y, z)); + LivingSpawnEvent.SpecialSpawn nEvent = new LivingSpawnEvent.SpecialSpawn(entity, world, x, y, z); + + if (result) //For the time being, copy the canceled state from the old legacy event + { // Remove when we remove LivingSpecialSpawnEvent. + nEvent.setCanceled(true); + } + + return MinecraftForge.EVENT_BUS.post(nEvent); + } } diff --git a/common/net/minecraftforge/event/entity/living/LivingSpawnEvent.java b/common/net/minecraftforge/event/entity/living/LivingSpawnEvent.java new file mode 100644 index 000000000..320b80a73 --- /dev/null +++ b/common/net/minecraftforge/event/entity/living/LivingSpawnEvent.java @@ -0,0 +1,50 @@ +package net.minecraftforge.event.entity.living; + +import net.minecraft.entity.EntityLiving; +import net.minecraft.world.World; +import net.minecraftforge.event.Cancelable; +import net.minecraftforge.event.Event.HasResult; + +public class LivingSpawnEvent extends LivingEvent +{ + public final World world; + public final float x; + public final float y; + public final float z; + + public LivingSpawnEvent(EntityLiving entity, World world, float x, float y, float z) + { + super(entity); + this.world = world; + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Fires before mob spawn events. + * + * Result is significant: + * DEFAULT: use vanilla spawn rules + * ALLOW: allow the spawn + * DENY: deny the spawn + * + */ + @HasResult + public static class CheckSpawn extends LivingSpawnEvent + { + public CheckSpawn(EntityLiving entity, World world, float x, float y, float z) + { + super(entity, world, x, y, z); + } + } + + @Cancelable + public static class SpecialSpawn extends LivingSpawnEvent + { + public SpecialSpawn(EntityLiving entity, World world, float x, float y, float z) + { + super(entity, world, x, y, z); + } + } +} \ No newline at end of file diff --git a/common/net/minecraftforge/event/entity/living/LivingSpecialSpawnEvent.java b/common/net/minecraftforge/event/entity/living/LivingSpecialSpawnEvent.java index 834c1ba7a..d8c2d4d25 100644 --- a/common/net/minecraftforge/event/entity/living/LivingSpecialSpawnEvent.java +++ b/common/net/minecraftforge/event/entity/living/LivingSpecialSpawnEvent.java @@ -4,6 +4,7 @@ import net.minecraft.entity.EntityLiving; import net.minecraft.world.World; import net.minecraftforge.event.Cancelable; +@Deprecated //Remove next MC Version @Cancelable public class LivingSpecialSpawnEvent extends LivingEvent { diff --git a/patches/minecraft/net/minecraft/world/SpawnerAnimals.java.patch b/patches/minecraft/net/minecraft/world/SpawnerAnimals.java.patch index c1d560a7a..d731aa820 100644 --- a/patches/minecraft/net/minecraft/world/SpawnerAnimals.java.patch +++ b/patches/minecraft/net/minecraft/world/SpawnerAnimals.java.patch @@ -8,17 +8,19 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; -@@ -19,6 +21,9 @@ +@@ -19,6 +21,11 @@ import net.minecraft.world.biome.SpawnListEntry; import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.common.MinecraftForge; ++import net.minecraftforge.event.Event.Result; ++import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.event.entity.living.LivingSpecialSpawnEvent; + public final class SpawnerAnimals { /** The 17x17 area around the player where mobs can spawn */ -@@ -93,6 +98,9 @@ +@@ -93,6 +100,9 @@ if ((!var35.getPeacefulCreature() || par2) && (var35.getPeacefulCreature() || par1) && (!var35.getAnimal() || par3) && par0WorldServer.countEntities(var35.getCreatureClass()) <= var35.getMaxNumberOfCreature() * eligibleChunksForSpawning.size() / 256) { Iterator var37 = eligibleChunksForSpawning.keySet().iterator(); @@ -28,7 +30,17 @@ label110: while (var37.hasNext()) -@@ -221,7 +229,8 @@ +@@ -169,7 +179,8 @@ + + var39.setLocationAndAngles((double)var24, (double)var25, (double)var26, par0WorldServer.rand.nextFloat() * 360.0F, 0.0F); + +- if (var39.getCanSpawnHere()) ++ Result canSpawn = ForgeEventFactory.canEntitySpawn(var39, par0WorldServer, var24, var25, var26); ++ if (canSpawn == Result.ALLOW || (canSpawn == Result.DEFAULT && var39.getCanSpawnHere())) + { + ++var16; + par0WorldServer.spawnEntityInWorld(var39); +@@ -221,7 +232,8 @@ else { int var5 = par1World.getBlockId(par2, par3 - 1, par4); @@ -38,11 +50,11 @@ } } -@@ -230,6 +239,11 @@ +@@ -230,6 +242,11 @@ */ private static void creatureSpecificInit(EntityLiving par0EntityLiving, World par1World, float par2, float par3, float par4) { -+ if (MinecraftForge.EVENT_BUS.post(new LivingSpecialSpawnEvent(par0EntityLiving, par1World, par2, par3, par4))) ++ if (ForgeEventFactory.doSpecialSpawn(par0EntityLiving, par1World, par2, par3, par4)) + { + return; + }