Add AsyncPortalCreateEvent
This commit is contained in:
parent
506f1651e5
commit
5d2085c986
2 changed files with 497 additions and 0 deletions
181
patches/api/0481-Add-AsyncPortalCreateEvent.patch
Normal file
181
patches/api/0481-Add-AsyncPortalCreateEvent.patch
Normal file
|
@ -0,0 +1,181 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 16 May 2021 13:40:23 -0700
|
||||
Subject: [PATCH] Add AsyncPortalCreateEvent
|
||||
|
||||
calls AsyncPortalCreateEvent in more places than
|
||||
PortalCreateEvent and with more reasons
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/event/world/AsyncPortalCreateEvent.java b/src/main/java/io/papermc/paper/event/world/AsyncPortalCreateEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..140e914626855d39376088761aaab6194f09bc3d
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/event/world/AsyncPortalCreateEvent.java
|
||||
@@ -0,0 +1,145 @@
|
||||
+package io.papermc.paper.event.world;
|
||||
+
|
||||
+import java.util.List;
|
||||
+import org.bukkit.RegionAccessor;
|
||||
+import org.bukkit.block.BlockState;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.server.ServerEvent;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.jetbrains.annotations.ApiStatus;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a portal is created.
|
||||
+ * <p>
|
||||
+ * May be triggered asynchronously. Use {@link Event#isAsynchronous()} to check.
|
||||
+ * </p>
|
||||
+ */
|
||||
+public class AsyncPortalCreateEvent extends ServerEvent implements Cancellable {
|
||||
+
|
||||
+ private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
+
|
||||
+ private final RegionAccessor regionAccessor;
|
||||
+ private final List<BlockState> blocks;
|
||||
+ private final Entity entity;
|
||||
+ private final CreateReason reason;
|
||||
+ private boolean cancel;
|
||||
+
|
||||
+ @ApiStatus.Internal
|
||||
+ public AsyncPortalCreateEvent(final boolean isAsync, final @NonNull RegionAccessor regionAccessor, final @NonNull List<BlockState> blocks, final @Nullable Entity entity, final @NonNull CreateReason reason) {
|
||||
+ super(isAsync);
|
||||
+ this.regionAccessor = regionAccessor;
|
||||
+ this.blocks = blocks;
|
||||
+ this.entity = entity;
|
||||
+ this.reason = reason;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the region accessor which may be a {@link org.bukkit.World} or
|
||||
+ * a {@link org.bukkit.generator.LimitedRegion}.
|
||||
+ *
|
||||
+ * @return the region accessor
|
||||
+ */
|
||||
+ public @NonNull RegionAccessor getRegionAccessor() {
|
||||
+ return this.regionAccessor;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets an array list of all the blocks associated with the created portal
|
||||
+ *
|
||||
+ * @return array list of all the blocks associated with the created portal
|
||||
+ */
|
||||
+ public @NonNull List<BlockState> getBlocks() {
|
||||
+ return this.blocks;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the Entity that triggered this portal creation (if available)
|
||||
+ *
|
||||
+ * @return Entity involved in this event
|
||||
+ */
|
||||
+ public @Nullable Entity getEntity() {
|
||||
+ return this.entity;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return this.cancel;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(final boolean cancel) {
|
||||
+ this.cancel = cancel;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the reason for the portal's creation
|
||||
+ *
|
||||
+ * @return CreateReason for the portal's creation
|
||||
+ */
|
||||
+ public @NonNull CreateReason getReason() {
|
||||
+ return this.reason;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NonNull HandlerList getHandlers() {
|
||||
+ return HANDLER_LIST;
|
||||
+ }
|
||||
+
|
||||
+ public static @NonNull HandlerList getHandlerList() {
|
||||
+ return HANDLER_LIST;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * An enum to specify the various reasons for a portal's creation
|
||||
+ */
|
||||
+ public enum CreateReason {
|
||||
+ /**
|
||||
+ * When the blocks inside a portal are created due to a portal frame
|
||||
+ * being set on fire.
|
||||
+ */
|
||||
+ FIRE,
|
||||
+ /**
|
||||
+ * When a nether portal frame and portal is created at the exit of an
|
||||
+ * entered nether portal.
|
||||
+ */
|
||||
+ NETHER_PAIR,
|
||||
+ /**
|
||||
+ * When the target end platform is created as a result of a player
|
||||
+ * entering an end portal.
|
||||
+ */
|
||||
+ END_PLATFORM,
|
||||
+ /**
|
||||
+ * When the ender dragon is defeated and a new end gateway
|
||||
+ * is generated on the main end island.
|
||||
+ */
|
||||
+ END_GATEWAY_DRAGON_DEFEAT,
|
||||
+
|
||||
+ /**
|
||||
+ * When an entity causes the generation of an end gateway
|
||||
+ * by going through one that does not have a linked gateway.
|
||||
+ */
|
||||
+ END_GATEWAY_PAIR,
|
||||
+
|
||||
+ /**
|
||||
+ * When an inactive end portal is generated on the main end
|
||||
+ * island in the end dimension. This can happen in normal world generation or
|
||||
+ * when a new dragon is spawned, replacing the active portal with a inactive one.
|
||||
+ */
|
||||
+ END_PORTAL,
|
||||
+
|
||||
+ /**
|
||||
+ * When an active end portal is generated on the main end
|
||||
+ * island in the end dimension.
|
||||
+ */
|
||||
+ ACTIVE_END_PORTAL,
|
||||
+
|
||||
+ /**
|
||||
+ * Fallback reason
|
||||
+ */
|
||||
+ UNKNOWN,
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/event/world/PortalCreateEvent.java b/src/main/java/org/bukkit/event/world/PortalCreateEvent.java
|
||||
index 579f017474ff22f0991ca884c35cdde7e14a94dc..8e6450d14a6ad16a22f8725f623944b83ebc4580 100644
|
||||
--- a/src/main/java/org/bukkit/event/world/PortalCreateEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/world/PortalCreateEvent.java
|
||||
@@ -11,7 +11,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Called when a portal is created
|
||||
+ * @deprecated use {@link io.papermc.paper.event.world.AsyncPortalCreateEvent}
|
||||
*/
|
||||
+@Deprecated(since = "1.21")
|
||||
public class PortalCreateEvent extends WorldEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancel = false;
|
||||
@@ -26,7 +28,6 @@ public class PortalCreateEvent extends WorldEvent implements Cancellable {
|
||||
|
||||
public PortalCreateEvent(@NotNull final List<BlockState> blocks, @NotNull final World world, @Nullable Entity entity, @NotNull CreateReason reason) {
|
||||
super(world);
|
||||
-
|
||||
this.blocks = blocks;
|
||||
this.entity = entity;
|
||||
this.reason = reason;
|
316
patches/server/1042-Add-AsyncPortalCreateEvent.patch
Normal file
316
patches/server/1042-Add-AsyncPortalCreateEvent.patch
Normal file
|
@ -0,0 +1,316 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 16 May 2021 13:40:35 -0700
|
||||
Subject: [PATCH] Add AsyncPortalCreateEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
index 89df488afeffd0c060d2d0e7fae16daf978bd192..2075364594746bca4d06df3aa2089b7263226b0f 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
@@ -142,17 +142,23 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity {
|
||||
|
||||
@Nullable
|
||||
public Vec3 getPortalPosition(ServerLevel world, BlockPos pos) {
|
||||
+ // Paper start - add entity param
|
||||
+ return this.getPortalPosition(world, pos, null);
|
||||
+ }
|
||||
+ @Nullable
|
||||
+ public Vec3 getPortalPosition(ServerLevel world, BlockPos pos, @Nullable net.minecraft.world.entity.Entity entity) {
|
||||
+ // Paper end - add entity param
|
||||
BlockPos blockposition1;
|
||||
|
||||
if (this.exitPortal == null && world.getTypeKey() == LevelStem.END) { // CraftBukkit - work in alternate worlds
|
||||
blockposition1 = TheEndGatewayBlockEntity.findOrCreateValidTeleportPos(world, pos);
|
||||
blockposition1 = blockposition1.above(10);
|
||||
TheEndGatewayBlockEntity.LOGGER.debug("Creating portal at {}", blockposition1);
|
||||
- TheEndGatewayBlockEntity.spawnGatewayPortal(world, blockposition1, EndGatewayConfiguration.knownExit(pos, false));
|
||||
+ TheEndGatewayBlockEntity.spawnGatewayPortal(world, blockposition1, EndGatewayConfiguration.knownExit(pos, false), entity); // Paper
|
||||
this.setExitPosition(blockposition1, this.exactTeleport);
|
||||
}
|
||||
|
||||
- if (this.exitPortal != null) {
|
||||
+ if (this.exitPortal != null && this.getLevel().getBlockEntity(this.exitPortal) instanceof TheEndGatewayBlockEntity) { // Paper - confirm gateway was created
|
||||
blockposition1 = this.exactTeleport ? this.exitPortal : TheEndGatewayBlockEntity.findExitPosition(world, this.exitPortal);
|
||||
return blockposition1.getBottomCenter();
|
||||
} else {
|
||||
@@ -267,8 +273,12 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity {
|
||||
return blockposition2;
|
||||
}
|
||||
|
||||
- private static void spawnGatewayPortal(ServerLevel world, BlockPos pos, EndGatewayConfiguration config) {
|
||||
- Feature.END_GATEWAY.place(config, world, world.getChunkSource().getGenerator(), RandomSource.create(), pos);
|
||||
+ // Paper start
|
||||
+ private static void spawnGatewayPortal(ServerLevel world, BlockPos pos, EndGatewayConfiguration config, @Nullable net.minecraft.world.entity.Entity entity) {
|
||||
+ if (world.ensureCanWrite(pos)) {
|
||||
+ ((net.minecraft.world.level.levelgen.feature.EndGatewayFeature)Feature.END_GATEWAY).place(new net.minecraft.world.level.levelgen.feature.FeaturePlaceContext<>(java.util.Optional.empty(), world, world.getChunkSource().getGenerator(), RandomSource.create(), pos, config), io.papermc.paper.event.world.AsyncPortalCreateEvent.CreateReason.END_GATEWAY_PAIR, entity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
index 18a1b4325cac81b040596071dab99ef9bf6f3142..6cbcc11de6901e4ef716f65407bec6a31e790265 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
@@ -406,8 +406,8 @@ public class EndDragonFight {
|
||||
if (dragon.getUUID().equals(this.dragonUUID)) {
|
||||
this.dragonEvent.setProgress(0.0F);
|
||||
this.dragonEvent.setVisible(false);
|
||||
- this.spawnExitPortal(true);
|
||||
- this.spawnNewGateway();
|
||||
+ this.spawnExitPortal(true, dragon); // Paper
|
||||
+ this.spawnNewGateway(dragon); // Paper
|
||||
// Paper start - Add DragonEggFormEvent
|
||||
BlockPos eggPosition = this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(this.origin));
|
||||
org.bukkit.craftbukkit.block.CraftBlockState eggState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(this.level, eggPosition);
|
||||
@@ -442,7 +442,7 @@ public class EndDragonFight {
|
||||
// Paper start - More DragonBattle API
|
||||
public boolean spawnNewGatewayIfPossible() {
|
||||
if (!this.gateways.isEmpty()) {
|
||||
- this.spawnNewGateway();
|
||||
+ this.spawnNewGateway(null); // Paper
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -457,26 +457,39 @@ public class EndDragonFight {
|
||||
}
|
||||
// Paper end - More DragonBattle API
|
||||
|
||||
- private void spawnNewGateway() {
|
||||
+ private void spawnNewGateway(@Nullable EnderDragon entityEnderDragon) { // Paper
|
||||
if (!this.gateways.isEmpty()) {
|
||||
int i = (Integer) this.gateways.remove(this.gateways.size() - 1);
|
||||
int j = Mth.floor(96.0D * Math.cos(2.0D * (-3.141592653589793D + 0.15707963267948966D * (double) i)));
|
||||
int k = Mth.floor(96.0D * Math.sin(2.0D * (-3.141592653589793D + 0.15707963267948966D * (double) i)));
|
||||
|
||||
- this.spawnNewGateway(new BlockPos(j, 75, k));
|
||||
+ this.spawnNewGateway(new BlockPos(j, 75, k), entityEnderDragon);
|
||||
}
|
||||
}
|
||||
|
||||
- public void spawnNewGateway(BlockPos pos) {
|
||||
+ public void spawnNewGateway(BlockPos pos, @Nullable EnderDragon entityEnderDragon) { // Paper
|
||||
this.level.levelEvent(3000, pos, 0);
|
||||
this.level.registryAccess().registry(Registries.CONFIGURED_FEATURE).flatMap((iregistry) -> {
|
||||
return iregistry.getHolder(EndFeatures.END_GATEWAY_DELAYED);
|
||||
}).ifPresent((holder_c) -> {
|
||||
- ((ConfiguredFeature) holder_c.value()).place(this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), pos);
|
||||
+ // Paper start
|
||||
+ if (holder_c.value().feature() instanceof net.minecraft.world.level.levelgen.feature.EndGatewayFeature endGatewayFeature && holder_c.value().config() instanceof net.minecraft.world.level.levelgen.feature.configurations.EndGatewayConfiguration endGatewayConfiguration) {
|
||||
+ if (this.level.ensureCanWrite(pos)) {
|
||||
+ endGatewayFeature.place(new net.minecraft.world.level.levelgen.feature.FeaturePlaceContext<>(java.util.Optional.empty(), this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), pos, endGatewayConfiguration), io.papermc.paper.event.world.AsyncPortalCreateEvent.CreateReason.END_GATEWAY_DRAGON_DEFEAT, entityEnderDragon); // Paper
|
||||
+ }
|
||||
+ } else {
|
||||
+ // Paper end
|
||||
+ holder_c.value().place(this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), pos);
|
||||
+ } // Paper
|
||||
});
|
||||
}
|
||||
|
||||
public void spawnExitPortal(boolean previouslyKilled) {
|
||||
+ // Paper start
|
||||
+ this.spawnExitPortal(previouslyKilled, null);
|
||||
+ }
|
||||
+ public void spawnExitPortal(boolean previouslyKilled, @Nullable Entity entity) {
|
||||
+ // Paper end
|
||||
EndPodiumFeature worldgenendtrophy = new EndPodiumFeature(previouslyKilled);
|
||||
|
||||
if (this.portalLocation == null) {
|
||||
@@ -490,7 +503,7 @@ public class EndDragonFight {
|
||||
this.portalLocation = this.portalLocation.atY(this.level.getMinBuildHeight() + 1);
|
||||
}
|
||||
// Paper end - Prevent "softlocked" exit portal generation
|
||||
- if (worldgenendtrophy.place(FeatureConfiguration.NONE, this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), this.portalLocation)) {
|
||||
+ if (worldgenendtrophy.place(FeatureConfiguration.NONE, this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), this.portalLocation, entity)) { // Paper - add entity context
|
||||
int i = Mth.positiveCeilDiv(4, 16);
|
||||
|
||||
this.level.getChunkSource().chunkMap.waitForLightBeforeSending(new ChunkPos(this.portalLocation), i);
|
||||
@@ -541,7 +554,7 @@ public class EndDragonFight {
|
||||
this.respawnStage = null;
|
||||
this.respawnTime = 0;
|
||||
this.resetSpikeCrystals();
|
||||
- this.spawnExitPortal(true);
|
||||
+ this.spawnExitPortal(true, enderCrystal); // Paper
|
||||
} else {
|
||||
this.updateCrystalCount();
|
||||
Entity entity = this.level.getEntity(this.dragonUUID);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/EndGatewayFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/EndGatewayFeature.java
|
||||
index b76facd940f911aa069e919d7db1ca3a7b849608..da0361bd3c9521dc4538b02ae5a32ca818062fb1 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/EndGatewayFeature.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/EndGatewayFeature.java
|
||||
@@ -14,8 +14,13 @@ public class EndGatewayFeature extends Feature<EndGatewayConfiguration> {
|
||||
|
||||
@Override
|
||||
public boolean place(FeaturePlaceContext<EndGatewayConfiguration> context) {
|
||||
+ // Paper start
|
||||
+ return this.place(context, io.papermc.paper.event.world.AsyncPortalCreateEvent.CreateReason.UNKNOWN, null);
|
||||
+ }
|
||||
+ public boolean place(FeaturePlaceContext<EndGatewayConfiguration> context, io.papermc.paper.event.world.AsyncPortalCreateEvent.CreateReason createReason, @javax.annotation.Nullable net.minecraft.world.entity.Entity entity) {
|
||||
+ // Paper end
|
||||
BlockPos blockPos = context.origin();
|
||||
- WorldGenLevel worldGenLevel = context.level();
|
||||
+ org.bukkit.craftbukkit.util.BlockStateListPopulator worldGenLevel = new org.bukkit.craftbukkit.util.BlockStateListPopulator(context.level()); // Paper
|
||||
EndGatewayConfiguration endGatewayConfiguration = context.config();
|
||||
|
||||
for (BlockPos blockPos2 : BlockPos.betweenClosed(blockPos.offset(-1, -2, -1), blockPos.offset(1, 2, 1))) {
|
||||
@@ -26,7 +31,7 @@ public class EndGatewayFeature extends Feature<EndGatewayConfiguration> {
|
||||
if (bl && bl2 && bl3) {
|
||||
BlockPos blockPos3 = blockPos2.immutable();
|
||||
this.setBlock(worldGenLevel, blockPos3, Blocks.END_GATEWAY.defaultBlockState());
|
||||
- endGatewayConfiguration.getExit().ifPresent(pos -> {
|
||||
+ endGatewayConfiguration.getExit().ifPresent(pos -> { // Paper - moved to below after tile entity has been created
|
||||
if (worldGenLevel.getBlockEntity(blockPos3) instanceof TheEndGatewayBlockEntity theEndGatewayBlockEntity) {
|
||||
theEndGatewayBlockEntity.setExitPosition(pos, endGatewayConfiguration.isExitExact());
|
||||
}
|
||||
@@ -42,6 +47,13 @@ public class EndGatewayFeature extends Feature<EndGatewayConfiguration> {
|
||||
}
|
||||
}
|
||||
|
||||
- return true;
|
||||
+ // Paper start
|
||||
+ worldGenLevel.refreshTiles(); // Update TheEndGatewayBlockEntity
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPortalCreateEvent(worldGenLevel, context.level(), entity, createReason)) {
|
||||
+ worldGenLevel.updateList();
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java
|
||||
index 0bc659a8427b89b5e3211220c55b52eec6a20494..947b443103fee1543075393918220868b0b4c5b3 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/EndPlatformFeature.java
|
||||
@@ -60,11 +60,7 @@ public class EndPlatformFeature extends Feature<NoneFeatureConfiguration> {
|
||||
return;
|
||||
}
|
||||
|
||||
- org.bukkit.World bworld = worldaccess.getLevel().getWorld();
|
||||
- PortalCreateEvent portalEvent = new PortalCreateEvent((List<BlockState>) (List) blockList.getList(), bworld, entity.getBukkitEntity(), org.bukkit.event.world.PortalCreateEvent.CreateReason.END_PLATFORM);
|
||||
-
|
||||
- worldaccess.getLevel().getCraftServer().getPluginManager().callEvent(portalEvent);
|
||||
- if (!portalEvent.isCancelled()) {
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPortalCreateEvent(blockList, worldaccess, entity, io.papermc.paper.event.world.AsyncPortalCreateEvent.CreateReason.END_PLATFORM)) {
|
||||
blockList.updateList();
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/EndPodiumFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/EndPodiumFeature.java
|
||||
index 9d3b765c764a6c5711f264bb74d04de2b1cf1232..9463ce6262b14940e1b4c422ce5e535f88d308ea 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/EndPodiumFeature.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/EndPodiumFeature.java
|
||||
@@ -27,7 +27,7 @@ public class EndPodiumFeature extends Feature<NoneFeatureConfiguration> {
|
||||
@Override
|
||||
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
|
||||
BlockPos blockPos = context.origin();
|
||||
- WorldGenLevel worldGenLevel = context.level();
|
||||
+ org.bukkit.craftbukkit.util.BlockStateListPopulator worldGenLevel = new org.bukkit.craftbukkit.util.BlockStateListPopulator(context.level()); // Paper
|
||||
|
||||
for (BlockPos blockPos2 : BlockPos.betweenClosed(
|
||||
new BlockPos(blockPos.getX() - 4, blockPos.getY() - 1, blockPos.getZ() - 4),
|
||||
@@ -63,6 +63,13 @@ public class EndPodiumFeature extends Feature<NoneFeatureConfiguration> {
|
||||
this.setBlock(worldGenLevel, blockPos3.relative(direction), Blocks.WALL_TORCH.defaultBlockState().setValue(WallTorchBlock.FACING, direction));
|
||||
}
|
||||
|
||||
- return true;
|
||||
+ // Paper start
|
||||
+ worldGenLevel.refreshTiles();
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPortalCreateEvent(worldGenLevel, context.level(), context.entitySource, this.active ? io.papermc.paper.event.world.AsyncPortalCreateEvent.CreateReason.ACTIVE_END_PORTAL : io.papermc.paper.event.world.AsyncPortalCreateEvent.CreateReason.END_PORTAL)) {
|
||||
+ worldGenLevel.updateList();
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/Feature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/Feature.java
|
||||
index d69bac79e99639abf5598edf7b865d7b3444cca1..5412574561bed4db6e86537a5c3f238a8150478c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/Feature.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/Feature.java
|
||||
@@ -187,7 +187,12 @@ public abstract class Feature<FC extends FeatureConfiguration> {
|
||||
public abstract boolean place(FeaturePlaceContext<FC> context);
|
||||
|
||||
public boolean place(FC config, WorldGenLevel world, ChunkGenerator chunkGenerator, RandomSource random, BlockPos pos) {
|
||||
- return world.ensureCanWrite(pos) && this.place(new FeaturePlaceContext<>(Optional.empty(), world, chunkGenerator, random, pos, config));
|
||||
+ // Paper start - add entity context
|
||||
+ return this.place(config, world, chunkGenerator, random, pos, null);
|
||||
+ }
|
||||
+ public boolean place(FC config, WorldGenLevel world, ChunkGenerator chunkGenerator, RandomSource random, BlockPos pos, @org.jetbrains.annotations.Nullable net.minecraft.world.entity.Entity entitySource) {
|
||||
+ return world.ensureCanWrite(pos) && this.place(new FeaturePlaceContext<>(Optional.empty(), world, chunkGenerator, random, pos, config, entitySource));
|
||||
+ // Paper end - add entity context
|
||||
}
|
||||
|
||||
protected static boolean isStone(BlockState state) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/FeaturePlaceContext.java b/src/main/java/net/minecraft/world/level/levelgen/feature/FeaturePlaceContext.java
|
||||
index c2f54b2c4f26ff3289ad226ccadf01a9f4e31c16..d0de7f93572d8c1e534303c7426cd5981ca2c1b7 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/FeaturePlaceContext.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/FeaturePlaceContext.java
|
||||
@@ -14,10 +14,17 @@ public class FeaturePlaceContext<FC extends FeatureConfiguration> {
|
||||
private final RandomSource random;
|
||||
private final BlockPos origin;
|
||||
private final FC config;
|
||||
+ public final @org.jetbrains.annotations.Nullable net.minecraft.world.entity.Entity entitySource; // Paper - add entity context
|
||||
|
||||
public FeaturePlaceContext(
|
||||
Optional<ConfiguredFeature<?, ?>> feature, WorldGenLevel world, ChunkGenerator generator, RandomSource random, BlockPos origin, FC config
|
||||
) {
|
||||
+ // Paper start - add entity context
|
||||
+ this(feature, world, generator, random, origin, config, null);
|
||||
+ }
|
||||
+ public FeaturePlaceContext(Optional<ConfiguredFeature<?, ?>> feature, WorldGenLevel world, ChunkGenerator generator, RandomSource random, BlockPos origin, FC config, @org.jetbrains.annotations.Nullable net.minecraft.world.entity.Entity entitySource) {
|
||||
+ this.entitySource = entitySource;
|
||||
+ // Paper end - add entity context
|
||||
this.topFeature = feature;
|
||||
this.level = world;
|
||||
this.chunkGenerator = generator;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/boss/CraftDragonBattle.java b/src/main/java/org/bukkit/craftbukkit/boss/CraftDragonBattle.java
|
||||
index 6bfabb38b51115beb2a65a165f235347838b6006..ce9a88d7355d8a928928a47469965dbe5c70c899 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/boss/CraftDragonBattle.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/boss/CraftDragonBattle.java
|
||||
@@ -150,7 +150,7 @@ public class CraftDragonBattle implements DragonBattle {
|
||||
|
||||
@Override
|
||||
public void spawnNewGateway(final io.papermc.paper.math.Position position) {
|
||||
- this.handle.spawnNewGateway(io.papermc.paper.util.MCUtil.toBlockPos(position));
|
||||
+ this.handle.spawnNewGateway(io.papermc.paper.util.MCUtil.toBlockPos(position), null); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 9c7cd9387f90d061aec76f7f0451a1da8b42ea3d..a3854711776bf737e209d20b4d280185f282c7dd 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -2223,4 +2223,33 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
// Paper end - add EntityFertilizeEggEvent
|
||||
+
|
||||
+ // Paper start - add AsyncPortalCreateEvent
|
||||
+ public static boolean callPortalCreateEvent(final org.bukkit.craftbukkit.util.BlockStateListPopulator blockList, final net.minecraft.world.level.ServerLevelAccessor world, @Nullable final Entity entity, final io.papermc.paper.event.world.AsyncPortalCreateEvent.CreateReason reason) {
|
||||
+ final org.bukkit.event.world.PortalCreateEvent.CreateReason legacyReason = switch (reason) {
|
||||
+ case FIRE -> org.bukkit.event.world.PortalCreateEvent.CreateReason.FIRE;
|
||||
+ case NETHER_PAIR -> org.bukkit.event.world.PortalCreateEvent.CreateReason.NETHER_PAIR;
|
||||
+ case END_PLATFORM -> org.bukkit.event.world.PortalCreateEvent.CreateReason.END_PLATFORM;
|
||||
+ default -> null;
|
||||
+ };
|
||||
+ boolean cancelled = false;
|
||||
+ if (Bukkit.isPrimaryThread() && legacyReason != null) {
|
||||
+ cancelled = !new org.bukkit.event.world.PortalCreateEvent((List<BlockState>) (List) blockList.getList(), world.getLevel().getWorld(), entity.getBukkitEntity(), legacyReason).callEvent();
|
||||
+ }
|
||||
+ final org.bukkit.RegionAccessor regionAccessor;
|
||||
+ if (world instanceof ServerLevel serverLevel) {
|
||||
+ regionAccessor = serverLevel.getWorld();
|
||||
+ } else if (world instanceof final net.minecraft.server.level.WorldGenRegion worldGenRegion) {
|
||||
+ regionAccessor = new org.bukkit.craftbukkit.generator.CraftLimitedRegion(worldGenRegion, worldGenRegion.getCenter());
|
||||
+ } else {
|
||||
+ return true;
|
||||
+ }
|
||||
+ final boolean result = new io.papermc.paper.event.world.AsyncPortalCreateEvent(!Bukkit.isPrimaryThread(), regionAccessor, (List<BlockState>) (List) blockList.getList(), entity.getBukkitEntity(), reason).callEvent();
|
||||
+ if (regionAccessor instanceof final org.bukkit.craftbukkit.generator.CraftLimitedRegion craftLimitedRegion) {
|
||||
+ craftLimitedRegion.saveEntities();
|
||||
+ craftLimitedRegion.breakLink();
|
||||
+ }
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end - add AsyncPortalCreateEvent
|
||||
}
|
Loading…
Reference in a new issue