mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-06 18:50:51 +01:00
167 lines
8.6 KiB
Diff
167 lines
8.6 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,19 @@
|
|
}
|
|
|
|
public void serverTick(ServerLevel world, BlockPos pos) {
|
|
+ if (spawnCount <= 0 || maxNearbyEntities <= 0) return; // Paper - Ignore impossible spawn tick
|
|
+ // 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();
|
|
@@ -125,6 +133,20 @@
|
|
} else if (!SpawnPlacements.checkSpawnRules((EntityType) optional.get(), world, EntitySpawnReason.SPAWNER, blockposition1, world.getRandom())) {
|
|
continue;
|
|
}
|
|
+ // Paper start - PreCreatureSpawnEvent
|
|
+ com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent event = new com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent(
|
|
+ io.papermc.paper.util.MCUtil.toLocation(world, d0, d1, d2),
|
|
+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(optional.get()),
|
|
+ io.papermc.paper.util.MCUtil.toLocation(world, pos)
|
|
+ );
|
|
+ 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());
|
|
@@ -143,6 +165,7 @@
|
|
return;
|
|
}
|
|
|
|
+ entity.preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; preserve entity motion from tag
|
|
entity.moveTo(entity.getX(), entity.getY(), entity.getZ(), randomsource.nextFloat() * 360.0F, 0.0F);
|
|
if (entity instanceof Mob) {
|
|
Mob entityinsentient = (Mob) entity;
|
|
@@ -157,13 +180,27 @@
|
|
((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
|
|
+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; // Paper - Entity#getEntitySpawnReason
|
|
+ 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 +211,7 @@
|
|
((Mob) entity).spawnAnim();
|
|
}
|
|
|
|
- flag = true;
|
|
+ //flag = true; // Paper - moved up above cancellable event
|
|
}
|
|
}
|
|
|
|
@@ -202,7 +239,13 @@
|
|
}
|
|
|
|
public void load(@Nullable Level world, BlockPos pos, CompoundTag nbt) {
|
|
+ // Paper start - use larger int if set
|
|
+ if (nbt.contains("Paper.Delay")) {
|
|
+ this.spawnDelay = nbt.getInt("Paper.Delay");
|
|
+ } else {
|
|
this.spawnDelay = nbt.getShort("Delay");
|
|
+ }
|
|
+ // Paper end
|
|
boolean flag = nbt.contains("SpawnData", 10);
|
|
|
|
if (flag) {
|
|
@@ -225,9 +268,15 @@
|
|
this.spawnPotentials = SimpleWeightedRandomList.single(this.nextSpawnData != null ? this.nextSpawnData : new SpawnData());
|
|
}
|
|
|
|
+ // Paper start - use ints if set
|
|
+ if (nbt.contains("Paper.MinSpawnDelay", net.minecraft.nbt.Tag.TAG_ANY_NUMERIC)) {
|
|
+ this.minSpawnDelay = nbt.getInt("Paper.MinSpawnDelay");
|
|
+ this.maxSpawnDelay = nbt.getInt("Paper.MaxSpawnDelay");
|
|
+ this.spawnCount = nbt.getShort("SpawnCount");
|
|
+ } else // Paper end
|
|
if (nbt.contains("MinSpawnDelay", 99)) {
|
|
- this.minSpawnDelay = nbt.getShort("MinSpawnDelay");
|
|
- this.maxSpawnDelay = nbt.getShort("MaxSpawnDelay");
|
|
+ this.minSpawnDelay = nbt.getInt("MinSpawnDelay"); // Paper - short -> int
|
|
+ this.maxSpawnDelay = nbt.getInt("MaxSpawnDelay"); // Paper - short -> int
|
|
this.spawnCount = nbt.getShort("SpawnCount");
|
|
}
|
|
|
|
@@ -244,9 +293,20 @@
|
|
}
|
|
|
|
public CompoundTag save(CompoundTag nbt) {
|
|
- nbt.putShort("Delay", (short) this.spawnDelay);
|
|
- nbt.putShort("MinSpawnDelay", (short) this.minSpawnDelay);
|
|
- nbt.putShort("MaxSpawnDelay", (short) this.maxSpawnDelay);
|
|
+ // Paper start
|
|
+ if (spawnDelay > Short.MAX_VALUE) {
|
|
+ nbt.putInt("Paper.Delay", this.spawnDelay);
|
|
+ }
|
|
+ nbt.putShort("Delay", (short) Math.min(Short.MAX_VALUE, this.spawnDelay));
|
|
+
|
|
+ if (minSpawnDelay > Short.MAX_VALUE || maxSpawnDelay > Short.MAX_VALUE) {
|
|
+ nbt.putInt("Paper.MinSpawnDelay", this.minSpawnDelay);
|
|
+ nbt.putInt("Paper.MaxSpawnDelay", this.maxSpawnDelay);
|
|
+ }
|
|
+
|
|
+ nbt.putShort("MinSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.minSpawnDelay));
|
|
+ nbt.putShort("MaxSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.maxSpawnDelay));
|
|
+ // Paper end
|
|
nbt.putShort("SpawnCount", (short) this.spawnCount);
|
|
nbt.putShort("MaxNearbyEntities", (short) this.maxNearbyEntities);
|
|
nbt.putShort("RequiredPlayerRange", (short) this.requiredPlayerRange);
|