net/minecraft/world/level/dimension/end
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
--- a/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
+++ b/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
@@ -70,8 +_,9 @@
|
||||
private static final int GATEWAY_DISTANCE = 96;
|
||||
public static final int DRAGON_SPAWN_Y = 128;
|
||||
private final Predicate<Entity> validPlayer;
|
||||
+ private static final Component DEFAULT_BOSS_EVENT_NAME = Component.translatable("entity.minecraft.ender_dragon"); // Paper - ensure reset EnderDragon boss event name
|
||||
public final ServerBossEvent dragonEvent = (ServerBossEvent)new ServerBossEvent(
|
||||
- Component.translatable("entity.minecraft.ender_dragon"), BossEvent.BossBarColor.PINK, BossEvent.BossBarOverlay.PROGRESS
|
||||
+ DEFAULT_BOSS_EVENT_NAME, BossEvent.BossBarColor.PINK, BossEvent.BossBarOverlay.PROGRESS // Paper
|
||||
)
|
||||
.setPlayBossMusic(true)
|
||||
.setCreateWorldFog(true);
|
||||
@@ -112,7 +_,12 @@
|
||||
if (data.isRespawning) {
|
||||
this.respawnStage = DragonRespawnAnimation.START;
|
||||
}
|
||||
-
|
||||
+ // Paper start - Add config to disable ender dragon legacy check
|
||||
+ if (data == EndDragonFight.Data.DEFAULT && !level.paperConfig().entities.spawning.scanForLegacyEnderDragon) {
|
||||
+ this.needsStateScanning = false;
|
||||
+ this.dragonKilled = true;
|
||||
+ }
|
||||
+ // Paper end - Add config to disable ender dragon legacy check
|
||||
this.portalLocation = data.exitPortalLocation.orElse(null);
|
||||
this.gateways.addAll(data.gateways.orElseGet(() -> {
|
||||
ObjectArrayList<Integer> list = new ObjectArrayList<>(ContiguousSet.create(Range.closedOpen(0, 20), DiscreteDomain.integers()));
|
||||
@@ -209,9 +_,9 @@
|
||||
this.dragonUUID = enderDragon.getUUID();
|
||||
LOGGER.info("Found that there's a dragon still alive ({})", enderDragon);
|
||||
this.dragonKilled = false;
|
||||
- if (!hasActiveExitPortal) {
|
||||
+ if (!hasActiveExitPortal && this.level.paperConfig().entities.behavior.shouldRemoveDragon) { // Paper - Toggle for removing existing dragon
|
||||
LOGGER.info("But we didn't have a portal, let's remove it.");
|
||||
- enderDragon.discard();
|
||||
+ enderDragon.discard(null); // CraftBukkit - add Bukkit remove cause
|
||||
this.dragonUUID = null;
|
||||
}
|
||||
}
|
||||
@@ -366,12 +_,22 @@
|
||||
this.dragonEvent.setVisible(false);
|
||||
this.spawnExitPortal(true);
|
||||
this.spawnNewGateway();
|
||||
- if (!this.previouslyKilled) {
|
||||
- this.level
|
||||
- .setBlockAndUpdate(
|
||||
- this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(this.origin)),
|
||||
- Blocks.DRAGON_EGG.defaultBlockState()
|
||||
- );
|
||||
+ // 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);
|
||||
+ eggState.setData(Blocks.DRAGON_EGG.defaultBlockState());
|
||||
+ io.papermc.paper.event.block.DragonEggFormEvent eggEvent = new io.papermc.paper.event.block.DragonEggFormEvent(org.bukkit.craftbukkit.block.CraftBlock.at(this.level, eggPosition), eggState,
|
||||
+ new org.bukkit.craftbukkit.boss.CraftDragonBattle(this));
|
||||
+ // Paper end - Add DragonEggFormEvent
|
||||
+ if (this.level.paperConfig().entities.behavior.enderDragonsDeathAlwaysPlacesDragonEgg || !this.previouslyKilled) { // Paper - Add toggle for always placing the dragon egg
|
||||
+ // Paper start - Add DragonEggFormEvent
|
||||
+ // this.level.setBlockAndUpdate(this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.getLocation(this.origin)), Blocks.DRAGON_EGG.defaultBlockState());
|
||||
+ } else {
|
||||
+ eggEvent.setCancelled(true);
|
||||
+ }
|
||||
+ if (eggEvent.callEvent()) {
|
||||
+ eggEvent.getNewState().update(true);
|
||||
+ // Paper end - Add DragonEggFormEvent
|
||||
}
|
||||
|
||||
this.previouslyKilled = true;
|
||||
@@ -385,6 +_,24 @@
|
||||
this.gateways.clear();
|
||||
}
|
||||
|
||||
+ // Paper start - More DragonBattle API
|
||||
+ public boolean spawnNewGatewayIfPossible() {
|
||||
+ if (!this.gateways.isEmpty()) {
|
||||
+ this.spawnNewGateway();
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ public List<EndCrystal> getSpikeCrystals() {
|
||||
+ final List<EndCrystal> endCrystals = new java.util.ArrayList<>();
|
||||
+ for (final SpikeFeature.EndSpike spike : SpikeFeature.getSpikesForLevel(this.level)) {
|
||||
+ endCrystals.addAll(this.level.getEntitiesOfClass(EndCrystal.class, spike.getTopBoundingBox()));
|
||||
+ }
|
||||
+ return endCrystals;
|
||||
+ }
|
||||
+ // Paper end - More DragonBattle API
|
||||
+
|
||||
private void spawnNewGateway() {
|
||||
if (!this.gateways.isEmpty()) {
|
||||
int i = this.gateways.remove(this.gateways.size() - 1);
|
||||
@@ -413,6 +_,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Prevent "softlocked" exit portal generation
|
||||
+ if (this.portalLocation.getY() <= this.level.getMinY()) {
|
||||
+ this.portalLocation = this.portalLocation.atY(this.level.getMinY() + 1);
|
||||
+ }
|
||||
+ // Paper end - Prevent "softlocked" exit portal generation
|
||||
if (endPodiumFeature.place(
|
||||
FeatureConfiguration.NONE, this.level, this.level.getChunkSource().getGenerator(), RandomSource.create(), this.portalLocation
|
||||
)) {
|
||||
@@ -432,6 +_,7 @@
|
||||
enderDragon.moveTo(this.origin.getX(), 128 + this.origin.getY(), this.origin.getZ(), this.level.random.nextFloat() * 360.0F, 0.0F);
|
||||
this.level.addFreshEntity(enderDragon);
|
||||
this.dragonUUID = enderDragon.getUUID();
|
||||
+ this.resetSpikeCrystals(); // Paper - Reset ender crystals on dragon spawn
|
||||
}
|
||||
|
||||
return enderDragon;
|
||||
@@ -443,6 +_,10 @@
|
||||
this.ticksSinceDragonSeen = 0;
|
||||
if (dragon.hasCustomName()) {
|
||||
this.dragonEvent.setName(dragon.getDisplayName());
|
||||
+ // Paper start - ensure reset EnderDragon boss event name
|
||||
+ } else {
|
||||
+ this.dragonEvent.setName(DEFAULT_BOSS_EVENT_NAME);
|
||||
+ // Paper end - ensure reset EnderDragon boss event name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -470,7 +_,13 @@
|
||||
return this.previouslyKilled;
|
||||
}
|
||||
|
||||
- public void tryRespawn() {
|
||||
+ public boolean tryRespawn() { // CraftBukkit - return boolean
|
||||
+ // Paper start - Perf: Do crystal-portal proximity check before entity lookup
|
||||
+ return this.tryRespawn(null);
|
||||
+ }
|
||||
+
|
||||
+ public boolean tryRespawn(@Nullable BlockPos placedEndCrystalPos) { // placedEndCrystalPos is null if the tryRespawn() call was not caused by a placed end crystal
|
||||
+ // Paper end - Perf: Do crystal-portal proximity check before entity lookup
|
||||
if (this.dragonKilled && this.respawnStage == null) {
|
||||
BlockPos blockPos = this.portalLocation;
|
||||
if (blockPos == null) {
|
||||
@@ -485,6 +_,22 @@
|
||||
|
||||
blockPos = this.portalLocation;
|
||||
}
|
||||
+ // Paper start - Perf: Do crystal-portal proximity check before entity lookup
|
||||
+ if (placedEndCrystalPos != null) {
|
||||
+ // The end crystal must be 0 or 1 higher than the portal origin
|
||||
+ int dy = placedEndCrystalPos.getY() - blockPos.getY();
|
||||
+ if (dy != 0 && dy != 1) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // The end crystal must be within a distance of 1 in one planar direction, and 3 in the other
|
||||
+ int dx = placedEndCrystalPos.getX() - blockPos.getX();
|
||||
+ int dz = placedEndCrystalPos.getZ() - blockPos.getZ();
|
||||
+ if (!((dx >= -1 && dx <= 1 && dz >= -3 && dz <= 3) || (dx >= -3 && dx <= 3 && dz >= -1 && dz <= 1))) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Perf: Do crystal-portal proximity check before entity lookup
|
||||
+
|
||||
|
||||
List<EndCrystal> list = Lists.newArrayList();
|
||||
BlockPos blockPos1 = blockPos.above(1);
|
||||
@@ -492,18 +_,19 @@
|
||||
for (Direction direction : Direction.Plane.HORIZONTAL) {
|
||||
List<EndCrystal> entitiesOfClass = this.level.getEntitiesOfClass(EndCrystal.class, new AABB(blockPos1.relative(direction, 2)));
|
||||
if (entitiesOfClass.isEmpty()) {
|
||||
- return;
|
||||
+ return false; // CraftBukkit - return value
|
||||
}
|
||||
|
||||
list.addAll(entitiesOfClass);
|
||||
}
|
||||
|
||||
LOGGER.debug("Found all crystals, respawning dragon.");
|
||||
- this.respawnDragon(list);
|
||||
+ return this.respawnDragon(list); // CraftBukkit - return value
|
||||
}
|
||||
+ return false; // CraftBukkit - return value
|
||||
}
|
||||
|
||||
- public void respawnDragon(List<EndCrystal> crystals) {
|
||||
+ public boolean respawnDragon(List<EndCrystal> crystals) { // CraftBukkit - return boolean
|
||||
if (this.dragonKilled && this.respawnStage == null) {
|
||||
for (BlockPattern.BlockPatternMatch blockPatternMatch = this.findExitPortal(); blockPatternMatch != null; blockPatternMatch = this.findExitPortal()) {
|
||||
for (int i = 0; i < this.exitPortalPattern.getWidth(); i++) {
|
||||
@@ -522,7 +_,9 @@
|
||||
this.respawnTime = 0;
|
||||
this.spawnExitPortal(false);
|
||||
this.respawnCrystals = crystals;
|
||||
+ return true; // CraftBukkit - return value
|
||||
}
|
||||
+ return false; // CraftBukkit - return value
|
||||
}
|
||||
|
||||
public void resetSpikeCrystals() {
|
||||
Reference in New Issue
Block a user