mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 15:00:13 +01:00
More entity classes
This commit is contained in:
parent
64e61681f4
commit
ea14971545
4 changed files with 253 additions and 336 deletions
|
@ -0,0 +1,155 @@
|
||||||
|
--- a/net/minecraft/world/entity/EntityType.java
|
||||||
|
+++ b/net/minecraft/world/entity/EntityType.java
|
||||||
|
@@ -176,6 +_,7 @@
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import net.minecraft.world.phys.shapes.Shapes;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
+import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
public class EntityType<T extends Entity> implements FeatureElement, EntityTypeTest<Entity, T> {
|
||||||
|
@@ -215,7 +_,7 @@
|
||||||
|
.fireImmune()
|
||||||
|
.sized(6.0F, 0.5F)
|
||||||
|
.clientTrackingRange(10)
|
||||||
|
- .updateInterval(Integer.MAX_VALUE)
|
||||||
|
+ .updateInterval(10) // CraftBukkit - SPIGOT-3729: track area effect clouds
|
||||||
|
);
|
||||||
|
public static final EntityType<Armadillo> ARMADILLO = register(
|
||||||
|
"armadillo", EntityType.Builder.of(Armadillo::new, MobCategory.CREATURE).sized(0.7F, 0.65F).eyeHeight(0.26F).clientTrackingRange(10)
|
||||||
|
@@ -1132,6 +_,22 @@
|
||||||
|
boolean shouldOffsetY,
|
||||||
|
boolean shouldOffsetYMore
|
||||||
|
) {
|
||||||
|
+ // CraftBukkit start
|
||||||
|
+ return this.spawn(level, spawnedFrom, player, pos, reason, shouldOffsetY, shouldOffsetYMore, reason == EntitySpawnReason.DISPENSER ? org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DISPENSE_EGG : org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // Paper - use correct spawn reason for dispenser spawn eggs
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Nullable
|
||||||
|
+ public T spawn(
|
||||||
|
+ ServerLevel level,
|
||||||
|
+ @Nullable ItemStack spawnedFrom,
|
||||||
|
+ @Nullable Player player,
|
||||||
|
+ BlockPos pos,
|
||||||
|
+ EntitySpawnReason reason,
|
||||||
|
+ boolean shouldOffsetY,
|
||||||
|
+ boolean shouldOffsetYMore,
|
||||||
|
+ org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason createSpawnReason
|
||||||
|
+ ) {
|
||||||
|
+ // CraftBukkit end
|
||||||
|
Consumer<T> consumer;
|
||||||
|
if (spawnedFrom != null) {
|
||||||
|
consumer = createDefaultStackConfig(level, spawnedFrom, player);
|
||||||
|
@@ -1139,7 +_,7 @@
|
||||||
|
consumer = entity -> {};
|
||||||
|
}
|
||||||
|
|
||||||
|
- return this.spawn(level, consumer, pos, reason, shouldOffsetY, shouldOffsetYMore);
|
||||||
|
+ return this.spawn(level, consumer, pos, reason, shouldOffsetY, shouldOffsetYMore, createSpawnReason); // CraftBukkit
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Entity> Consumer<T> createDefaultStackConfig(Level level, ItemStack spawnedFrom, @Nullable Player player) {
|
||||||
|
@@ -1159,19 +_,54 @@
|
||||||
|
Consumer<T> consumer, Level level, ItemStack spawnedFrom, @Nullable Player player
|
||||||
|
) {
|
||||||
|
CustomData customData = spawnedFrom.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
|
||||||
|
- return !customData.isEmpty() ? consumer.andThen(entity -> updateCustomEntityTag(level, player, entity, customData)) : consumer;
|
||||||
|
+ // CraftBukkit start - SPIGOT-5665
|
||||||
|
+ return !customData.isEmpty() ? consumer.andThen(entity -> {
|
||||||
|
+ try {
|
||||||
|
+ updateCustomEntityTag(level, player, entity, customData);
|
||||||
|
+ } catch (Throwable t) {
|
||||||
|
+ EntityType.LOGGER.warn("Error loading spawn egg NBT", t);
|
||||||
|
+ }
|
||||||
|
+ }) : consumer;
|
||||||
|
+ // CraftBukkit end
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public T spawn(ServerLevel level, BlockPos pos, EntitySpawnReason reason) {
|
||||||
|
- return this.spawn(level, null, pos, reason, false, false);
|
||||||
|
+ // CraftBukkit start
|
||||||
|
+ return this.spawn(level, pos, reason, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
|
||||||
|
+ }
|
||||||
|
+ @Nullable
|
||||||
|
+ public T spawn(ServerLevel level, BlockPos pos, EntitySpawnReason reason, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason creatureSpawnReason) {
|
||||||
|
+ return this.spawn(level, null, pos, reason, false, false, creatureSpawnReason);
|
||||||
|
+ // CraftBukkit End
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public T spawn(ServerLevel level, @Nullable Consumer<T> consumer, BlockPos pos, EntitySpawnReason reason, boolean shouldOffsetY, boolean shouldOffsetYMore) {
|
||||||
|
+ // CraftBukkit start
|
||||||
|
+ return this.spawn(level, consumer, pos, reason, shouldOffsetY, shouldOffsetYMore, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
|
||||||
|
+ }
|
||||||
|
+ @Nullable
|
||||||
|
+ public T spawn(ServerLevel level, @Nullable Consumer<T> consumer, BlockPos pos, EntitySpawnReason reason, boolean shouldOffsetY, boolean shouldOffsetYMore, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason creatureSpawnReason) {
|
||||||
|
+ // CraftBukkit end
|
||||||
|
+ // Paper start - PreCreatureSpawnEvent
|
||||||
|
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
|
||||||
|
+ io.papermc.paper.util.MCUtil.toLocation(level, pos),
|
||||||
|
+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(this),
|
||||||
|
+ creatureSpawnReason
|
||||||
|
+ );
|
||||||
|
+ if (!event.callEvent()) {
|
||||||
|
+ return null;
|
||||||
|
+ }
|
||||||
|
+ // Paper end - PreCreatureSpawnEvent
|
||||||
|
T entity = this.create(level, consumer, pos, reason, shouldOffsetY, shouldOffsetYMore);
|
||||||
|
if (entity != null) {
|
||||||
|
- level.addFreshEntityWithPassengers(entity);
|
||||||
|
+ // CraftBukkit start
|
||||||
|
+ level.addFreshEntityWithPassengers(entity, creatureSpawnReason);
|
||||||
|
+ if (entity.isRemoved()) {
|
||||||
|
+ return null; // Don't return an entity when CreatureSpawnEvent is canceled
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
if (entity instanceof Mob mob) {
|
||||||
|
mob.playAmbientSound();
|
||||||
|
}
|
||||||
|
@@ -1225,6 +_,15 @@
|
||||||
|
EntityType<?> entityType = customData.parseEntityType(server.registryAccess(), Registries.ENTITY_TYPE);
|
||||||
|
if (entity.getType() == entityType) {
|
||||||
|
if (level.isClientSide || !entity.getType().onlyOpCanSetNbt() || player != null && server.getPlayerList().isOp(player.getGameProfile())) {
|
||||||
|
+ // Paper start - filter out protected tags
|
||||||
|
+ if (player == null || !player.getBukkitEntity().hasPermission("minecraft.nbt.place")) {
|
||||||
|
+ customData = customData.update((compound) -> {
|
||||||
|
+ for (net.minecraft.commands.arguments.NbtPathArgument.NbtPath tag : level.paperConfig().entities.spawning.filteredEntityTagNbtPaths) {
|
||||||
|
+ tag.remove(compound);
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
+ // Paper end - filter out protected tags
|
||||||
|
customData.loadInto(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1296,9 +_,19 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<Entity> create(CompoundTag tag, Level level, EntitySpawnReason spawnReason) {
|
||||||
|
+ // Paper start - Don't fire sync event during generation
|
||||||
|
+ return create(tag, level, spawnReason, false);
|
||||||
|
+ }
|
||||||
|
+ public static Optional<Entity> create(CompoundTag tag, Level level, EntitySpawnReason spawnReason, boolean generation) {
|
||||||
|
+ // Paper end - Don't fire sync event during generation
|
||||||
|
return Util.ifElse(
|
||||||
|
by(tag).map(entityType -> entityType.create(level, spawnReason)),
|
||||||
|
- entity -> entity.load(tag),
|
||||||
|
+ // Paper start - Don't fire sync event during generation
|
||||||
|
+ entity -> {
|
||||||
|
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
|
||||||
|
+ entity.load(tag);
|
||||||
|
+ },
|
||||||
|
+ // Paper end - Don't fire sync event during generation
|
||||||
|
() -> LOGGER.warn("Skipping Entity with id {}", tag.getString("id"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@@ -1325,7 +_,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<EntityType<?>> by(CompoundTag tag) {
|
||||||
|
- return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.parse(tag.getString("id")));
|
||||||
|
+ return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(tag.getString("id"))); // Paper - Validate ResourceLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
|
@ -0,0 +1,98 @@
|
||||||
|
--- a/net/minecraft/world/entity/Leashable.java
|
||||||
|
+++ b/net/minecraft/world/entity/Leashable.java
|
||||||
|
@@ -56,7 +_,13 @@
|
||||||
|
@Nullable
|
||||||
|
private static Leashable.LeashData readLeashDataInternal(CompoundTag tag) {
|
||||||
|
if (tag.contains("leash", 10)) {
|
||||||
|
- return new Leashable.LeashData(Either.left(tag.getCompound("leash").getUUID("UUID")));
|
||||||
|
+ // Paper start
|
||||||
|
+ final CompoundTag leashTag = tag.getCompound("leash");
|
||||||
|
+ if (!leashTag.hasUUID("UUID")) {
|
||||||
|
+ return null;
|
||||||
|
+ }
|
||||||
|
+ return new Leashable.LeashData(Either.left(leashTag.getUUID("UUID")));
|
||||||
|
+ // Paper end
|
||||||
|
} else {
|
||||||
|
if (tag.contains("leash", 11)) {
|
||||||
|
Either<UUID, BlockPos> either = NbtUtils.readBlockPos(tag, "leash").<Either<UUID, BlockPos>>map(Either::right).orElse(null);
|
||||||
|
@@ -72,6 +_,11 @@
|
||||||
|
default void writeLeashData(CompoundTag tag, @Nullable Leashable.LeashData leashData) {
|
||||||
|
if (leashData != null) {
|
||||||
|
Either<UUID, BlockPos> either = leashData.delayedLeashInfo;
|
||||||
|
+ // CraftBukkit start - SPIGOT-7487: Don't save (and possible drop) leash, when the holder was removed by a plugin
|
||||||
|
+ if (leashData.leashHolder != null && leashData.leashHolder.pluginRemoved) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
if (leashData.leashHolder instanceof LeashFenceKnotEntity leashFenceKnotEntity) {
|
||||||
|
either = Either.right(leashFenceKnotEntity.getPos());
|
||||||
|
} else if (leashData.leashHolder != null) {
|
||||||
|
@@ -104,7 +_,9 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.tickCount > 100) {
|
||||||
|
+ entity.forceDrops = true; // CraftBukkit
|
||||||
|
entity.spawnAtLocation(serverLevel, Items.LEAD);
|
||||||
|
+ entity.forceDrops = false; // CraftBukkit
|
||||||
|
entity.setLeashData(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -128,7 +_,9 @@
|
||||||
|
entity.onLeashRemoved();
|
||||||
|
if (entity.level() instanceof ServerLevel serverLevel) {
|
||||||
|
if (dropItem) {
|
||||||
|
+ entity.forceDrops = true; // CraftBukkit
|
||||||
|
entity.spawnAtLocation(serverLevel, Items.LEAD);
|
||||||
|
+ entity.forceDrops = false; // CraftBukkit
|
||||||
|
}
|
||||||
|
|
||||||
|
if (broadcastPacket) {
|
||||||
|
@@ -146,7 +_,15 @@
|
||||||
|
|
||||||
|
if (leashData != null && leashData.leashHolder != null) {
|
||||||
|
if (!entity.isAlive() || !leashData.leashHolder.isAlive()) {
|
||||||
|
- if (level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
|
||||||
|
+ // Paper start - Expand EntityUnleashEvent
|
||||||
|
+ final org.bukkit.event.entity.EntityUnleashEvent event = new org.bukkit.event.entity.EntityUnleashEvent(
|
||||||
|
+ entity.getBukkitEntity(),
|
||||||
|
+ !entity.isAlive() ? org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.PLAYER_UNLEASH : org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.HOLDER_GONE,
|
||||||
|
+ level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS) && !entity.pluginRemoved
|
||||||
|
+ );
|
||||||
|
+ event.callEvent();
|
||||||
|
+ if (event.isDropLeash()) { // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin
|
||||||
|
+ // Paper end - Expand EntityUnleashEvent
|
||||||
|
entity.dropLeash();
|
||||||
|
} else {
|
||||||
|
entity.removeLeash();
|
||||||
|
@@ -160,7 +_,7 @@
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (f > 10.0) {
|
||||||
|
+ if (f > entity.level().paperConfig().misc.maxLeashDistance.or(LEASH_TOO_FAR_DIST)) { // Paper - Configurable max leash distance
|
||||||
|
entity.leashTooFarBehaviour();
|
||||||
|
} else if (f > 6.0) {
|
||||||
|
entity.elasticRangeLeashBehaviour(leashHolder, f);
|
||||||
|
@@ -177,7 +_,21 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
default void leashTooFarBehaviour() {
|
||||||
|
- this.dropLeash();
|
||||||
|
+ // CraftBukkit start
|
||||||
|
+ boolean dropLeash = true; // Paper
|
||||||
|
+ if (this instanceof Entity entity) {
|
||||||
|
+ // Paper start - Expand EntityUnleashEvent
|
||||||
|
+ final org.bukkit.event.entity.EntityUnleashEvent event = new org.bukkit.event.entity.EntityUnleashEvent(entity.getBukkitEntity(), org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.DISTANCE, true);
|
||||||
|
+ if (!event.callEvent()) return;
|
||||||
|
+ dropLeash = event.isDropLeash();
|
||||||
|
+ }
|
||||||
|
+ // CraftBukkit end
|
||||||
|
+ if (dropLeash) {
|
||||||
|
+ this.dropLeash();
|
||||||
|
+ } else {
|
||||||
|
+ this.removeLeash();
|
||||||
|
+ }
|
||||||
|
+ // Paper end - Expand EntityUnleashEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
default void closeRangeLeashBehaviour(Entity entity) {
|
|
@ -1,179 +0,0 @@
|
||||||
--- a/net/minecraft/world/entity/EntityType.java
|
|
||||||
+++ b/net/minecraft/world/entity/EntityType.java
|
|
||||||
@@ -176,6 +176,7 @@
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import net.minecraft.world.phys.shapes.Shapes;
|
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
||||||
+import org.bukkit.event.entity.CreatureSpawnEvent;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
public class EntityType<T extends Entity> implements FeatureElement, EntityTypeTest<Entity, T> {
|
|
||||||
@@ -191,7 +192,7 @@
|
|
||||||
return Items.ACACIA_CHEST_BOAT;
|
|
||||||
}), MobCategory.MISC).noLootTable().sized(1.375F, 0.5625F).eyeHeight(0.5625F).clientTrackingRange(10));
|
|
||||||
public static final EntityType<Allay> ALLAY = EntityType.register("allay", EntityType.Builder.of(Allay::new, MobCategory.CREATURE).sized(0.35F, 0.6F).eyeHeight(0.36F).ridingOffset(0.04F).clientTrackingRange(8).updateInterval(2));
|
|
||||||
- public static final EntityType<AreaEffectCloud> AREA_EFFECT_CLOUD = EntityType.register("area_effect_cloud", EntityType.Builder.of(AreaEffectCloud::new, MobCategory.MISC).noLootTable().fireImmune().sized(6.0F, 0.5F).clientTrackingRange(10).updateInterval(Integer.MAX_VALUE));
|
|
||||||
+ public static final EntityType<AreaEffectCloud> AREA_EFFECT_CLOUD = EntityType.register("area_effect_cloud", EntityType.Builder.of(AreaEffectCloud::new, MobCategory.MISC).noLootTable().fireImmune().sized(6.0F, 0.5F).clientTrackingRange(10).updateInterval(10)); // CraftBukkit - SPIGOT-3729: track area effect clouds
|
|
||||||
public static final EntityType<Armadillo> ARMADILLO = EntityType.register("armadillo", EntityType.Builder.of(Armadillo::new, MobCategory.CREATURE).sized(0.7F, 0.65F).eyeHeight(0.26F).clientTrackingRange(10));
|
|
||||||
public static final EntityType<ArmorStand> ARMOR_STAND = EntityType.register("armor_stand", EntityType.Builder.of(ArmorStand::new, MobCategory.MISC).sized(0.5F, 1.975F).eyeHeight(1.7775F).clientTrackingRange(10));
|
|
||||||
public static final EntityType<Arrow> ARROW = EntityType.register("arrow", EntityType.Builder.of(Arrow::new, MobCategory.MISC).noLootTable().sized(0.5F, 0.5F).eyeHeight(0.13F).clientTrackingRange(4).updateInterval(20));
|
|
||||||
@@ -399,7 +400,7 @@
|
|
||||||
return ResourceKey.create(Registries.ENTITY_TYPE, ResourceLocation.withDefaultNamespace(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
- private static <T extends Entity> EntityType<T> register(String id, EntityType.Builder<T> type) {
|
|
||||||
+ private static <T extends Entity> EntityType<T> register(String id, EntityType.Builder type) { // CraftBukkit - decompile error
|
|
||||||
return EntityType.register(EntityType.vanillaEntityId(id), type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -431,16 +432,23 @@
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public T spawn(ServerLevel world, @Nullable ItemStack stack, @Nullable Player player, BlockPos pos, EntitySpawnReason spawnReason, boolean alignPosition, boolean invertY) {
|
|
||||||
- Consumer consumer;
|
|
||||||
+ // CraftBukkit start
|
|
||||||
+ return this.spawn(world, stack, player, pos, spawnReason, alignPosition, invertY, spawnReason == EntitySpawnReason.DISPENSER ? org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DISPENSE_EGG : org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // Paper - use correct spawn reason for dispenser spawn eggs
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- if (stack != null) {
|
|
||||||
- consumer = EntityType.createDefaultStackConfig(world, stack, player);
|
|
||||||
+ @Nullable
|
|
||||||
+ public T spawn(ServerLevel worldserver, @Nullable ItemStack itemstack, @Nullable Player entityhuman, BlockPos blockposition, EntitySpawnReason entityspawnreason, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
|
|
||||||
+ // CraftBukkit end
|
|
||||||
+ Consumer<T> consumer; // CraftBukkit - decompile error
|
|
||||||
+
|
|
||||||
+ if (itemstack != null) {
|
|
||||||
+ consumer = EntityType.createDefaultStackConfig(worldserver, itemstack, entityhuman);
|
|
||||||
} else {
|
|
||||||
consumer = (entity) -> {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
- return this.spawn(world, consumer, pos, spawnReason, alignPosition, invertY);
|
|
||||||
+ return this.spawn(worldserver, consumer, blockposition, entityspawnreason, flag, flag1, spawnReason); // CraftBukkit
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends Entity> Consumer<T> createDefaultStackConfig(Level world, ItemStack stack, @Nullable Player player) {
|
|
||||||
@@ -464,21 +472,50 @@
|
|
||||||
CustomData customdata = (CustomData) stack.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
|
|
||||||
|
|
||||||
return !customdata.isEmpty() ? chained.andThen((entity) -> {
|
|
||||||
- EntityType.updateCustomEntityTag(world, player, entity, customdata);
|
|
||||||
+ try { EntityType.updateCustomEntityTag(world, player, entity, customdata); } catch (Throwable t) { EntityType.LOGGER.warn("Error loading spawn egg NBT", t); } // CraftBukkit - SPIGOT-5665
|
|
||||||
}) : chained;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public T spawn(ServerLevel world, BlockPos pos, EntitySpawnReason reason) {
|
|
||||||
- return this.spawn(world, (Consumer) null, pos, reason, false, false);
|
|
||||||
+ // CraftBukkit start
|
|
||||||
+ return this.spawn(world, pos, reason, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
+ public T spawn(ServerLevel worldserver, BlockPos blockposition, EntitySpawnReason entityspawnreason, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
|
|
||||||
+ return this.spawn(worldserver, (Consumer<T>) null, blockposition, entityspawnreason, false, false, spawnReason); // CraftBukkit - decompile error
|
|
||||||
+ // CraftBukkit end
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @Nullable
|
|
||||||
public T spawn(ServerLevel world, @Nullable Consumer<T> afterConsumer, BlockPos pos, EntitySpawnReason reason, boolean alignPosition, boolean invertY) {
|
|
||||||
- T t0 = this.create(world, afterConsumer, pos, reason, alignPosition, invertY);
|
|
||||||
+ // CraftBukkit start
|
|
||||||
+ return this.spawn(world, afterConsumer, pos, reason, alignPosition, invertY, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @Nullable
|
|
||||||
+ public T spawn(ServerLevel worldserver, @Nullable Consumer<T> consumer, BlockPos blockposition, EntitySpawnReason entityspawnreason, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
|
|
||||||
+ // CraftBukkit end
|
|
||||||
+ // Paper start - PreCreatureSpawnEvent
|
|
||||||
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
|
|
||||||
+ io.papermc.paper.util.MCUtil.toLocation(worldserver, blockposition),
|
|
||||||
+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(this),
|
|
||||||
+ spawnReason
|
|
||||||
+ );
|
|
||||||
+ if (!event.callEvent()) {
|
|
||||||
+ return null;
|
|
||||||
+ }
|
|
||||||
+ // Paper end - PreCreatureSpawnEvent
|
|
||||||
+ T t0 = this.create(worldserver, consumer, blockposition, entityspawnreason, flag, flag1);
|
|
||||||
|
|
||||||
if (t0 != null) {
|
|
||||||
- world.addFreshEntityWithPassengers(t0);
|
|
||||||
+ // CraftBukkit start
|
|
||||||
+ worldserver.addFreshEntityWithPassengers(t0, spawnReason);
|
|
||||||
+ if (t0.isRemoved()) {
|
|
||||||
+ return null; // Don't return an entity when CreatureSpawnEvent is canceled
|
|
||||||
+ }
|
|
||||||
+ // CraftBukkit end
|
|
||||||
if (t0 instanceof Mob) {
|
|
||||||
Mob entityinsentient = (Mob) t0;
|
|
||||||
|
|
||||||
@@ -542,6 +579,15 @@
|
|
||||||
|
|
||||||
if (entity.getType() == entitytypes) {
|
|
||||||
if (world.isClientSide || !entity.getType().onlyOpCanSetNbt() || player != null && minecraftserver.getPlayerList().isOp(player.getGameProfile())) {
|
|
||||||
+ // Paper start - filter out protected tags
|
|
||||||
+ if (player == null || !player.getBukkitEntity().hasPermission("minecraft.nbt.place")) {
|
|
||||||
+ nbt = nbt.update((compound) -> {
|
|
||||||
+ for (net.minecraft.commands.arguments.NbtPathArgument.NbtPath tag : world.paperConfig().entities.spawning.filteredEntityTagNbtPaths) {
|
|
||||||
+ tag.remove(compound);
|
|
||||||
+ }
|
|
||||||
+ });
|
|
||||||
+ }
|
|
||||||
+ // Paper end - filter out protected tags
|
|
||||||
nbt.loadInto(entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -613,9 +659,15 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<Entity> create(CompoundTag nbt, Level world, EntitySpawnReason reason) {
|
|
||||||
+ // Paper start - Don't fire sync event during generation
|
|
||||||
+ return create(nbt, world, reason, false);
|
|
||||||
+ }
|
|
||||||
+ public static Optional<Entity> create(CompoundTag nbt, Level world, EntitySpawnReason reason, boolean generation) {
|
|
||||||
+ // Paper end - Don't fire sync event during generation
|
|
||||||
return Util.ifElse(EntityType.by(nbt).map((entitytypes) -> {
|
|
||||||
return entitytypes.create(world, reason);
|
|
||||||
}), (entity) -> {
|
|
||||||
+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
|
|
||||||
entity.load(nbt);
|
|
||||||
}, () -> {
|
|
||||||
EntityType.LOGGER.warn("Skipping Entity with id {}", nbt.getString("id"));
|
|
||||||
@@ -638,7 +690,7 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<EntityType<?>> by(CompoundTag nbt) {
|
|
||||||
- return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.parse(nbt.getString("id")));
|
|
||||||
+ return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(nbt.getString("id"))); // Paper - Validate ResourceLocation
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@@ -657,7 +709,7 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
return entity;
|
|
||||||
- }).orElse((Object) null);
|
|
||||||
+ }).orElse(null); // CraftBukkit - decompile error
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Stream<Entity> loadEntitiesRecursive(final List<? extends Tag> entityNbtList, final Level world, final EntitySpawnReason reason) {
|
|
||||||
@@ -718,7 +770,7 @@
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public T tryCast(Entity obj) {
|
|
||||||
- return obj.getType() == this ? obj : null;
|
|
||||||
+ return obj.getType() == this ? (T) obj : null; // CraftBukkit - decompile error
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@@ -791,7 +843,7 @@
|
|
||||||
this.canSpawnFarFromPlayer = spawnGroup == MobCategory.CREATURE || spawnGroup == MobCategory.MISC;
|
|
||||||
}
|
|
||||||
|
|
||||||
- public static <T extends Entity> EntityType.Builder<T> of(EntityType.EntityFactory<T> factory, MobCategory spawnGroup) {
|
|
||||||
+ public static <T extends Entity> EntityType.Builder<T> of(EntityType.EntityFactory factory, MobCategory spawnGroup) { // CraftBukkit - decompile error
|
|
||||||
return new EntityType.Builder<>(factory, spawnGroup);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,157 +0,0 @@
|
||||||
--- a/net/minecraft/world/entity/Leashable.java
|
|
||||||
+++ b/net/minecraft/world/entity/Leashable.java
|
|
||||||
@@ -15,6 +15,10 @@
|
|
||||||
import net.minecraft.world.level.GameRules;
|
|
||||||
import net.minecraft.world.level.ItemLike;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
+// CraftBukkit start
|
|
||||||
+import org.bukkit.event.entity.EntityUnleashEvent;
|
|
||||||
+import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason;
|
|
||||||
+// CraftBukkit end
|
|
||||||
|
|
||||||
public interface Leashable {
|
|
||||||
|
|
||||||
@@ -45,7 +49,7 @@
|
|
||||||
|
|
||||||
default void setDelayedLeashHolderId(int unresolvedLeashHolderId) {
|
|
||||||
this.setLeashData(new Leashable.LeashData(unresolvedLeashHolderId));
|
|
||||||
- Leashable.dropLeash((Entity) this, false, false);
|
|
||||||
+ Leashable.dropLeash((Entity & Leashable) this, false, false); // CraftBukkit - decompile error
|
|
||||||
}
|
|
||||||
|
|
||||||
default void readLeashData(CompoundTag nbt) {
|
|
||||||
@@ -61,10 +65,16 @@
|
|
||||||
@Nullable
|
|
||||||
private static Leashable.LeashData readLeashDataInternal(CompoundTag nbt) {
|
|
||||||
if (nbt.contains("leash", 10)) {
|
|
||||||
- return new Leashable.LeashData(Either.left(nbt.getCompound("leash").getUUID("UUID")));
|
|
||||||
+ // Paper start
|
|
||||||
+ final CompoundTag leashTag = nbt.getCompound("leash");
|
|
||||||
+ if (!leashTag.hasUUID("UUID")) {
|
|
||||||
+ return null;
|
|
||||||
+ }
|
|
||||||
+ return new Leashable.LeashData(Either.left(leashTag.getUUID("UUID")));
|
|
||||||
+ // Paper end
|
|
||||||
} else {
|
|
||||||
if (nbt.contains("leash", 11)) {
|
|
||||||
- Either<UUID, BlockPos> either = (Either) NbtUtils.readBlockPos(nbt, "leash").map(Either::right).orElse((Object) null);
|
|
||||||
+ Either<UUID, BlockPos> either = (Either) NbtUtils.readBlockPos(nbt, "leash").map(Either::right).orElse(null); // CraftBukkit - decompile error
|
|
||||||
|
|
||||||
if (either != null) {
|
|
||||||
return new Leashable.LeashData(either);
|
|
||||||
@@ -79,6 +89,11 @@
|
|
||||||
if (leashData != null) {
|
|
||||||
Either<UUID, BlockPos> either = leashData.delayedLeashInfo;
|
|
||||||
Entity entity = leashData.leashHolder;
|
|
||||||
+ // CraftBukkit start - SPIGOT-7487: Don't save (and possible drop) leash, when the holder was removed by a plugin
|
|
||||||
+ if (entity != null && entity.pluginRemoved) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ // CraftBukkit end
|
|
||||||
|
|
||||||
if (entity instanceof LeashFenceKnotEntity) {
|
|
||||||
LeashFenceKnotEntity entityleash = (LeashFenceKnotEntity) entity;
|
|
||||||
@@ -121,7 +136,9 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity.tickCount > 100) {
|
|
||||||
+ entity.forceDrops = true; // CraftBukkit
|
|
||||||
entity.spawnAtLocation(worldserver, (ItemLike) Items.LEAD);
|
|
||||||
+ entity.forceDrops = false; // CraftBukkit
|
|
||||||
((Leashable) entity).setLeashData((Leashable.LeashData) null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -130,11 +147,11 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
default void dropLeash() {
|
|
||||||
- Leashable.dropLeash((Entity) this, true, true);
|
|
||||||
+ Leashable.dropLeash((Entity & Leashable) this, true, true); // CraftBukkit - decompile error
|
|
||||||
}
|
|
||||||
|
|
||||||
default void removeLeash() {
|
|
||||||
- Leashable.dropLeash((Entity) this, true, false);
|
|
||||||
+ Leashable.dropLeash((Entity & Leashable) this, true, false); // CraftBukkit - decompile error
|
|
||||||
}
|
|
||||||
|
|
||||||
default void onLeashRemoved() {}
|
|
||||||
@@ -151,7 +168,9 @@
|
|
||||||
ServerLevel worldserver = (ServerLevel) world;
|
|
||||||
|
|
||||||
if (dropItem) {
|
|
||||||
+ entity.forceDrops = true; // CraftBukkit
|
|
||||||
entity.spawnAtLocation(worldserver, (ItemLike) Items.LEAD);
|
|
||||||
+ entity.forceDrops = false; // CraftBukkit
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sendPacket) {
|
|
||||||
@@ -171,7 +190,11 @@
|
|
||||||
|
|
||||||
if (leashable_a != null && leashable_a.leashHolder != null) {
|
|
||||||
if (!entity.isAlive() || !leashable_a.leashHolder.isAlive()) {
|
|
||||||
- if (world.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
|
|
||||||
+ // Paper start - Expand EntityUnleashEvent
|
|
||||||
+ final EntityUnleashEvent event = new EntityUnleashEvent(entity.getBukkitEntity(), (!entity.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE, world.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS) && !entity.pluginRemoved);
|
|
||||||
+ event.callEvent();
|
|
||||||
+ if (event.isDropLeash()) { // CraftBukkit - SPIGOT-7487: Don't drop leash, when the holder was removed by a plugin
|
|
||||||
+ // Paper end - Expand EntityUnleashEvent
|
|
||||||
((Leashable) entity).dropLeash();
|
|
||||||
} else {
|
|
||||||
((Leashable) entity).removeLeash();
|
|
||||||
@@ -187,7 +210,7 @@
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if ((double) f > 10.0D) {
|
|
||||||
+ if ((double) f > entity.level().paperConfig().misc.maxLeashDistance.or(LEASH_TOO_FAR_DIST)) { // Paper - Configurable max leash distance
|
|
||||||
((Leashable) entity).leashTooFarBehaviour();
|
|
||||||
} else if ((double) f > 6.0D) {
|
|
||||||
((Leashable) entity).elasticRangeLeashBehaviour(entity1, f);
|
|
||||||
@@ -205,13 +228,27 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
default void leashTooFarBehaviour() {
|
|
||||||
- this.dropLeash();
|
|
||||||
+ // CraftBukkit start
|
|
||||||
+ boolean dropLeash = true; // Paper
|
|
||||||
+ if (this instanceof Entity entity) {
|
|
||||||
+ // Paper start - Expand EntityUnleashEvent
|
|
||||||
+ final EntityUnleashEvent event = new EntityUnleashEvent(entity.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE, true);
|
|
||||||
+ if (!event.callEvent()) return;
|
|
||||||
+ dropLeash = event.isDropLeash();
|
|
||||||
+ }
|
|
||||||
+ // CraftBukkit end
|
|
||||||
+ if (dropLeash) {
|
|
||||||
+ this.dropLeash();
|
|
||||||
+ } else {
|
|
||||||
+ this.removeLeash();
|
|
||||||
+ }
|
|
||||||
+ // Paper end - Expand EntityUnleashEvent
|
|
||||||
}
|
|
||||||
|
|
||||||
default void closeRangeLeashBehaviour(Entity entity) {}
|
|
||||||
|
|
||||||
default void elasticRangeLeashBehaviour(Entity leashHolder, float distance) {
|
|
||||||
- Leashable.legacyElasticRangeLeashBehaviour((Entity) this, leashHolder, distance);
|
|
||||||
+ Leashable.legacyElasticRangeLeashBehaviour((Entity & Leashable) this, leashHolder, distance); // CraftBukkit - decompile error
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <E extends Entity & Leashable> void legacyElasticRangeLeashBehaviour(E entity, Entity leashHolder, float distance) {
|
|
||||||
@@ -223,7 +260,7 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
default void setLeashedTo(Entity leashHolder, boolean sendPacket) {
|
|
||||||
- this.setLeashedTo((Entity) this, leashHolder, sendPacket);
|
|
||||||
+ Leashable.setLeashedTo((Entity & Leashable) this, leashHolder, sendPacket); // CraftBukkit - decompile error
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <E extends Entity & Leashable> void setLeashedTo(E entity, Entity leashHolder, boolean sendPacket) {
|
|
||||||
@@ -254,7 +291,7 @@
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
default Entity getLeashHolder() {
|
|
||||||
- return Leashable.getLeashHolder((Entity) this);
|
|
||||||
+ return Leashable.getLeashHolder((Entity & Leashable) this); // CraftBukkit - decompile error
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
Loading…
Reference in a new issue