18f0f8d1ca
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 312281ea PR-742: Make World implement Keyed CraftBukkit Changes: 2ac7fa7a SPIGOT-7014: getLootTable API should not persistently update loot table 7fdd7941 PR-1046: Make World implement Keyed 7bc728a6 PR-1045: Revert changes to persistence required checks Spigot Changes: b6d12d17 Rebuild patches
146 Zeilen
9.4 KiB
Diff
146 Zeilen
9.4 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/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
index 8699a3bd63e2df83615ae39a6873d9874f0fb8da..05a3d736193775c1aa6ce3759e13a1f76f747d09 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
|
|
@@ -338,6 +338,20 @@ public class EntityType<T extends Entity> implements EntityTypeTest<Entity, T> {
|
|
|
|
@Nullable
|
|
public T spawn(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 ac44ba98d0acc9aa2a75088d8a9a145fdbcbd911..ecd7083b40ce6230d49ea4487766a6f06b4e96d0 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
|
@@ -997,6 +997,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 5bf68b03ddfc7c9554c467e2c0588084a796f6fa..18b1b7c05665ee1fb06670ceded719b19f3a4ee3 100644
|
|
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
|
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
|
@@ -122,6 +122,27 @@ public abstract class BaseSpawner {
|
|
} else if (!SpawnPlacements.checkSpawnRules((EntityType) optional.get(), world, MobSpawnType.SPAWNER, blockposition1, world.getRandom())) {
|
|
continue;
|
|
}
|
|
+ // 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());
|
|
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
|
index fee21a585b95448a5edab70002e9c4ea36a5d989..a62c5f48e54d10eb416111448cd250704ef594a0 100644
|
|
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
|
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
|
@@ -211,7 +211,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) {
|
|
@@ -258,9 +264,25 @@ public final class NaturalSpawner {
|
|
return squaredDistance <= 576.0D ? false : (world.getSharedSpawnPos().closerToCenterThan(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.isNaturalSpawningAllowed((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())) {
|