From 8dca9f2694b737d41887b651a0f1560bff750ad2 Mon Sep 17 00:00:00 2001 From: Steven Blom Date: Wed, 14 Sep 2016 02:02:27 +0930 Subject: [PATCH] New event to allow mutating a baby entity based on it's parents (#3227) --- .../entity/ai/EntityAIMate.java.patch | 21 ++++ .../entity/ai/EntityAIVillagerMate.java.patch | 19 ++++ .../entity/living/BabyEntitySpawnEvent.java | 105 ++++++++++++++++++ .../minecraftforge/debug/BreedingTest.java | 24 ++++ 4 files changed, 169 insertions(+) create mode 100644 patches/minecraft/net/minecraft/entity/ai/EntityAIMate.java.patch create mode 100644 patches/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch create mode 100644 src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java create mode 100644 src/test/java/net/minecraftforge/debug/BreedingTest.java diff --git a/patches/minecraft/net/minecraft/entity/ai/EntityAIMate.java.patch b/patches/minecraft/net/minecraft/entity/ai/EntityAIMate.java.patch new file mode 100644 index 000000000..9e57b3479 --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/ai/EntityAIMate.java.patch @@ -0,0 +1,21 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAIMate.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAIMate.java +@@ -86,6 +86,18 @@ + { + EntityAgeable entityageable = this.field_75390_d.func_90011_a(this.field_75391_e); + ++ final net.minecraftforge.event.entity.living.BabyEntitySpawnEvent event = new net.minecraftforge.event.entity.living.BabyEntitySpawnEvent(field_75390_d, field_75391_e, entityageable); ++ final boolean cancelled = net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event); ++ entityageable = event.getChild(); ++ if (cancelled) { ++ //Reset the "inLove" state for the animals ++ this.field_75390_d.func_70873_a(6000); ++ this.field_75391_e.func_70873_a(6000); ++ this.field_75390_d.func_70875_t(); ++ this.field_75391_e.func_70875_t(); ++ return; ++ } ++ + if (entityageable != null) + { + EntityPlayer entityplayer = this.field_75390_d.func_146083_cb(); diff --git a/patches/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch b/patches/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch new file mode 100644 index 000000000..9b81a621e --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch @@ -0,0 +1,19 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java +@@ -113,11 +113,15 @@ + + private void func_75447_i() + { +- EntityVillager entityvillager = this.field_75450_b.func_90011_a(this.field_75451_c); ++ net.minecraft.entity.EntityAgeable entityvillager = this.field_75450_b.func_90011_a(this.field_75451_c); + this.field_75451_c.func_70873_a(6000); + this.field_75450_b.func_70873_a(6000); + this.field_75451_c.func_175549_o(false); + this.field_75450_b.func_175549_o(false); ++ ++ final net.minecraftforge.event.entity.living.BabyEntitySpawnEvent event = new net.minecraftforge.event.entity.living.BabyEntitySpawnEvent(field_75450_b, field_75451_c, entityvillager); ++ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event) || event.getChild() == null) { return; } ++ entityvillager = event.getChild(); + entityvillager.func_70873_a(-24000); + entityvillager.func_70012_b(this.field_75450_b.field_70165_t, this.field_75450_b.field_70163_u, this.field_75450_b.field_70161_v, 0.0F, 0.0F); + this.field_75448_d.func_72838_d(entityvillager); diff --git a/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java b/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java new file mode 100644 index 000000000..061fa78d6 --- /dev/null +++ b/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java @@ -0,0 +1,105 @@ +/* + * Minecraft Forge + * Copyright (c) 2016. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.event.entity.living; + +import net.minecraft.entity.EntityAgeable; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.ai.EntityAIMate; +import net.minecraft.entity.ai.EntityAIVillagerMate; +import net.minecraft.entity.passive.EntityAnimal; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.Cancelable; +import net.minecraftforge.fml.common.eventhandler.Event; +import javax.annotation.Nullable; + +/** + * BabyEntitySpawnEvent is fired just before a baby entity is about to be spawned.
+ * Parents will have disengaged their relationship. {@link @Cancelable}
+ * It is possible to change the child completely by using {@link #setChild(EntityAgeable)}
+ * This event is fired from {@link EntityAIMate#spawnBaby()} and {@link EntityAIVillagerMate#giveBirth()}
+ *
+ * {@link #parentA} contains the initiating parent entity.
+ * {@link #parentB} contains the secondary parent entity.
+ * {@link #causedByPlayer} contains the player responsible for the breading (if applicable).
+ * {@link #child} contains the child that will be spawned.
+ *
+ * This event is {@link Cancelable}.
+ * If this event is canceled, the child Entity is not added to the world, and the parents
+ * will no longer attempt to mate. + *
+ * This event does not have a result. {@link HasResult}
+ *
+ * This event is fired on the {@link MinecraftForge#EVENT_BUS}. + **/ +@Cancelable +public class BabyEntitySpawnEvent extends Event +{ + private final EntityLiving parentA; + private final EntityLiving parentB; + private final EntityPlayer causedByPlayer; + private EntityAgeable child; + + public BabyEntitySpawnEvent(EntityLiving parentA, EntityLiving parentB, @Nullable EntityAgeable proposedChild) + { + //causedByPlayer calculated here to simplify the patch. + EntityPlayer causedByPlayer = null; + if (parentA instanceof EntityAnimal) { + causedByPlayer = ((EntityAnimal)parentA).getPlayerInLove(); + } + + if (causedByPlayer == null && parentB instanceof EntityAnimal) + { + causedByPlayer = ((EntityAnimal)parentB).getPlayerInLove(); + } + + this.parentA = parentA; + this.parentB = parentB; + this.causedByPlayer = causedByPlayer; + this.child = proposedChild; + } + + public EntityLiving getParentA() + { + return parentA; + } + + public EntityLiving getParentB() + { + return parentB; + } + + @Nullable + public EntityPlayer getCausedByPlayer() + { + return causedByPlayer; + } + + @Nullable + public EntityAgeable getChild() + { + return child; + } + + public void setChild(EntityAgeable proposedChild) + { + child = proposedChild; + } +} \ No newline at end of file diff --git a/src/test/java/net/minecraftforge/debug/BreedingTest.java b/src/test/java/net/minecraftforge/debug/BreedingTest.java new file mode 100644 index 000000000..ac63cdbb2 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/BreedingTest.java @@ -0,0 +1,24 @@ +package net.minecraftforge.debug; + +import net.minecraft.entity.passive.EntityCow; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.living.BabyEntitySpawnEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +@Mod(modid = BreedingTest.MODID, name = "BreedingTest", version = "1.0") +public class BreedingTest +{ + public static final String MODID = "breedingtest"; + + @Mod.EventHandler + public void preInit(FMLPreInitializationEvent event) { + MinecraftForge.EVENT_BUS.register(this); + } + + @SubscribeEvent + public void onBabyBorn(BabyEntitySpawnEvent event) { + event.setChild(new EntityCow(event.getChild().worldObj)); + } +}