Skip to content

Commit

Permalink
add new debug command to generate a team island (fully configured or …
Browse files Browse the repository at this point in the history
…not), or the spread files
  • Loading branch information
MelanX committed Apr 22, 2024
1 parent 0741094 commit 0aee6c4
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/main/java/de/melanx/skyblockbuilder/EventListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import de.melanx.skyblockbuilder.commands.invitation.DeclineCommand;
import de.melanx.skyblockbuilder.commands.invitation.InviteCommand;
import de.melanx.skyblockbuilder.commands.invitation.JoinCommand;
import de.melanx.skyblockbuilder.commands.operator.GenerateCommand;
import de.melanx.skyblockbuilder.commands.operator.ManageCommand;
import de.melanx.skyblockbuilder.config.StartingInventory;
import de.melanx.skyblockbuilder.config.common.CustomizationConfig;
Expand Down Expand Up @@ -90,6 +91,7 @@ public static void onRegisterCommands(RegisterCommandsEvent event) {
.then(ConvertCommand.register())
.then(CreateCommand.register())
.then(DeclineCommand.register())
.then(GenerateCommand.register())
.then(HomeCommand.register())
.then(InventoryCommand.register())
.then(InviteCommand.register())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import de.melanx.skyblockbuilder.data.SkyblockSavedData;
import de.melanx.skyblockbuilder.data.Team;
import de.melanx.skyblockbuilder.template.TemplateLoader;
import de.melanx.skyblockbuilder.util.SkyPaths;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.commands.arguments.EntityArgument;
Expand All @@ -13,6 +14,8 @@
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.players.PlayerList;

import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import java.util.Objects;
import java.util.Set;
Expand Down Expand Up @@ -52,7 +55,20 @@ public class Suggestions {
// Lists all templates
public static final SuggestionProvider<CommandSourceStack> TEMPLATES = ((context, builder) -> SharedSuggestionProvider
.suggest(TemplateLoader.getTemplateNames().stream()
.map(s -> s.split(" ").length == 1 ? s : "\"" + s + "\""), builder));
.map(s -> "\"" + s + "\""), builder));

public static final SuggestionProvider<CommandSourceStack> SPREADS = (((context, builder) -> {
try {
//noinspection resource
return SharedSuggestionProvider.suggest(
Files.list(SkyPaths.SPREADS_DIR)
.filter(s -> s.toString().endsWith(".nbt") || s.toString().endsWith(".snbt"))
.filter(Files::isRegularFile)
.map(s -> "\"" + SkyPaths.SPREADS_DIR.relativize(s) + "\""), builder);
} catch (IOException e) {
throw new RuntimeException(e);
}
}));

// Lists all teams except spawn
public static final SuggestionProvider<CommandSourceStack> ALL_TEAMS = (context, builder) -> SharedSuggestionProvider
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package de.melanx.skyblockbuilder.commands.operator;

import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import de.melanx.skyblockbuilder.commands.Suggestions;
import de.melanx.skyblockbuilder.data.SkyblockSavedData;
import de.melanx.skyblockbuilder.template.ConfiguredTemplate;
import de.melanx.skyblockbuilder.template.TemplateLoader;
import de.melanx.skyblockbuilder.util.SkyPaths;
import de.melanx.skyblockbuilder.util.TemplateUtil;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.*;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import org.moddingx.libx.command.CommandUtil;

import java.io.IOException;

