93 lines
5.9 KiB
Diff
93 lines
5.9 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Aikar <aikar@aikar.co>
|
||
|
Date: Sun, 14 Jan 2018 17:01:31 -0500
|
||
|
Subject: [PATCH] PreCreatureSpawnEvent
|
||
|
|
||
|
Adds an event to fire before an Entity is created, so that plugins that need to cancel
|
||
|
CreatureSpawnEvent can do so from this event instead.
|
||
|
|
||
|
Cancelling CreatureSpawnEvent rapidly causes a lot of garbage collection and CPU waste
|
||
|
as it's done after the Entity object has been fully created.
|
||
|
|
||
|
Mob Limiting plugins and blanket "ban this type of monster" plugins should use this event
|
||
|
instead and save a lot of server resources.
|
||
|
|
||
|
See: https://github.com/PaperMC/Paper/issues/917
|
||
|
|
||
|
diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
|
||
|
index efd4d2844c4ad638837a1fd971927758908e7db1..45cd44335427a818a580158d57025289f37079bf 100644
|
||
|
--- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
|
||
|
+++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
|
||
|
@@ -105,6 +105,27 @@ public abstract class MobSpawnerAbstract {
|
||
|
double d5 = j >= 3 ? nbttaglist.h(2) : (double) blockposition.getZ() + (world.random.nextDouble() - world.random.nextDouble()) * (double) this.spawnRange + 0.5D;
|
||
|
|
||
|
if (world.b(((EntityTypes) optional.get()).a(d3, d4, d5)) && EntityPositionTypes.a((EntityTypes) optional.get(), world.getMinecraftWorld(), EnumMobSpawn.SPAWNER, new BlockPosition(d3, d4, d5), world.getRandom())) {
|
||
|
+ // Paper start
|
||
|
+ EntityTypes<?> entityType = optional.get();
|
||
|
+ String key = EntityTypes.getName(entityType).getKey();
|
||
|
+
|
||
|
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(key);
|
||
|
+ if (type != null) {
|
||
|
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
|
||
|
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
|
||
|
+ MCUtil.toLocation(world, d3, d4, d5),
|
||
|
+ type,
|
||
|
+ org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER
|
||
|
+ );
|
||
|
+ if (!event.callEvent()) {
|
||
|
+ flag = true;
|
||
|
+ if (event.shouldAbortSpawn()) {
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ // Paper end
|
||
|
Entity entity = EntityTypes.a(nbttagcompound, world, (entity1) -> {
|
||
|
entity1.setPositionRotation(d3, d4, d5, entity1.yaw, entity1.pitch);
|
||
|
return entity1;
|
||
|
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
||
|
index 50be743513145bd2c8b9c65af219f60099cbb09f..4b1a5e92cc05df06edd6d2d7eab5ca70b70ede79 100644
|
||
|
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
||
|
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
||
|
@@ -180,7 +180,12 @@ public final class SpawnerCreature {
|
||
|
j1 = biomebase_biomemeta.d + worldserver.random.nextInt(1 + biomebase_biomemeta.e - biomebase_biomemeta.d);
|
||
|
}
|
||
|
|
||
|
- if (a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2) && spawnercreature_c.test(biomebase_biomemeta.c, blockposition_mutableblockposition, ichunkaccess)) {
|
||
|
+ // Paper start
|
||
|
+ Boolean doSpawning = a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2);
|
||
|
+ if (doSpawning == null) {
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ if (doSpawning.booleanValue() && spawnercreature_c.test(biomebase_biomemeta.c, blockposition_mutableblockposition, ichunkaccess)) { // Paper end
|
||
|
EntityInsentient entityinsentient = a(worldserver, biomebase_biomemeta.c);
|
||
|
|
||
|
if (entityinsentient == null) {
|
||
|
@@ -234,8 +239,24 @@ public final class SpawnerCreature {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- private static boolean a(WorldServer worldserver, EnumCreatureType enumcreaturetype, StructureManager structuremanager, ChunkGenerator chunkgenerator, BiomeBase.BiomeMeta biomebase_biomemeta, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) {
|
||
|
+ private static Boolean a(WorldServer worldserver, EnumCreatureType enumcreaturetype, StructureManager structuremanager, ChunkGenerator chunkgenerator, BiomeBase.BiomeMeta biomebase_biomemeta, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) { // Paper
|
||
|
EntityTypes<?> entitytypes = biomebase_biomemeta.c;
|
||
|
+ // Paper start
|
||
|
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
|
||
|
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityTypes.getName(entitytypes).getKey());
|
||
|
+ if (type != null) {
|
||
|
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
|
||
|
+ MCUtil.toLocation(worldserver, blockposition_mutableblockposition),
|
||
|
+ type, SpawnReason.NATURAL
|
||
|
+ );
|
||
|
+ if (!event.callEvent()) {
|
||
|
+ if (event.shouldAbortSpawn()) {
|
||
|
+ return null;
|
||
|
+ }
|
||
|
+ return false; // TODO is this handled correctly?
|
||
|
+ }
|
||
|
+ }
|
||
|
+ // Paper end
|
||
|
|
||
|
if (entitytypes.e() == EnumCreatureType.MISC) {
|
||
|
return false;
|