mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-09 11:44:19 +01:00
cad0c129c8
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
103 lines
5.4 KiB
Diff
103 lines
5.4 KiB
Diff
--- a/net/minecraft/world/level/BaseSpawner.java
|
|
+++ b/net/minecraft/world/level/BaseSpawner.java
|
|
@@ -49,15 +49,17 @@
|
|
public int maxNearbyEntities = 6;
|
|
public int requiredPlayerRange = 16;
|
|
public int spawnRange = 4;
|
|
+ private int tickDelay = 0; // Paper - Configurable mob spawner tick rate
|
|
|
|
public BaseSpawner() {}
|
|
|
|
public void setEntityId(EntityType<?> type, @Nullable Level world, RandomSource random, BlockPos pos) {
|
|
this.getOrCreateNextSpawnData(world, random, pos).getEntityToSpawn().putString("id", BuiltInRegistries.ENTITY_TYPE.getKey(type).toString());
|
|
+ this.spawnPotentials = SimpleWeightedRandomList.empty(); // CraftBukkit - SPIGOT-3496, MC-92282
|
|
}
|
|
|
|
public boolean isNearPlayer(Level world, BlockPos pos) {
|
|
- return world.hasNearbyAlivePlayer((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (double) this.requiredPlayerRange);
|
|
+ return world.hasNearbyAlivePlayerThatAffectsSpawning((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (double) this.requiredPlayerRange); // Paper - Affects Spawning API
|
|
}
|
|
|
|
public void clientTick(Level world, BlockPos pos) {
|
|
@@ -82,13 +84,18 @@
|
|
}
|
|
|
|
public void serverTick(ServerLevel world, BlockPos pos) {
|
|
+ // Paper start - Configurable mob spawner tick rate
|
|
+ if (spawnDelay > 0 && --tickDelay > 0) return;
|
|
+ tickDelay = world.paperConfig().tickRates.mobSpawner;
|
|
+ if (tickDelay == -1) { return; } // If disabled
|
|
+ // Paper end - Configurable mob spawner tick rate
|
|
if (this.isNearPlayer(world, pos)) {
|
|
- if (this.spawnDelay == -1) {
|
|
+ if (this.spawnDelay < -tickDelay) { // Paper - Configurable mob spawner tick rate
|
|
this.delay(world, pos);
|
|
}
|
|
|
|
if (this.spawnDelay > 0) {
|
|
- --this.spawnDelay;
|
|
+ this.spawnDelay -= tickDelay; // Paper - Configurable mob spawner tick rate
|
|
} else {
|
|
boolean flag = false;
|
|
RandomSource randomsource = world.getRandom();
|
|
@@ -123,8 +130,22 @@
|
|
continue;
|
|
}
|
|
} else if (!SpawnPlacements.checkSpawnRules((EntityType) optional.get(), world, EntitySpawnReason.SPAWNER, blockposition1, world.getRandom())) {
|
|
+ continue;
|
|
+ }
|
|
+ // Paper start - PreCreatureSpawnEvent
|
|
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
|
|
+ io.papermc.paper.util.MCUtil.toLocation(world, d0, d1, d2),
|
|
+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(optional.get()),
|
|
+ org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER
|
|
+ );
|
|
+ if (!event.callEvent()) {
|
|
+ flag = true;
|
|
+ if (event.shouldAbortSpawn()) {
|
|
+ break;
|
|
+ }
|
|
continue;
|
|
}
|
|
+ // Paper end - PreCreatureSpawnEvent
|
|
|
|
Entity entity = EntityType.loadEntityRecursive(nbttagcompound, world, EntitySpawnReason.SPAWNER, (entity1) -> {
|
|
entity1.moveTo(d0, d1, d2, entity1.getYRot(), entity1.getXRot());
|
|
@@ -157,13 +178,26 @@
|
|
((Mob) entity).finalizeSpawn(world, world.getCurrentDifficultyAt(entity.blockPosition()), EntitySpawnReason.SPAWNER, (SpawnGroupData) null);
|
|
}
|
|
|
|
- Optional optional1 = mobspawnerdata.getEquipment();
|
|
+ Optional<net.minecraft.world.entity.EquipmentTable> optional1 = mobspawnerdata.getEquipment(); // CraftBukkit - decompile error
|
|
|
|
Objects.requireNonNull(entityinsentient);
|
|
optional1.ifPresent(entityinsentient::equip);
|
|
+ // Spigot Start
|
|
+ if ( entityinsentient.level().spigotConfig.nerfSpawnerMobs )
|
|
+ {
|
|
+ entityinsentient.aware = false;
|
|
+ }
|
|
+ // Spigot End
|
|
}
|
|
|
|
- if (!world.tryAddFreshEntityWithPassengers(entity)) {
|
|
+ entity.spawnedViaMobSpawner = true; // Paper
|
|
+ flag = true; // Paper
|
|
+ // CraftBukkit start
|
|
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
|
|
+ continue;
|
|
+ }
|
|
+ if (!world.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER)) {
|
|
+ // CraftBukkit end
|
|
this.delay(world, pos);
|
|
return;
|
|
}
|
|
@@ -174,7 +208,7 @@
|
|
((Mob) entity).spawnAnim();
|
|
}
|
|
|
|
- flag = true;
|
|
+ //flag = true; // Paper - moved up above cancellable event
|
|
}
|
|
}
|
|
|