public class GenerateCommand {

private static final StructurePlaceSettings SETTINGS = new StructurePlaceSettings().setKnownShape(true).setKeepLiquids(false);

public static ArgumentBuilder<CommandSourceStack, ?> register() {
return Commands.literal("generate").requires(source -> source.hasPermission(2))
.then(Commands.literal("template")
.then(Commands.argument("template", StringArgumentType.string()).suggests(Suggestions.TEMPLATES)
.executes(GenerateCommand::generateTemplate)
.then(Commands.argument("pos", BlockPosArgument.blockPos())
.executes(GenerateCommand::generateTemplate)
.then(Commands.argument("border", BoolArgumentType.bool())
.executes(GenerateCommand::generateTemplate)
.then(Commands.argument("spreads", BoolArgumentType.bool())
.executes(GenerateCommand::generateTemplate))))))
.then(Commands.literal("spread")
.then(Commands.argument("file", StringArgumentType.string()).suggests(Suggestions.SPREADS)
.executes(GenerateCommand::generateSpread)
.then(Commands.argument("pos", BlockPosArgument.blockPos())
.executes(GenerateCommand::generateSpread))));
}

private static int generateTemplate(CommandContext<CommandSourceStack> context) {
String template = StringArgumentType.getString(context, "template");
BlockPos pos = BlockPos.containing(context.getSource().getPosition());
boolean border = CommandUtil.getArgumentOrDefault(context, "border", Boolean.class, false);
boolean spreads = CommandUtil.getArgumentOrDefault(context, "spreads", Boolean.class, false);
try {
pos = BlockPosArgument.getBlockPos(context, "pos");
} catch (IllegalArgumentException ignored) {}

ServerLevel level = context.getSource().getLevel();
ConfiguredTemplate configuredTemplate = TemplateLoader.getConfiguredTemplate(template);


if (configuredTemplate == null) {
context.getSource().sendFailure(Component.translatable("skyblockbuilder.command.generated.fail"));
return 0;
}
if (spreads) {
configuredTemplate.placeInWorld(level, pos, SETTINGS, level.random, Block.UPDATE_CLIENTS);
} else {
configuredTemplate.getTemplate().placeInWorld(level, pos, pos, SETTINGS, level.random, Block.UPDATE_CLIENTS);
}

if (border) {
SkyblockSavedData.surround(level, pos, configuredTemplate);
}

GenerateCommand.showLocationResult(context.getSource(), template, pos);
return 1;
}

private static int generateSpread(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
String file = StringArgumentType.getString(context, "file");
BlockPos pos = BlockPos.containing(context.getSource().getPosition());
try {
pos = BlockPosArgument.getBlockPos(context, "pos");
} catch (IllegalArgumentException ignored) {}

CompoundTag nbt;
try {
nbt = TemplateUtil.readTemplate(SkyPaths.SPREADS_DIR.resolve(file));
} catch (IOException e) {
throw new RuntimeException(e);
}

StructureTemplate template = new StructureTemplate();
//noinspection deprecation
template.load(BuiltInRegistries.BLOCK.asLookup(), nbt);

ServerLevel level = context.getSource().getLevel();
template.placeInWorld(level, pos, pos, SETTINGS, level.random, Block.UPDATE_CLIENTS);
showLocationResult(context.getSource(), file, pos);

return 1;
}

private static void showLocationResult(CommandSourceStack source, String structureName, BlockPos generatedAt) {
MutableComponent coords = ComponentUtils.wrapInSquareBrackets(Component.translatable("chat.coordinates", generatedAt.getX(), generatedAt.getY(), generatedAt.getZ()).withStyle(style -> style
.withColor(ChatFormatting.GREEN)
.withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/tp @s " + generatedAt.getX() + " " + generatedAt.getY() + " " + generatedAt.getZ()))
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable("chat.coordinates.tooltip")))));
source.sendSuccess(() -> Component.translatable("skyblockbuilder.command.generated", structureName, coords), true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ public Team createTeam(String teamName, ConfiguredTemplate template) {
BlockPos center = team.getIsland().getCenter();
List<BlockSnapshot> capturedBlockSnapshots = (List<BlockSnapshot>) this.level.capturedBlockSnapshots.clone();
this.level.captureBlockSnapshots = true;
template.placeInWorld(this.level, center, center, settings, RandomSource.create(), Block.UPDATE_CLIENTS);
template.placeInWorld(this.level, center, settings, RandomSource.create(), Block.UPDATE_CLIENTS);
SkyblockSavedData.surround(this.level, team.getIsland().getCenter(), template);
this.level.captureBlockSnapshots = false;
this.level.capturedBlockSnapshots.clear();
Expand Down Expand Up @@ -515,7 +515,7 @@ public static Set<TemplatesConfig.Spawn> initialPossibleSpawns(BlockPos center,
return positions;
}

private static void surround(ServerLevel level, BlockPos zero, ConfiguredTemplate configuredTemplate) {
public static void surround(ServerLevel level, BlockPos zero, ConfiguredTemplate configuredTemplate) {
if (configuredTemplate.getSurroundingBlocks().isEmpty() || configuredTemplate.getSurroundingMargin() <= 0) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ private static Set<TemplatesConfig.Spawn> collectSpawns(Map<String, Set<BlockPos
return spawns;
}

public boolean placeInWorld(ServerLevelAccessor serverLevel, BlockPos pos, BlockPos otherPos, StructurePlaceSettings settings, RandomSource random, int flags) {
public boolean placeInWorld(ServerLevelAccessor serverLevel, BlockPos pos, StructurePlaceSettings settings, RandomSource random, int flags) {
for (SpreadConfig spread : this.spreads) {
BlockPos offset = spread.getRandomOffset(random);
if (spread.getOrigin() != TemplateInfo.SpreadInfo.Origin.ZERO) {
offset = offset.offset(TemplateInfo.SpreadInfo.Origin.originOffset(spread.getOrigin(), this.template));
}
spread.getTemplate().placeInWorld(serverLevel, pos.offset(offset), otherPos.offset(offset), settings, random, flags);
spread.getTemplate().placeInWorld(serverLevel, pos.offset(offset), pos.offset(offset), settings, random, flags);
}
return this.template.placeInWorld(serverLevel, pos, otherPos, settings, random, flags);
return this.template.placeInWorld(serverLevel, pos, pos, settings, random, flags);
}

public StructureTemplate getTemplate() {
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/assets/skyblockbuilder/lang/de_de.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
"skyblockbuilder.command.argument.disable": "deaktivieren",
"skyblockbuilder.command.argument.disabled": "deaktiviert",

"skyblockbuilder.command.generated": "%s an %s generiert",
"skyblockbuilder.command.generated.fail": "Diese Vorlage existiert nicht.",

"skyblockbuilder.error.no_skyblock": "Dieser Befehl kann nur in SkyBlock Welten verwendet werden.",
"skyblockbuilder.command.error.cooldown": "Versuche es in %s Minuten noch einmal.",
"skyblockbuilder.command.error.creating_file": "Fehlgeschlagen, folgende Datei zu erstellen: %s",
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/assets/skyblockbuilder/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
"skyblockbuilder.command.argument.disable": "disable",
"skyblockbuilder.command.argument.disabled": "disabled",

"skyblockbuilder.command.generated": "Generated %s at %s",
"skyblockbuilder.command.generated.fail": "This template doesn't exist.",

"skyblockbuilder.error.no_skyblock": "This command can only be used in a skyblock world.",
"skyblockbuilder.command.error.cooldown": "Try again in %smin.",
"skyblockbuilder.command.error.creating_file": "Failed to create file %s",
Expand Down

0 comments on commit 0aee6c4

Please sign in to comment.