ReAdded PreCreatureSpawnEvent from removed (#5814)

This commit is contained in:
mechoriet 2021-06-14 07:40:21 +02:00 committed by GitHub
parent 9c95d0481d
commit dcbb16316d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 150 additions and 215 deletions

View file

@ -1,215 +0,0 @@
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
1.17: Has to be looked into more
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/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
index e3d92d1d35911b2960a7ca82bd4f324d285d0533..e39d950783599b01271bdb7e67fe68b46af0c49c 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -17,6 +17,7 @@ import net.minecraft.nbt.ListTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.MCUtil;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.BlockTags;
@@ -317,6 +318,20 @@ public class EntityType<T extends Entity> {
@Nullable
public T spawnCreature(ServerLevel worldserver, @Nullable CompoundTag nbttagcompound, @Nullable Component ichatbasecomponent, @Nullable Player entityhuman, BlockPos blockposition, MobSpawnType enummobspawn, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
+ // Paper start - Call PreCreatureSpawnEvent
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityType.getKey(this).getPath());
+ if (type != null) {
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
+ MCUtil.toLocation(worldserver, blockposition),
+ type,
+ spawnReason
+ );
+ if (!event.callEvent()) {
+ return null;
+ }
+ }
+ // Paper end
T t0 = this.create(worldserver, nbttagcompound, ichatbasecomponent, entityhuman, blockposition, enummobspawn, flag, flag1);
if (t0 != null) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/GolemSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/GolemSensor.java
index f3a7807a20b279056d5640ab02aa77f7b1dabc2a..880d69bad933294a2cfdea9adb3e648e29eb42be 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/GolemSensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/GolemSensor.java
@@ -33,8 +33,8 @@ public class GolemSensor extends Sensor<LivingEntity> {
Optional<List<LivingEntity>> optional = entityliving.getBrain().getMemory(MemoryModuleType.MOBS);
if (optional.isPresent()) {
- boolean flag = ((List) optional.get()).stream().anyMatch((entityliving1) -> {
- return entityliving1.getEntityType().equals(EntityType.IRON_GOLEM);
+ boolean flag = optional.get().stream().anyMatch((entityliving1) -> { // Paper - decompile fixes
+ return entityliving1.getType().equals(EntityType.IRON_GOLEM);
});
if (flag) {
@@ -44,6 +44,7 @@ public class GolemSensor extends Sensor<LivingEntity> {
}
}
+ public static void setDetectedRecently(LivingEntity entityLiving) { golemDetected(entityLiving); } // Paper - OBFHELPER
public static void golemDetected(LivingEntity entityliving) {
entityliving.getBrain().setMemoryWithExpiry(MemoryModuleType.GOLEM_DETECTED_RECENTLY, true, 600L);
}
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
index a66fab2e04a5d87ced139ed15d2434c5ffcec695..eed6265dc8275921a18fc5f4970ba131ba782132 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
@@ -30,6 +30,7 @@ import net.minecraft.network.protocol.game.DebugPackets;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
+import net.minecraft.server.MCUtil;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
@@ -942,6 +943,21 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
BlockPos blockposition1 = this.findSpawnPositionForGolemInColumn(blockposition, d0, d1);
if (blockposition1 != null) {
+ // Paper start - Call PreCreatureSpawnEvent
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
+ MCUtil.toLocation(level, blockposition1),
+ org.bukkit.entity.EntityType.IRON_GOLEM,
+ org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE
+ );
+ if (!event.callEvent()) {
+ if (event.shouldAbortSpawn()) {
+ GolemSensor.golemDetected(this); // Set Golem Last Seen to stop it from spawning another one
+ return null;
+ }
+ break;
+ }
+ // Paper end
IronGolem entityirongolem = (IronGolem) EntityType.IRON_GOLEM.create(world, (CompoundTag) null, (Component) null, (Player) null, blockposition1, MobSpawnType.MOB_SUMMONED, false, false);
if (entityirongolem != null) {
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
index 4582fc1bb767214241568fbc22b0ee2cbf3322e0..ac572eba10a7239d71dfae060f623b076d4252ce 100644
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
@@ -12,6 +12,7 @@ import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.MCUtil;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.StringUtil;
import net.minecraft.util.WeighedRandom;
@@ -125,6 +126,27 @@ public abstract class BaseSpawner {
ServerLevel worldserver = (ServerLevel) world;
if (SpawnPlacements.checkSpawnRules((EntityType) optional.get(), worldserver, MobSpawnType.SPAWNER, new BlockPos(d3, d4, d5), world.getRandom())) {
+ // Paper start
+ EntityType<?> entityType = optional.get();
+ String key = EntityType.getKey(entityType).getPath();
+
+ 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 = EntityType.loadEntityRecursive(nbttagcompound, world, (entity1) -> {
entity1.moveTo(d3, d4, d5, entity1.yRot, entity1.xRot);
return entity1;
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
index a19ac1cb7e4d8d478648a048b2bfa0daf85a80c9..8a71eaf2855be0d415d1f7b18dbec98353fe5b47 100644
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -15,6 +15,7 @@ import net.minecraft.core.Direction;
import net.minecraft.core.Position;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
+import net.minecraft.server.MCUtil;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.FluidTags;
@@ -214,9 +215,16 @@ public final class NaturalSpawner {
j1 = biomesettingsmobs_c.minCount + world.random.nextInt(1 + biomesettingsmobs_c.maxCount - biomesettingsmobs_c.minCount);
}
- if (isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2) && checker.test(biomesettingsmobs_c.type, blockposition_mutableblockposition, chunk)) {
+ // Paper start
+ Boolean doSpawning = a(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2);
+ if (doSpawning == null) {
+ return;
+ }
+ if (doSpawning && checker.test(biomesettingsmobs_c.type, blockposition_mutableblockposition, chunk)) {
+ // Paper end
Mob entityinsentient = getMobForSpawn(world, biomesettingsmobs_c.type);
+
if (entityinsentient == null) {
return;
}
@@ -269,17 +277,33 @@ public final class NaturalSpawner {
}
}
- private static boolean isValidSpawnPostitionForType(ServerLevel world, MobCategory group, StructureFeatureManager structureAccessor, ChunkGenerator chunkGenerator, MobSpawnSettings.SpawnerData spawnEntry, BlockPos.MutableBlockPos pos, double squaredDistance) {
- EntityType<?> entitytypes = spawnEntry.type;
+ private static Boolean a(ServerLevel worldserver, MobCategory enumcreaturetype, StructureFeatureManager structuremanager, ChunkGenerator chunkgenerator, MobSpawnSettings.SpawnerData biomesettingsmobs_c, BlockPos.MutableBlockPos blockposition_mutableblockposition, double d0) { // Paper
+ EntityType<?> entitytypes = biomesettingsmobs_c.type;
+ // Paper start
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityType.getKey(entitytypes).getPath());
+ 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;
+ }
+ }
+ // Paper end
if (entitytypes.getCategory() == MobCategory.MISC) {
return false;
- } else if (!entitytypes.canSpawnFarFromPlayer() && squaredDistance > (double) (entitytypes.getCategory().getDespawnDistance() * entitytypes.getCategory().getDespawnDistance())) {
+ } else if (!entitytypes.canSpawnFarFromPlayer() && d0 > (double) (entitytypes.getCategory().getDespawnDistance() * entitytypes.getCategory().getDespawnDistance())) {
return false;
- } else if (entitytypes.canSummon() && canSpawnMobAt(world, structureAccessor, chunkGenerator, group, spawnEntry, (BlockPos) pos)) {
+ } else if (entitytypes.canSummon() && canSpawnMobAt(worldserver, structuremanager, chunkgenerator, enumcreaturetype, biomesettingsmobs_c, (BlockPos) blockposition_mutableblockposition)) {
SpawnPlacements.Type entitypositiontypes_surface = SpawnPlacements.getPlacementType(entitytypes);
- return !isSpawnPositionOk(entitypositiontypes_surface, (LevelReader) world, pos, entitytypes) ? false : (!SpawnPlacements.checkSpawnRules(entitytypes, world, MobSpawnType.NATURAL, pos, world.random) ? false : world.noCollision(entitytypes.getAABB((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D)));
+ return !isSpawnPositionOk(entitypositiontypes_surface, (LevelReader) worldserver, blockposition_mutableblockposition, entitytypes) ? false : (!SpawnPlacements.checkSpawnRules(entitytypes, worldserver, MobSpawnType.NATURAL, blockposition_mutableblockposition, worldserver.random) ? false : worldserver.noCollision(entitytypes.getAABB((double) blockposition_mutableblockposition.getX() + 0.5D, (double) blockposition_mutableblockposition.getY(), (double) blockposition_mutableblockposition.getZ() + 0.5D)));
} else {
return false;
}

View file

@ -0,0 +1,150 @@
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/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
index 9f5f2bd9bdfce14da030b09f56c821ec1989e12f..872f92ac1a6bc86ce54700dbf555ceea4fab2057 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -333,6 +333,20 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T> {
@Nullable
public T spawnCreature(ServerLevel worldserver, @Nullable CompoundTag nbttagcompound, @Nullable Component ichatbasecomponent, @Nullable Player entityhuman, BlockPos blockposition, MobSpawnType enummobspawn, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
+ // Paper start - Call PreCreatureSpawnEvent
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityType.getKey(this).getPath());
+ if (type != null) {
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
+ net.minecraft.server.MCUtil.toLocation(worldserver, blockposition),
+ type,
+ spawnReason
+ );
+ if (!event.callEvent()) {
+ return null;
+ }
+ }
+ // Paper end
T t0 = this.create(worldserver, nbttagcompound, ichatbasecomponent, entityhuman, blockposition, enummobspawn, flag, flag1);
if (t0 != null) {
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
index 6a9e2105b2d9a4ee83c0a2516d5ef26dc3b99053..aec77679584a2acab5818e26e2586b5316118e84 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
@@ -987,6 +987,21 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
BlockPos blockposition1 = this.findSpawnPositionForGolemInColumn(blockposition, d0, d1);
if (blockposition1 != null) {
+ // Paper start - Call PreCreatureSpawnEvent
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
+ net.minecraft.server.MCUtil.toLocation(level, blockposition1),
+ org.bukkit.entity.EntityType.IRON_GOLEM,
+ org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE
+ );
+ if (!event.callEvent()) {
+ if (event.shouldAbortSpawn()) {
+ GolemSensor.golemDetected(this); // Set Golem Last Seen to stop it from spawning another one
+ return null;
+ }
+ break;
+ }
+ // Paper end
IronGolem entityirongolem = (IronGolem) EntityType.IRON_GOLEM.create(world, (CompoundTag) null, (Component) null, (Player) null, blockposition1, MobSpawnType.MOB_SUMMONED, false, false);
if (entityirongolem != null) {
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
index c6298b12e4e0c20be20e7e493be728f028f9eb31..68ce2732dfdc25ddadc15c43c30a609f9b1eba86 100644
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
@@ -132,6 +132,27 @@ public abstract class BaseSpawner {
double d2 = j >= 3 ? nbttaglist.getDouble(2) : (double) pos.getZ() + (world.random.nextDouble() - world.random.nextDouble()) * (double) this.spawnRange + 0.5D;
if (world.noCollision(((EntityType) optional.get()).getAABB(d0, d1, d2)) && SpawnPlacements.checkSpawnRules((EntityType) optional.get(), world, MobSpawnType.SPAWNER, new BlockPos(d0, d1, d2), world.getRandom())) {
+ // Paper start
+ EntityType<?> entityType = optional.get();
+ String key = EntityType.getKey(entityType).getPath();
+
+ 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(
+ net.minecraft.server.MCUtil.toLocation(world, d0, d1, d2),
+ type,
+ org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER
+ );
+ if (!event.callEvent()) {
+ flag = true;
+ if (event.shouldAbortSpawn()) {
+ break;
+ }
+ continue;
+ }
+ }
+ // Paper end
Entity entity = EntityType.loadEntityRecursive(nbttagcompound, world, (entity1) -> {
entity1.moveTo(d0, d1, d2, entity1.getYRot(), entity1.getXRot());
return entity1;
@@ -349,3 +370,4 @@ public abstract class BaseSpawner {
return this.oSpin;
}
}
+
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
index 30ba1e3cb75d994770b006b9dfd6669000a9c1a4..6204bf41d410df9784b32f993b46d7adb2af5f13 100644
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -231,7 +231,13 @@ public final class NaturalSpawner {
j1 = biomesettingsmobs_c.minCount + world.random.nextInt(1 + biomesettingsmobs_c.maxCount - biomesettingsmobs_c.minCount);
}
- if (NaturalSpawner.isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2) && checker.test(biomesettingsmobs_c.type, blockposition_mutableblockposition, chunk)) {
+ // Paper start
+ Boolean doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2);
+ if (doSpawning == null) {
+ return;
+ }
+ if (doSpawning && checker.test(biomesettingsmobs_c.type, blockposition_mutableblockposition, chunk)) {
+ // Paper end
Mob entityinsentient = NaturalSpawner.getMobForSpawn(world, biomesettingsmobs_c.type);
if (entityinsentient == null) {
@@ -278,9 +284,25 @@ public final class NaturalSpawner {
return squaredDistance <= 576.0D ? false : (world.getSharedSpawnPos().closerThan((Position) (new Vec3((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D)), 24.0D) ? false : Objects.equals(new ChunkPos(pos), chunk.getPos()) || world.isPositionEntityTicking((BlockPos) pos));
}
- private static boolean isValidSpawnPostitionForType(ServerLevel world, MobCategory group, StructureFeatureManager structureAccessor, ChunkGenerator chunkGenerator, MobSpawnSettings.SpawnerData spawnEntry, BlockPos.MutableBlockPos pos, double squaredDistance) {
+ private static Boolean isValidSpawnPostitionForType(ServerLevel world, MobCategory group, StructureFeatureManager structureAccessor, ChunkGenerator chunkGenerator, MobSpawnSettings.SpawnerData spawnEntry, BlockPos.MutableBlockPos pos, double squaredDistance) { // Paper
EntityType<?> entitytypes = spawnEntry.type;
+ // Paper start
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityType.getKey(entitytypes).getPath());
+ if (type != null) {
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
+ net.minecraft.server.MCUtil.toLocation(world, pos),
+ type, SpawnReason.NATURAL
+ );
+ if (!event.callEvent()) {
+ if (event.shouldAbortSpawn()) {
+ return null;
+ }
+ return false;
+ }
+ }
+ // Paper end
if (entitytypes.getCategory() == MobCategory.MISC) {
return false;
} else if (!entitytypes.canSpawnFarFromPlayer() && squaredDistance > (double) (entitytypes.getCategory().getDespawnDistance() * entitytypes.getCategory().getDespawnDistance())) {