Added tpnext command

This commit is contained in:
Frank 2022-06-25 20:34:44 +02:00
parent dc6e0ae5e5
commit 06a677169e
2 changed files with 125 additions and 4 deletions

View file

@ -1,21 +1,37 @@
package org.betterx.betterend.commands; package org.betterx.betterend.commands;
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
import org.betterx.bclib.api.v2.poi.BCLPoiType; import org.betterx.bclib.api.v2.poi.BCLPoiType;
import org.betterx.bclib.util.BlocksHelper; import org.betterx.bclib.util.BlocksHelper;
import org.betterx.betterend.registry.EndBiomes;
import org.betterx.betterend.registry.EndPoiTypes; import org.betterx.betterend.registry.EndPoiTypes;
import org.betterx.betterend.world.biome.EndBiome;
import com.mojang.brigadier.Command; import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.datafixers.util.Either;
import com.mojang.datafixers.util.Pair;
import com.mojang.math.Vector3d;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands; import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.ResourceOrTagLocationArgument;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.commands.LocateCommand;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -23,9 +39,7 @@ import net.minecraft.world.phys.Vec3;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import java.util.HashMap; import java.util.*;
import java.util.Map;
import java.util.Optional;
public class CommandRegistry { public class CommandRegistry {
public static void register() { public static void register() {
@ -44,6 +58,10 @@ public class CommandRegistry {
.requires(source -> source.hasPermission(Commands.LEVEL_OWNERS)) .requires(source -> source.hasPermission(Commands.LEVEL_OWNERS))
.executes(ctx -> find_poi(ctx, EndPoiTypes.ETERNAL_PORTAL_INACTIVE)) .executes(ctx -> find_poi(ctx, EndPoiTypes.ETERNAL_PORTAL_INACTIVE))
) )
.then(Commands.literal("tpnext")
.requires(source -> source.hasPermission(Commands.LEVEL_OWNERS))
.executes(ctx -> teleportToNextBiome(ctx))
)
); );
} }
@ -92,5 +110,103 @@ public class CommandRegistry {
} }
return Command.SINGLE_SUCCESS; return Command.SINGLE_SUCCESS;
} }
private static int biomeIndex = 0;
private static final int MAX_SEARCH_RADIUS = 6400 * 2;
private static final int SAMPLE_RESOLUTION_HORIZONTAL = 32;
private static final int SAMPLE_RESOLUTION_VERTICAL = 64;
private static final DynamicCommandExceptionType ERROR_BIOME_NOT_FOUND = new DynamicCommandExceptionType(
(object) -> {
return Component.literal("The next biome (" + object + ") was not found.");
});
private static int teleportToNextBiome(CommandContext<CommandSourceStack> ctx) throws CommandSyntaxException {
final CommandSourceStack source = ctx.getSource();
List<EndBiome> biomes = EndBiomes.ALL_BE_BIOMES;
if (biomeIndex < 0 || biomeIndex >= biomes.size()) {
source.sendFailure(Component.literal("Failed to find the next Biome...")
.setStyle(Style.EMPTY.withColor(ChatFormatting.RED)));
return 0;
}
final BCLBiome biome = biomes.get(biomeIndex);
source.sendSuccess(Component.literal("Locating Biome " + biome)
.setStyle(Style.EMPTY.withColor(ChatFormatting.DARK_GREEN)), false);
biomeIndex = (biomeIndex + 1) % biomes.size();
final BlockPos currentPosition = new BlockPos(source.getPosition());
final BlockPos biomePosition = source.getLevel()
.findClosestBiome3d(
b -> b.unwrapKey().orElseThrow().location().equals(biome.getID()),
currentPosition,
MAX_SEARCH_RADIUS,
SAMPLE_RESOLUTION_HORIZONTAL,
SAMPLE_RESOLUTION_VERTICAL
)
.getFirst();
final String biomeName = biome.toString();
if (biomePosition == null) {
throw ERROR_BIOME_NOT_FOUND.create(biomeName);
} else {
final ServerPlayer player = source.getPlayerOrException();
BlockState state;
BlockPos target;
double yPos = source.getPosition().y();
boolean didWrap = false;
do {
target = new BlockPos(biomePosition.getX(), yPos, biomePosition.getZ());
state = player.level.getBlockState(target);
yPos--;
if (yPos <= player.level.getMinBuildHeight() + 1) {
if (didWrap) break;
yPos = 127;
didWrap = true;
}
} while (!state.isAir() && yPos > player.level.getMinBuildHeight() && yPos < player.level.getMaxBuildHeight());
Vector3d targetPlayerPos = new Vector3d(target.getX() + 0.5, target.getY() - 1, target.getZ() + 0.5);
player.connection.teleport(
targetPlayerPos.x,
targetPlayerPos.y,
targetPlayerPos.z,
0,
0,
Collections.EMPTY_SET
);
ResourceOrTagLocationArgument.Result result = new ResourceOrTagLocationArgument.Result() {
@Override
public Either<ResourceKey, TagKey> unwrap() {
return Either.left(BiomeAPI.getBiomeKey(biome.getBiome()));
}
@Override
public Optional<ResourceOrTagLocationArgument.Result> cast(ResourceKey resourceKey) {
return Optional.empty();
}
@Override
public String asPrintable() {
return biomeName;
}
@Override
public boolean test(Object o) {
return false;
}
};
ResourceKey<Biome> a = BiomeAPI.getBiomeKey(biome.getBiome());
Holder<Biome> h = BuiltinRegistries.BIOME.getHolder(a).orElseThrow();
return LocateCommand.showLocateResult(
source,
result,
currentPosition,
new Pair<>(biomePosition, h),
"commands.locatebiome.success",
false
);
}
}
} }

View file

@ -18,9 +18,12 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import java.util.LinkedList;
import java.util.List;
public class EndBiomes { public class EndBiomes {
public static final BiomeAPI.BiomeType END_CAVE = new BiomeAPI.BiomeType("END_CAVE", BiomeAPI.BiomeType.END); public static final BiomeAPI.BiomeType END_CAVE = new BiomeAPI.BiomeType("END_CAVE", BiomeAPI.BiomeType.END);
public static final List<EndBiome> ALL_BE_BIOMES = new LinkedList<>();
public static BiomePicker CAVE_BIOMES = null; public static BiomePicker CAVE_BIOMES = null;
private static HexBiomeMap caveBiomeMap; private static HexBiomeMap caveBiomeMap;
private static long lastSeed; private static long lastSeed;
@ -113,6 +116,7 @@ public class EndBiomes {
} else { } else {
BiomeAPI.registerEndVoidBiome(biome); BiomeAPI.registerEndVoidBiome(biome);
} }
ALL_BE_BIOMES.add(biome);
} }
return biome; return biome;
} }
@ -150,6 +154,7 @@ public class EndBiomes {
final EndCaveBiome biome = EndCaveBiome.create(biomeConfig); final EndCaveBiome biome = EndCaveBiome.create(biomeConfig);
if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) {
BiomeAPI.registerBiome(biome, END_CAVE); BiomeAPI.registerBiome(biome, END_CAVE);
//ALL_BE_BIOMES.add(biome);
} }
return biome; return biome;
} }