|
|
|
@ -14,11 +14,55 @@ instead and save a lot of server resources.
|
|
|
|
|
|
|
|
|
|
See: https://github.com/PaperMC/Paper/issues/917
|
|
|
|
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/util/SpawnUtil.java b/src/main/java/net/minecraft/util/SpawnUtil.java
|
|
|
|
|
index f4d1a3e861a8727d7f3efd75c0e83cc9418fa9bd..4f2952cb39be3644e81ae627b748b7916eed2304 100644
|
|
|
|
|
--- a/src/main/java/net/minecraft/util/SpawnUtil.java
|
|
|
|
|
+++ b/src/main/java/net/minecraft/util/SpawnUtil.java
|
|
|
|
|
@@ -19,10 +19,10 @@ public class SpawnUtil {
|
|
|
|
|
|
|
|
|
|
public static <T extends Mob> Optional<T> trySpawnMob(EntityType<T> entityType, MobSpawnType reason, ServerLevel world, BlockPos pos, int tries, int horizontalRange, int verticalRange, SpawnUtil.Strategy requirements) {
|
|
|
|
|
// CraftBukkit start
|
|
|
|
|
- return SpawnUtil.trySpawnMob(entityType, reason, world, pos, tries, horizontalRange, verticalRange, requirements, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
|
|
|
|
|
+ return SpawnUtil.trySpawnMob(entityType, reason, world, pos, tries, horizontalRange, verticalRange, requirements, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT, null); // Paper
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- public static <T extends Mob> Optional<T> trySpawnMob(EntityType<T> entitytypes, MobSpawnType enummobspawn, ServerLevel worldserver, BlockPos blockposition, int i, int j, int k, SpawnUtil.Strategy spawnutil_a, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
|
|
|
|
|
+ public static <T extends Mob> Optional<T> trySpawnMob(EntityType<T> entitytypes, MobSpawnType enummobspawn, ServerLevel worldserver, BlockPos blockposition, int i, int j, int k, SpawnUtil.Strategy spawnutil_a, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason, @javax.annotation.Nullable Runnable onAbort) { // Paper
|
|
|
|
|
// CraftBukkit end
|
|
|
|
|
BlockPos.MutableBlockPos blockposition_mutableblockposition = blockposition.mutable();
|
|
|
|
|
|
|
|
|
|
@@ -32,6 +32,26 @@ public class SpawnUtil {
|
|
|
|
|
|
|
|
|
|
blockposition_mutableblockposition.setWithOffset(blockposition, i1, k, j1);
|
|
|
|
|
if (worldserver.getWorldBorder().isWithinBounds((BlockPos) blockposition_mutableblockposition) && SpawnUtil.moveToPossibleSpawnPosition(worldserver, k, blockposition_mutableblockposition, spawnutil_a)) {
|
|
|
|
|
+ // Paper start
|
|
|
|
|
+ String key = EntityType.getKey(entitytypes).getPath();
|
|
|
|
|
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(key);
|
|
|
|
|
+
|
|
|
|
|
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
|
|
|
|
|
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
|
|
|
|
|
+ net.minecraft.server.MCUtil.toLocation(worldserver, blockposition),
|
|
|
|
|
+ type,
|
|
|
|
|
+ reason
|
|
|
|
|
+ );
|
|
|
|
|
+ if (!event.callEvent()) {
|
|
|
|
|
+ if (event.shouldAbortSpawn()) {
|
|
|
|
|
+ if (onAbort != null) {
|
|
|
|
|
+ onAbort.run();
|
|
|
|
|
+ }
|
|
|
|
|
+ return Optional.empty();
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ // Paper end
|
|
|
|
|
T t0 = entitytypes.create(worldserver, (CompoundTag) null, (Component) null, (Player) null, blockposition_mutableblockposition, enummobspawn, false, false); // CraftBukkit - decompile error
|
|
|
|
|
|
|
|
|
|
if (t0 != null) {
|
|
|
|
|
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
|
|
|
|
|
index 0c7c8b8671738d9ec408f5dc7f2950a9991858b8..3ee0d583bb6e07570071562a083462c8d67e8a1d 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> {
|
|
|
|
|
@@ -347,6 +347,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) {
|
|
|
|
@ -40,36 +84,23 @@ index 8699a3bd63e2df83615ae39a6873d9874f0fb8da..05a3d736193775c1aa6ce3759e13a1f7
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
index 25cd8a4101cf44955d95924c9794c238ddde2901..f957c0aca36b7228ac3a33ca04c948b1d10642d1 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);
|
|
|
|
|
@@ -947,7 +947,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
|
|
|
|
}).limit(5L).collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
if (list1.size() >= requiredCount) {
|
|
|
|
|
- if (SpawnUtil.trySpawnMob(EntityType.IRON_GOLEM, MobSpawnType.MOB_SUMMONED, world, this.blockPosition(), 10, 8, 6, SpawnUtil.Strategy.LEGACY_IRON_GOLEM, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE).isPresent()) { // CraftBukkit
|
|
|
|
|
+ if (SpawnUtil.trySpawnMob(EntityType.IRON_GOLEM, MobSpawnType.MOB_SUMMONED, world, this.blockPosition(), 10, 8, 6, SpawnUtil.Strategy.LEGACY_IRON_GOLEM, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE, () -> {GolemSensor.golemDetected(this);}).isPresent()) { // CraftBukkit // Paper - Set Golem Last Seen to stop it from spawning another one
|
|
|
|
|
list.forEach(GolemSensor::golemDetected);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
index c104ea31c63fab8f23b4db71ba6e664f710e0bee..031bb42a1921966e8dd45c9e57dcd09f2dece7fb 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 {
|
|
|
|
|
@@ -124,6 +124,27 @@ public abstract class BaseSpawner {
|
|
|
|
|
} else if (!SpawnPlacements.checkSpawnRules((EntityType) optional.get(), world, MobSpawnType.SPAWNER, blockposition1, world.getRandom())) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
@ -98,10 +129,10 @@ index 5bf68b03ddfc7c9554c467e2c0588084a796f6fa..18b1b7c05665ee1fb06670ceded719b1
|
|
|
|
|
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
|
|
|
|
|
index 878fc7f57178bff0e42fd01434f0aaa2732f5a5b..ec6fcfc94b34d2b523c011b197e6484d13517c36 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 {
|
|
|
|
|
@@ -212,7 +212,13 @@ public final class NaturalSpawner {
|
|
|
|
|
j1 = biomesettingsmobs_c.minCount + world.random.nextInt(1 + biomesettingsmobs_c.maxCount - biomesettingsmobs_c.minCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -116,12 +147,12 @@ index fee21a585b95448a5edab70002e9c4ea36a5d989..a62c5f48e54d10eb416111448cd25070
|
|
|
|
|
Mob entityinsentient = NaturalSpawner.getMobForSpawn(world, biomesettingsmobs_c.type);
|
|
|
|
|
|
|
|
|
|
if (entityinsentient == null) {
|
|
|
|
|
@@ -258,9 +264,25 @@ public final class NaturalSpawner {
|
|
|
|
|
@@ -259,9 +265,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
|
|
|
|
|
- private static boolean isValidSpawnPostitionForType(ServerLevel world, MobCategory group, StructureManager structureAccessor, ChunkGenerator chunkGenerator, MobSpawnSettings.SpawnerData spawnEntry, BlockPos.MutableBlockPos pos, double squaredDistance) {
|
|
|
|
|
+ private static Boolean isValidSpawnPostitionForType(ServerLevel world, MobCategory group, StructureManager structureAccessor, ChunkGenerator chunkGenerator, MobSpawnSettings.SpawnerData spawnEntry, BlockPos.MutableBlockPos pos, double squaredDistance) { // Paper
|
|
|
|
|
EntityType<?> entitytypes = spawnEntry.type;
|
|
|
|
|
|
|
|
|
|
+ // Paper start
|