Dragon respawning fix

This commit is contained in:
paulevsGitch 2021-05-03 22:53:27 +03:00
parent 60175b2425
commit 53268ec8c8
5 changed files with 98 additions and 14 deletions

View file

@ -0,0 +1,87 @@
package ru.betterend.mixin.common;
import java.util.List;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.google.common.collect.Lists;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.boss.enderdragon.EndCrystal;
import net.minecraft.world.level.block.state.pattern.BlockPattern;
import net.minecraft.world.level.dimension.end.DragonRespawnAnimation;
import net.minecraft.world.level.dimension.end.EndDragonFight;
import net.minecraft.world.phys.AABB;
import ru.betterend.util.BlocksHelper;
import ru.betterend.world.generator.GeneratorOptions;
@Mixin(EndDragonFight.class)
public class EndDragonFightMixin {
@Shadow
private DragonRespawnAnimation respawnStage;
@Shadow
private boolean dragonKilled;
@Shadow
private BlockPos portalLocation;
@Final
@Shadow
private static Logger LOGGER;
@Final
@Shadow
private ServerLevel level;
@Shadow
private BlockPattern.BlockPatternMatch findExitPortal() {
return null;
}
@Shadow
private void spawnExitPortal(boolean bl) {}
@Shadow
private void respawnDragon(List<EndCrystal> list) {}
@Inject(method = "tryRespawn", at = @At("HEAD"), cancellable = true)
private void be_tryRespawnDragon(CallbackInfo info) {
if (GeneratorOptions.replacePortal() && GeneratorOptions.hasDragonFights() && this.dragonKilled && this.respawnStage == null) {
BlockPos blockPos = this.portalLocation;
if (blockPos == null) {
LOGGER.debug("Tried to respawn, but need to find the portal first.");
BlockPattern.BlockPatternMatch blockPatternMatch = this.findExitPortal();
if (blockPatternMatch == null) {
LOGGER.debug("Couldn't find a portal, so we made one.");
this.spawnExitPortal(true);
}
else {
LOGGER.debug("Found the exit portal & temporarily using it.");
}
blockPos = this.portalLocation;
}
List<EndCrystal> crystals = Lists.newArrayList();
BlockPos center = blockPos.above(2);
for (Direction dir : BlocksHelper.HORIZONTAL) {
List<EndCrystal> crystalList = this.level.getEntitiesOfClass(EndCrystal.class, new AABB(center.relative(dir, 3)));
if (crystalList.isEmpty()) {
info.cancel();
return;
}
crystals.addAll(crystalList);
}
LOGGER.debug("Found all crystals, respawning dragon.");
this.respawnDragon(crystals);
info.cancel();
}
}
}

View file

@ -14,6 +14,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.levelgen.Heightmap.Types;
import net.minecraft.world.level.levelgen.feature.EndPodiumFeature;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
@ -40,7 +41,7 @@ public class EndPodiumFeatureMixin {
blockPos = be_updatePos(blockPos, world);
StructureTemplate structure = StructureHelper.readStructure(BetterEnd.makeID(active ? "portal/end_portal_active" : "portal/end_portal_inactive"));
BlockPos size = structure.getSize();
blockPos = blockPos.offset(-(size.getX() >> 1), -3, -(size.getZ() >> 1));
blockPos = blockPos.offset(-(size.getX() >> 1), -1, -(size.getZ() >> 1));
structure.placeInWorldChunk(world, blockPos, new StructurePlaceSettings(), random);
info.setReturnValue(true);
info.cancel();
@ -56,7 +57,7 @@ public class EndPodiumFeatureMixin {
if (GeneratorOptions.useNewGenerator()) {
BlockPos pos = GeneratorOptions.getPortalPos();
if (pos.equals(BlockPos.ZERO)) {
int y = world.getChunk(blockPos).getHeight(Types.WORLD_SURFACE, blockPos.getX(), blockPos.getZ());
int y = world.getChunk(0, 0, ChunkStatus.FULL).getHeight(Types.WORLD_SURFACE, blockPos.getX(), blockPos.getZ());
if (y < 1) {
y = 65;
}