mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-08 19:34:09 +01:00
aebf9e869b
Uses correct setPositionRotation for Entity teleporting instead of setLocation as this is how Vanilla teleports entities. Cancel any pending motion when teleported.
166 lines
8.5 KiB
Diff
166 lines
8.5 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();
|
|
@@ -125,6 +132,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 +164,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 +179,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 +210,7 @@
|
|
((Mob) entity).spawnAnim();
|
|
}
|
|
|
|
- flag = true;
|
|
+ //flag = true; // Paper - moved up above cancellable event
|
|
}
|
|
}
|
|
|
|
@@ -202,7 +238,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 +267,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 +292,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);
|