diff --git a/gradle.properties b/gradle.properties index 554341e0..a4fe3c13 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use # or better: https://modmuss50.me/fabric.html - minecraft_version=1.18.2 + minecraft_version=22w11a loader_version=0.13.3 fabric_version=0.46.4+1.18 diff --git a/src/main/java/carpet/CarpetExtension.java b/src/main/java/carpet/CarpetExtension.java index f09dd7a8..91c87215 100644 --- a/src/main/java/carpet/CarpetExtension.java +++ b/src/main/java/carpet/CarpetExtension.java @@ -3,7 +3,9 @@ package carpet; import carpet.script.CarpetExpression; import carpet.settings.SettingsManager; import com.mojang.brigadier.CommandDispatcher; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; +import net.minecraft.core.RegistryAccess; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import java.util.Map; @@ -44,12 +46,32 @@ public interface CarpetExtension /** * Register your own commands right after vanilla commands are added * If that matters for you + * + * Deprecated, use either this or rather {@link CarpetExtension#registerCommands(CommandDispatcher, CommandBuildContext)} * * @param dispatcher The current {@link CommandSource} dispatcher * where you should register your commands * */ - default void registerCommands(CommandDispatcher dispatcher) {} + @Deprecated(forRemoval = true) + default void registerCommands(CommandDispatcher dispatcher) { + final CommandBuildContext context = new CommandBuildContext(RegistryAccess.BUILTIN.get()); + context.missingTagAccessPolicy(CommandBuildContext.MissingTagAccessPolicy.RETURN_EMPTY); + registerCommands(dispatcher, context); + } + + /** + * Register your own commands right after vanilla commands are added + * If that matters for you + * + * @param dispatcher The current {@link CommandDispatcher} dispatcher + * where you should register your commands + * @param commandBuildContext The current {@link CommandBuildContext} context + * * which you can use for registries lookup + */ + default void registerCommands(CommandDispatcher dispatcher, final CommandBuildContext commandBuildContext) {} + + /** * Provide your own custom settings manager managed in the same way as base /carpet diff --git a/src/main/java/carpet/CarpetServer.java b/src/main/java/carpet/CarpetServer.java index 56dbd771..9754fb2e 100644 --- a/src/main/java/carpet/CarpetServer.java +++ b/src/main/java/carpet/CarpetServer.java @@ -32,6 +32,7 @@ import com.mojang.brigadier.CommandDispatcher; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.DedicatedServerModInitializer; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.server.MinecraftServer; @@ -117,37 +118,35 @@ public class CarpetServer // static for now - easier to handle all around the co extensions.forEach(e -> e.onTick(server)); } - @Deprecated - public static void registerCarpetCommands(CommandDispatcher dispatcher) { - } - - public static void registerCarpetCommands(CommandDispatcher dispatcher, Commands.CommandSelection environment) + public static void registerCarpetCommands(CommandDispatcher dispatcher, Commands.CommandSelection environment, CommandBuildContext commandBuildContext) { if (settingsManager == null) // bootstrap dev initialization check { return; } - settingsManager.registerCommand(dispatcher); + settingsManager.registerCommand(dispatcher, commandBuildContext); extensions.forEach(e -> { SettingsManager sm = e.customSettingsManager(); - if (sm != null) sm.registerCommand(dispatcher); + if (sm != null) sm.registerCommand(dispatcher, commandBuildContext); }); - TickCommand.register(dispatcher); - ProfileCommand.register(dispatcher); - CounterCommand.register(dispatcher); - LogCommand.register(dispatcher); - SpawnCommand.register(dispatcher); - PlayerCommand.register(dispatcher); - //CameraModeCommand.register(dispatcher); - InfoCommand.register(dispatcher); - DistanceCommand.register(dispatcher); - PerimeterInfoCommand.register(dispatcher); - DrawCommand.register(dispatcher); - ScriptCommand.register(dispatcher); - MobAICommand.register(dispatcher); + TickCommand.register(dispatcher, commandBuildContext); + ProfileCommand.register(dispatcher, commandBuildContext); + CounterCommand.register(dispatcher, commandBuildContext); + LogCommand.register(dispatcher, commandBuildContext); + SpawnCommand.register(dispatcher, commandBuildContext); + PlayerCommand.register(dispatcher, commandBuildContext); + InfoCommand.register(dispatcher, commandBuildContext); + DistanceCommand.register(dispatcher, commandBuildContext); + PerimeterInfoCommand.register(dispatcher, commandBuildContext); + DrawCommand.register(dispatcher, commandBuildContext); + ScriptCommand.register(dispatcher, commandBuildContext); + MobAICommand.register(dispatcher, commandBuildContext); // registering command of extensions that has registered before either server is created // for all other, they will have them registered when they add themselves - extensions.forEach(e -> e.registerCommands(dispatcher)); + extensions.forEach(e -> { + e.registerCommands(dispatcher, commandBuildContext); + e.registerCommands(dispatcher); + }); currentCommandDispatcher = dispatcher; if (environment != Commands.CommandSelection.DEDICATED) diff --git a/src/main/java/carpet/commands/CounterCommand.java b/src/main/java/carpet/commands/CounterCommand.java index 59e0cd3d..39b4ee42 100644 --- a/src/main/java/carpet/commands/CounterCommand.java +++ b/src/main/java/carpet/commands/CounterCommand.java @@ -5,6 +5,7 @@ import carpet.helpers.HopperCounter; import carpet.utils.Messenger; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandRuntimeException; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; @@ -20,7 +21,7 @@ public class CounterCommand /** * The method used to register the command and make it available for the players to use. */ - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, CommandBuildContext commandBuildContext) { LiteralArgumentBuilder literalargumentbuilder = Commands.literal("counter").executes((context) -> listAllCounters(context.getSource(), false)).requires((player) -> diff --git a/src/main/java/carpet/commands/DistanceCommand.java b/src/main/java/carpet/commands/DistanceCommand.java index 0a5b2d23..9f9193fa 100644 --- a/src/main/java/carpet/commands/DistanceCommand.java +++ b/src/main/java/carpet/commands/DistanceCommand.java @@ -5,6 +5,7 @@ import carpet.settings.SettingsManager; import carpet.utils.DistanceCalculator; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.coordinates.Vec3Argument; @@ -13,7 +14,7 @@ import static net.minecraft.commands.Commands.literal; public class DistanceCommand { - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, CommandBuildContext commandBuildContext) { LiteralArgumentBuilder command = literal("distance"). requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandDistance)). diff --git a/src/main/java/carpet/commands/DrawCommand.java b/src/main/java/carpet/commands/DrawCommand.java index 479ee8c5..1715067b 100644 --- a/src/main/java/carpet/commands/DrawCommand.java +++ b/src/main/java/carpet/commands/DrawCommand.java @@ -15,6 +15,8 @@ import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import java.util.List; import java.util.function.Predicate; + +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.blocks.BlockInput; import net.minecraft.commands.arguments.blocks.BlockPredicateArgument; @@ -35,48 +37,48 @@ import static net.minecraft.commands.SharedSuggestionProvider.suggest; public class DrawCommand { - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, final CommandBuildContext context) { LiteralArgumentBuilder command = literal("draw"). requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandDraw)). then(literal("sphere"). then(argument("center", BlockPosArgument.blockPos()). then(argument("radius", IntegerArgumentType.integer(1)). - then(drawShape(c -> DrawCommand.drawSphere(c, false)))))). + then(drawShape(c -> DrawCommand.drawSphere(c, false), context))))). then(literal("ball"). then(argument("center", BlockPosArgument.blockPos()). then(argument("radius", IntegerArgumentType.integer(1)). - then(drawShape(c -> DrawCommand.drawSphere(c, true)))))). + then(drawShape(c -> DrawCommand.drawSphere(c, true), context))))). then(literal("diamond"). then(argument("center", BlockPosArgument.blockPos()). then(argument("radius", IntegerArgumentType.integer(1)). - then(drawShape(c -> DrawCommand.drawDiamond(c, true)))))). + then(drawShape(c -> DrawCommand.drawDiamond(c, true), context))))). then(literal("pyramid"). then(argument("center", BlockPosArgument.blockPos()). then(argument("radius", IntegerArgumentType.integer(1)). then(argument("height",IntegerArgumentType.integer(1)). then(argument("pointing",StringArgumentType.word()).suggests( (c, b) -> suggest(new String[]{"up","down"},b)). then(argument("orientation",StringArgumentType.word()).suggests( (c, b) -> suggest(new String[]{"y","x","z"},b)). - then(drawShape(c -> DrawCommand.drawPyramid(c, "square", true))))))))). + then(drawShape(c -> DrawCommand.drawPyramid(c, "square", true), context)))))))). then(literal("cone"). then(argument("center", BlockPosArgument.blockPos()). then(argument("radius", IntegerArgumentType.integer(1)). then(argument("height",IntegerArgumentType.integer(1)). then(argument("pointing",StringArgumentType.word()).suggests( (c, b) -> suggest(new String[]{"up","down"},b)). then(argument("orientation",StringArgumentType.word()).suggests( (c, b) -> suggest(new String[]{"y","x","z"},b)) - .then(drawShape(c -> DrawCommand.drawPyramid(c, "circle", true))))))))). + .then(drawShape(c -> DrawCommand.drawPyramid(c, "circle", true), context)))))))). then(literal("cylinder"). then(argument("center", BlockPosArgument.blockPos()). then(argument("radius", IntegerArgumentType.integer(1)). then(argument("height",IntegerArgumentType.integer(1)). then(argument("orientation",StringArgumentType.word()).suggests( (c, b) -> suggest(new String[]{"y","x","z"},b)) - .then(drawShape(c -> DrawCommand.drawPrism(c, "circle")))))))). + .then(drawShape(c -> DrawCommand.drawPrism(c, "circle"), context))))))). then(literal("cuboid"). then(argument("center", BlockPosArgument.blockPos()). then(argument("radius", IntegerArgumentType.integer(1)). then(argument("height",IntegerArgumentType.integer(1)). then(argument("orientation",StringArgumentType.word()).suggests( (c, b) -> suggest(new String[]{"y","x","z"},b)) - .then(drawShape(c -> DrawCommand.drawPrism(c, "square")))))))); + .then(drawShape(c -> DrawCommand.drawPrism(c, "square"), context))))))); dispatcher.register(command); } @@ -87,12 +89,12 @@ public class DrawCommand } private static RequiredArgumentBuilder - drawShape(Command drawer) + drawShape(Command drawer, CommandBuildContext commandBuildContext) { - return argument("block", BlockStateArgument.block()). + return argument("block", BlockStateArgument.block(commandBuildContext)). executes(drawer) .then(literal("replace") - .then(argument("filter", BlockPredicateArgument.blockPredicate()) + .then(argument("filter", BlockPredicateArgument.blockPredicate(commandBuildContext)) .executes(drawer))); } diff --git a/src/main/java/carpet/commands/InfoCommand.java b/src/main/java/carpet/commands/InfoCommand.java index 924e88e4..267f0067 100644 --- a/src/main/java/carpet/commands/InfoCommand.java +++ b/src/main/java/carpet/commands/InfoCommand.java @@ -9,6 +9,8 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; + +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.coordinates.BlockPosArgument; import net.minecraft.core.BlockPos; @@ -21,7 +23,7 @@ import static net.minecraft.commands.Commands.literal; public class InfoCommand { - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, CommandBuildContext commandBuildContext) { LiteralArgumentBuilder command = literal("info"). requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandInfo)). diff --git a/src/main/java/carpet/commands/LogCommand.java b/src/main/java/carpet/commands/LogCommand.java index f6ebab9e..6e86f2ef 100644 --- a/src/main/java/carpet/commands/LogCommand.java +++ b/src/main/java/carpet/commands/LogCommand.java @@ -14,6 +14,8 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; + +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.world.entity.player.Player; @@ -24,7 +26,7 @@ import static net.minecraft.commands.SharedSuggestionProvider.suggest; public class LogCommand { - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, CommandBuildContext commandBuildContext) { LiteralArgumentBuilder literalargumentbuilder = Commands.literal("log"). requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandLog)). diff --git a/src/main/java/carpet/commands/MobAICommand.java b/src/main/java/carpet/commands/MobAICommand.java index 92fb224b..48cb5f84 100644 --- a/src/main/java/carpet/commands/MobAICommand.java +++ b/src/main/java/carpet/commands/MobAICommand.java @@ -6,6 +6,7 @@ import carpet.utils.MobAI; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.EntitySummonArgument; import net.minecraft.core.Registry; @@ -16,7 +17,7 @@ import static net.minecraft.commands.SharedSuggestionProvider.suggest; public class MobAICommand { - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, final CommandBuildContext commandBuildContext) { LiteralArgumentBuilder command = literal("track"). requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandTrackAI)). diff --git a/src/main/java/carpet/commands/PerimeterInfoCommand.java b/src/main/java/carpet/commands/PerimeterInfoCommand.java index 715d7a2f..525eeb18 100644 --- a/src/main/java/carpet/commands/PerimeterInfoCommand.java +++ b/src/main/java/carpet/commands/PerimeterInfoCommand.java @@ -6,6 +6,7 @@ import carpet.utils.Messenger; import carpet.utils.PerimeterDiagnostics; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.EntitySummonArgument; import net.minecraft.commands.arguments.coordinates.BlockPosArgument; @@ -21,7 +22,7 @@ import static net.minecraft.commands.Commands.literal; public class PerimeterInfoCommand { - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, CommandBuildContext commandBuildContext) { LiteralArgumentBuilder command = literal("perimeterinfo"). requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandPerimeterInfo)). diff --git a/src/main/java/carpet/commands/PlayerCommand.java b/src/main/java/carpet/commands/PlayerCommand.java index 14bdcc49..bd84853f 100644 --- a/src/main/java/carpet/commands/PlayerCommand.java +++ b/src/main/java/carpet/commands/PlayerCommand.java @@ -15,6 +15,7 @@ import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.DimensionArgument; import net.minecraft.commands.arguments.coordinates.RotationArgument; @@ -44,7 +45,7 @@ public class PlayerCommand { // TODO: allow any order like execute - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, CommandBuildContext commandBuildContext) { final String[] gamemodeStrings = Arrays.stream(GameType.values()) .map(GameType::getName) diff --git a/src/main/java/carpet/commands/ProfileCommand.java b/src/main/java/carpet/commands/ProfileCommand.java index 2eb2ffa2..4f3097d7 100644 --- a/src/main/java/carpet/commands/ProfileCommand.java +++ b/src/main/java/carpet/commands/ProfileCommand.java @@ -4,6 +4,7 @@ import carpet.CarpetSettings; import carpet.settings.SettingsManager; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import static carpet.commands.TickCommand.healthEntities; @@ -15,7 +16,7 @@ import static net.minecraft.commands.Commands.literal; public class ProfileCommand { - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, CommandBuildContext commandBuildContext) { LiteralArgumentBuilder literalargumentbuilder = literal("profile"). requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandProfile)). diff --git a/src/main/java/carpet/commands/ScriptCommand.java b/src/main/java/carpet/commands/ScriptCommand.java index 66a265ba..00e027d2 100644 --- a/src/main/java/carpet/commands/ScriptCommand.java +++ b/src/main/java/carpet/commands/ScriptCommand.java @@ -23,6 +23,7 @@ import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.commands.CommandBuildContext; import org.apache.commons.lang3.StringUtils; import java.io.IOException; @@ -129,7 +130,7 @@ public class ScriptCommand }); } - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, final CommandBuildContext commandBuildContext) { LiteralArgumentBuilder b = literal("globals"). executes(context -> listGlobals(context, false)). @@ -216,7 +217,7 @@ public class ScriptCommand then(argument("from", BlockPosArgument.blockPos()). then(argument("to", BlockPosArgument.blockPos()). then(argument("expr", StringArgumentType.string()). - then(argument("block", BlockStateArgument.block()). + then(argument("block", BlockStateArgument.block(commandBuildContext)). executes((cc) -> scriptFill( cc, BlockPosArgument.getSpawnablePos(cc, "origin"), @@ -227,7 +228,7 @@ public class ScriptCommand null, "solid" )). then(literal("replace"). - then(argument("filter", BlockPredicateArgument.blockPredicate()) + then(argument("filter", BlockPredicateArgument.blockPredicate(commandBuildContext)) .executes((cc) -> scriptFill( cc, BlockPosArgument.getSpawnablePos(cc, "origin"), @@ -243,7 +244,7 @@ public class ScriptCommand then(argument("from", BlockPosArgument.blockPos()). then(argument("to", BlockPosArgument.blockPos()). then(argument("expr", StringArgumentType.string()). - then(argument("block", BlockStateArgument.block()). + then(argument("block", BlockStateArgument.block(commandBuildContext)). executes((cc) -> scriptFill( cc, BlockPosArgument.getSpawnablePos(cc, "origin"), @@ -254,7 +255,7 @@ public class ScriptCommand null, "outline" )). then(literal("replace"). - then(argument("filter", BlockPredicateArgument.blockPredicate()) + then(argument("filter", BlockPredicateArgument.blockPredicate(commandBuildContext)) .executes((cc) -> scriptFill( cc, BlockPosArgument.getSpawnablePos(cc, "origin"), diff --git a/src/main/java/carpet/commands/SpawnCommand.java b/src/main/java/carpet/commands/SpawnCommand.java index 156fa5a8..831b5712 100644 --- a/src/main/java/carpet/commands/SpawnCommand.java +++ b/src/main/java/carpet/commands/SpawnCommand.java @@ -15,6 +15,8 @@ import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import java.util.Arrays; import java.util.Locale; import java.util.stream.Collectors; + +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.DimensionArgument; import net.minecraft.commands.arguments.coordinates.BlockPosArgument; @@ -36,7 +38,7 @@ import static net.minecraft.commands.SharedSuggestionProvider.suggest; public class SpawnCommand { - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, CommandBuildContext commandBuildContext) { LiteralArgumentBuilder literalargumentbuilder = literal("spawn"). requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandSpawn)); diff --git a/src/main/java/carpet/commands/TickCommand.java b/src/main/java/carpet/commands/TickCommand.java index f99ecaab..319bbdab 100644 --- a/src/main/java/carpet/commands/TickCommand.java +++ b/src/main/java/carpet/commands/TickCommand.java @@ -9,6 +9,7 @@ import carpet.utils.Messenger; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.network.chat.BaseComponent; import net.minecraft.server.level.ServerPlayer; @@ -25,7 +26,7 @@ import static net.minecraft.commands.SharedSuggestionProvider.suggest; public class TickCommand { - public static void register(CommandDispatcher dispatcher) + public static void register(CommandDispatcher dispatcher, CommandBuildContext commandBuildContext) { LiteralArgumentBuilder literalargumentbuilder = literal("tick"). requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandTick)). diff --git a/src/main/java/carpet/fakes/ChunkGeneratorInterface.java b/src/main/java/carpet/fakes/ChunkGeneratorInterface.java index f2b02b5b..de3d2ffd 100644 --- a/src/main/java/carpet/fakes/ChunkGeneratorInterface.java +++ b/src/main/java/carpet/fakes/ChunkGeneratorInterface.java @@ -1,12 +1,13 @@ package carpet.fakes; -import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.levelgen.structure.Structure; import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement; import java.util.List; public interface ChunkGeneratorInterface { - void initStrongholds(); - List getPlacementsForFeatureCM(final ConfiguredStructureFeature structure); + void initStrongholds(final ServerLevel level); + List getPlacementsForFeatureCM(final ServerLevel level, final Structure structure); } diff --git a/src/main/java/carpet/helpers/EntityPlayerActionPack.java b/src/main/java/carpet/helpers/EntityPlayerActionPack.java index 345bf784..788b58af 100644 --- a/src/main/java/carpet/helpers/EntityPlayerActionPack.java +++ b/src/main/java/carpet/helpers/EntityPlayerActionPack.java @@ -399,7 +399,7 @@ public class EntityPlayerActionPack boolean blockBroken = false; if (player.gameMode.getGameModeForPlayer().isCreative()) { - player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.getLevel().getMaxBuildHeight()); + player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.getLevel().getMaxBuildHeight(), -1); ap.blockHitDelay = 5; blockBroken = true; } @@ -407,9 +407,9 @@ public class EntityPlayerActionPack { if (ap.currentBlock != null) { - player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, side, player.getLevel().getMaxBuildHeight()); + player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, side, player.getLevel().getMaxBuildHeight(), -1); } - player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.getLevel().getMaxBuildHeight()); + player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.getLevel().getMaxBuildHeight(), -1); boolean notAir = !state.isAir(); if (notAir && ap.curBlockDamageMP == 0) { @@ -432,7 +432,7 @@ public class EntityPlayerActionPack ap.curBlockDamageMP += state.getDestroyProgress(player, player.level, pos); if (ap.curBlockDamageMP >= 1) { - player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK, side, player.getLevel().getMaxBuildHeight()); + player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK, side, player.getLevel().getMaxBuildHeight(), -1); ap.currentBlock = null; ap.blockHitDelay = 5; blockBroken = true; @@ -454,7 +454,7 @@ public class EntityPlayerActionPack EntityPlayerActionPack ap = ((ServerPlayerEntityInterface) player).getActionPack(); if (ap.currentBlock == null) return; player.level.destroyBlockProgress(-1, ap.currentBlock, -1); - player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, Direction.DOWN, player.getLevel().getMaxBuildHeight()); + player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, Direction.DOWN, player.getLevel().getMaxBuildHeight(), -1); ap.currentBlock = null; } }, diff --git a/src/main/java/carpet/helpers/FeatureGenerator.java b/src/main/java/carpet/helpers/FeatureGenerator.java index fba161d4..12162801 100644 --- a/src/main/java/carpet/helpers/FeatureGenerator.java +++ b/src/main/java/carpet/helpers/FeatureGenerator.java @@ -2,6 +2,7 @@ package carpet.helpers; import carpet.CarpetSettings; import carpet.fakes.ChunkGeneratorInterface; +import com.google.common.collect.ImmutableList; import com.mojang.datafixers.util.Pair; import java.util.HashMap; @@ -16,6 +17,7 @@ import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; import net.minecraft.core.QuartPos; import net.minecraft.core.Registry; +import net.minecraft.data.BuiltinRegistries; import net.minecraft.data.worldgen.ProcessorLists; import net.minecraft.data.worldgen.placement.PlacementUtils; import net.minecraft.resources.ResourceLocation; @@ -27,20 +29,22 @@ import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.RandomState; +import net.minecraft.world.level.levelgen.VerticalAnchor; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.feature.StructureFeature; import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; -import net.minecraft.world.level.levelgen.feature.configurations.JigsawConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.SimpleRandomFeatureConfiguration; import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration; import net.minecraft.world.level.levelgen.feature.featuresize.TwoLayersFeatureSize; import net.minecraft.world.level.levelgen.feature.foliageplacers.BlobFoliagePlacer; import net.minecraft.world.level.levelgen.feature.foliageplacers.FancyFoliagePlacer; import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.heightproviders.ConstantHeight; import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.StructureSet; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureType; import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement; import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool; import net.minecraft.world.level.levelgen.feature.treedecorators.BeehiveDecorator; @@ -49,6 +53,7 @@ import net.minecraft.world.level.levelgen.feature.trunkplacers.StraightTrunkPlac import net.minecraft.world.level.levelgen.placement.PlacedFeature; import net.minecraft.world.level.levelgen.structure.StructureStart; import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement; +import net.minecraft.world.level.levelgen.structure.structures.JigsawStructure; public class FeatureGenerator { @@ -61,10 +66,10 @@ public class FeatureGenerator return custom.plop(world, pos); } ResourceLocation id = new ResourceLocation(featureName); - ConfiguredStructureFeature structureFeature = world.registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY).get(id); - if (structureFeature != null) + Structure structure = world.registryAccess().registryOrThrow(Registry.STRUCTURE_REGISTRY).get(id); + if (structure != null) { - return plopAnywhere( structureFeature, world, pos, world.getChunkSource().getGenerator(), false); + return plopAnywhere( structure, world, pos, world.getChunkSource().getGenerator(), false); } ConfiguredFeature configuredFeature = world.registryAccess().registryOrThrow(Registry.CONFIGURED_FEATURE_REGISTRY).get(id); @@ -80,10 +85,10 @@ public class FeatureGenerator CarpetSettings.skipGenerationChecks.set(false); } } - StructureFeature structure = Registry.STRUCTURE_FEATURE.get(id); + StructureType structureType = Registry.STRUCTURE_TYPES.get(id); if (structure != null) { - ConfiguredStructureFeature configuredStandard = getDefaultFeature(structure, world, pos); + Structure configuredStandard = getDefaultFeature(structureType, world, pos); if (configuredStandard != null) return plopAnywhere(configuredStandard, world, pos, world.getChunkSource().getGenerator(), false); } @@ -107,17 +112,17 @@ public class FeatureGenerator return null; } - public static ConfiguredStructureFeature resolveConfiguredStructure(String name, ServerLevel world, BlockPos pos) + public static Structure resolveConfiguredStructure(String name, ServerLevel world, BlockPos pos) { ResourceLocation id = new ResourceLocation(name); - ConfiguredStructureFeature configuredStructureFeature = world.registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY).get(id); + Structure configuredStructureFeature = world.registryAccess().registryOrThrow(Registry.STRUCTURE_REGISTRY).get(id); if (configuredStructureFeature != null) return configuredStructureFeature; - StructureFeature structureFeature = Registry.STRUCTURE_FEATURE.get(id); + StructureType structureFeature = Registry.STRUCTURE_TYPES.get(id); if (structureFeature == null) return null; return getDefaultFeature(structureFeature, world, pos); } - synchronized public static Boolean plopGrid(ConfiguredStructureFeature structureFeature, ServerLevel world, BlockPos pos) + synchronized public static Boolean plopGrid(Structure structureFeature, ServerLevel world, BlockPos pos) { return plopAnywhere( structureFeature, world, pos, world.getChunkSource().getGenerator(), true); } @@ -153,11 +158,11 @@ public class FeatureGenerator return simplePlop(new ConfiguredFeature(Feature.TREE, config)); } - private static Thing spawnCustomStructure(ConfiguredStructureFeature structure) + private static Thing spawnCustomStructure(Structure structure) { return setupCustomStructure(structure,false); } - private static Thing setupCustomStructure(ConfiguredStructureFeature structure, boolean wireOnly) + private static Thing setupCustomStructure(Structure structure, boolean wireOnly) { return (w, p) -> plopAnywhere(structure, w, p, w.getChunkSource().getGenerator(), wireOnly); } @@ -169,17 +174,17 @@ public class FeatureGenerator return null; } - private static ConfiguredStructureFeature getDefaultFeature(StructureFeature structure, ServerLevel world, BlockPos pos) + private static Structure getDefaultFeature(StructureType structure, ServerLevel world, BlockPos pos) { // would be nice to have a way to grab structures of this type for position - + // TODO allow old types, like vaillage, or bastion Holder existingBiome = world.getBiome(pos); - ConfiguredStructureFeature result = null; - for (var confstr : world.registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY).entrySet().stream(). - filter(cS -> cS.getValue().feature == structure).map(Map.Entry::getValue).toList()) + Structure result = null; + for (Structure confstr : world.registryAccess().registryOrThrow(Registry.STRUCTURE_REGISTRY).entrySet().stream(). + filter(cS -> cS.getValue().type() == structure).map(Map.Entry::getValue).toList()) { result = confstr; - if (confstr.biomes.contains(existingBiome)) return result; + if (confstr.biomes().contains(existingBiome)) return result; } return result; } @@ -199,32 +204,33 @@ public class FeatureGenerator findFirst().map(Map.Entry::getValue).orElse(null); } - public static StructureStart shouldStructureStartAt(ServerLevel world, BlockPos pos, ConfiguredStructureFeature structure, boolean computeBox) + public static StructureStart shouldStructureStartAt(ServerLevel world, BlockPos pos, Structure structure, boolean computeBox) { - long seed = world.getSeed(); + //long seed = world.getSeed(); + RandomState seed = world.getChunkSource().randomState(); ChunkGenerator generator = world.getChunkSource().getGenerator(); ChunkGeneratorInterface cgi = (ChunkGeneratorInterface) generator; - List structureConfig = cgi.getPlacementsForFeatureCM(structure); + List structureConfig = cgi.getPlacementsForFeatureCM(world, structure); ChunkPos chunkPos = new ChunkPos(pos); - boolean couldPlace = structureConfig.stream().anyMatch(p -> p.isFeatureChunk(generator, world.getSeed(), chunkPos.x, chunkPos.z)); + boolean couldPlace = structureConfig.stream().anyMatch(p -> p.isStructureChunk(generator, seed, world.getSeed(), chunkPos.x, chunkPos.z)); if (!couldPlace) return null; final HolderSet structureBiomes = structure.biomes(); if (!computeBox) { - Holder genBiome = generator.getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ())); - if (structureBiomes.contains(genBiome) && structure.feature.canGenerate( - world.registryAccess(), generator, generator.getBiomeSource(), world.getStructureManager(), - seed, chunkPos, structure.config, world, structureBiomes::contains - )) + Holder genBiome = generator.getBiomeSource().getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ()), seed.sampler()); + if (structureBiomes.contains(genBiome) && structure.findGenerationPoint(new Structure.GenerationContext( + world.registryAccess(), generator, generator.getBiomeSource(), + seed, world.getStructureManager(), world.getSeed(), chunkPos, world, structureBiomes::contains + )).isPresent()) { return StructureStart.INVALID_START; } } else { final StructureStart filledStructure = structure.generate( - world.registryAccess(), generator, generator.getBiomeSource(), world.getStructureManager(), - seed, chunkPos, 0, world, structureBiomes::contains); + world.registryAccess(), generator, generator.getBiomeSource(), seed, world.getStructureManager(), + world.getSeed(), chunkPos, 0, world, structureBiomes::contains); if (filledStructure != null && filledStructure.isValid()) { return filledStructure; } @@ -251,61 +257,93 @@ public class FeatureGenerator PlacementUtils.inlinePlaced(Feature.CORAL_CLAW, FeatureConfiguration.NONE), PlacementUtils.inlinePlaced(Feature.CORAL_MUSHROOM, FeatureConfiguration.NONE) )))); - put("bastion_remnant_units", spawnCustomStructure(StructureFeature.BASTION_REMNANT.configured( - new JigsawConfiguration(Holder.direct(new StructureTemplatePool( - new ResourceLocation("bastion/starts"), - new ResourceLocation("empty"), - List.of( - Pair.of(StructurePoolElement.single("bastion/units/air_base", ProcessorLists.BASTION_GENERIC_DEGRADATION), 1) - ), - StructureTemplatePool.Projection.RIGID - )), 6), - BiomeTags.HAS_BASTION_REMNANT) + put("bastion_remnant_units", spawnCustomStructure( + new JigsawStructure( + BuiltinRegistries.BIOME.getOrCreateTag(BiomeTags.HAS_BASTION_REMNANT), + Map.of(), + GenerationStep.Decoration.SURFACE_STRUCTURES, + false, + Holder.direct(new StructureTemplatePool( + new ResourceLocation("bastion/starts"), + new ResourceLocation("empty"), + ImmutableList.of( + Pair.of(StructurePoolElement.single("bastion/units/air_base", ProcessorLists.BASTION_GENERIC_DEGRADATION), 1) + ), + StructureTemplatePool.Projection.RIGID + )), + 6, + ConstantHeight.of(VerticalAnchor.absolute(33)), + false + ) )); - put("bastion_remnant_hoglin_stable", spawnCustomStructure(StructureFeature.BASTION_REMNANT.configured( - new JigsawConfiguration(Holder.direct(new StructureTemplatePool( - new ResourceLocation("bastion/starts"), - new ResourceLocation("empty"), - List.of( - Pair.of(StructurePoolElement.single("bastion/hoglin_stable/air_base", ProcessorLists.BASTION_GENERIC_DEGRADATION), 1) - ), - StructureTemplatePool.Projection.RIGID - )), 6), - BiomeTags.HAS_BASTION_REMNANT) + put("bastion_remnant_hoglin_stable", spawnCustomStructure( + new JigsawStructure( + BuiltinRegistries.BIOME.getOrCreateTag(BiomeTags.HAS_BASTION_REMNANT), + Map.of(), + GenerationStep.Decoration.SURFACE_STRUCTURES, + false, + Holder.direct(new StructureTemplatePool( + new ResourceLocation("bastion/starts"), + new ResourceLocation("empty"), + ImmutableList.of( + Pair.of(StructurePoolElement.single("bastion/hoglin_stable/air_base", ProcessorLists.BASTION_GENERIC_DEGRADATION), 1) + ), + StructureTemplatePool.Projection.RIGID + )), + 6, + ConstantHeight.of(VerticalAnchor.absolute(33)), + false + ) )); - put("bastion_remnant_treasure", spawnCustomStructure(StructureFeature.BASTION_REMNANT.configured( - new JigsawConfiguration(Holder.direct(new StructureTemplatePool( - new ResourceLocation("bastion/starts"), - new ResourceLocation("empty"), - List.of( - Pair.of(StructurePoolElement.single("bastion/treasure/big_air_full", ProcessorLists.BASTION_GENERIC_DEGRADATION), 1) - ), - StructureTemplatePool.Projection.RIGID - )), 6), - BiomeTags.HAS_BASTION_REMNANT) + put("bastion_remnant_treasure", spawnCustomStructure( + new JigsawStructure( + BuiltinRegistries.BIOME.getOrCreateTag(BiomeTags.HAS_BASTION_REMNANT), + Map.of(), + GenerationStep.Decoration.SURFACE_STRUCTURES, + false, + Holder.direct(new StructureTemplatePool( + new ResourceLocation("bastion/starts"), + new ResourceLocation("empty"), + ImmutableList.of( + Pair.of(StructurePoolElement.single("bastion/treasure/big_air_full", ProcessorLists.BASTION_GENERIC_DEGRADATION), 1) + ), + StructureTemplatePool.Projection.RIGID + )), + 6, + ConstantHeight.of(VerticalAnchor.absolute(33)), + false + ) )); - put("bastion_remnant_bridge", spawnCustomStructure(StructureFeature.BASTION_REMNANT.configured( - new JigsawConfiguration(Holder.direct(new StructureTemplatePool( - new ResourceLocation("bastion/starts"), - new ResourceLocation("empty"), - List.of( - Pair.of(StructurePoolElement.single("bastion/bridge/starting_pieces/entrance_base", ProcessorLists.BASTION_GENERIC_DEGRADATION), 1) - ), - StructureTemplatePool.Projection.RIGID - )), 6), - BiomeTags.HAS_BASTION_REMNANT) + put("bastion_remnant_bridge", spawnCustomStructure( + new JigsawStructure( + BuiltinRegistries.BIOME.getOrCreateTag(BiomeTags.HAS_BASTION_REMNANT), + Map.of(), + GenerationStep.Decoration.SURFACE_STRUCTURES, + false, + Holder.direct(new StructureTemplatePool( + new ResourceLocation("bastion/starts"), + new ResourceLocation("empty"), + ImmutableList.of( + Pair.of(StructurePoolElement.single("bastion/bridge/starting_pieces/entrance_base", ProcessorLists.BASTION_GENERIC_DEGRADATION), 1) + ), + StructureTemplatePool.Projection.RIGID + )), + 6, + ConstantHeight.of(VerticalAnchor.absolute(33)), + false + ) )); }}; - public static boolean plopAnywhere(ConfiguredStructureFeature structure, ServerLevel world, BlockPos pos, ChunkGenerator generator, boolean wireOnly) + public static boolean plopAnywhere(Structure structure, ServerLevel world, BlockPos pos, ChunkGenerator generator, boolean wireOnly) { if (world.isClientSide()) return false; CarpetSettings.skipGenerationChecks.set(true); try { - StructureStart start = structure.generate(world.registryAccess(), generator, generator.getBiomeSource(), world.getStructureManager(), world.getSeed(), new ChunkPos(pos), 0, world, b -> true ); + StructureStart start = structure.generate(world.registryAccess(), generator, generator.getBiomeSource(), world.getChunkSource().randomState(), world.getStructureManager(), world.getSeed(), new ChunkPos(pos), 0, world, b -> true ); if (start == StructureStart.INVALID_START) { return false; @@ -315,18 +353,18 @@ public class FeatureGenerator int k = pos.getZ() >> 4; long chId = ChunkPos.asLong(j, k); - world.getChunk(j, k).addReferenceForFeature(structure, chId); + world.getChunk(j, k).addReferenceForStructure(structure, chId); BoundingBox box = start.getBoundingBox(); if (!wireOnly) { - Registry> registry3 = world.registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY); + Registry registry3 = world.registryAccess().registryOrThrow(Registry.STRUCTURE_REGISTRY); world.setCurrentlyGenerating(() -> { Objects.requireNonNull(structure); return registry3.getResourceKey(structure).map(Object::toString).orElseGet(structure::toString); }); - start.placeInChunk(world, world.structureFeatureManager(), generator, rand, box, new ChunkPos(j, k)); + start.placeInChunk(world, world.structureManager(), generator, rand, box, new ChunkPos(j, k)); } //structurestart.notifyPostProcessAt(new ChunkPos(j, k)); int i = Math.max(box.getXSpan(),box.getZSpan())/16+1; @@ -339,7 +377,7 @@ public class FeatureGenerator if (k1 == j && l1 == k) continue; if (box.intersects(k1<<4, l1<<4, (k1<<4) + 15, (l1<<4) + 15)) { - world.getChunk(k1, l1).addReferenceForFeature(structure, chId); + world.getChunk(k1, l1).addReferenceForStructure(structure, chId); } } } diff --git a/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java b/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java index 4773fc6d..06868170 100644 --- a/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java +++ b/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java @@ -3,7 +3,8 @@ package carpet.mixins; import carpet.utils.SpawnOverrides; import it.unimi.dsi.fastutil.longs.LongSet; import net.minecraft.core.Holder; -import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.levelgen.structure.Structure; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -12,7 +13,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import net.minecraft.core.BlockPos; import net.minecraft.util.random.WeightedRandomList; import net.minecraft.world.entity.MobCategory; -import net.minecraft.world.level.StructureFeatureManager; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.MobSpawnSettings; import net.minecraft.world.level.chunk.ChunkGenerator; @@ -30,9 +30,9 @@ public abstract class ChunkGenerator_customMobSpawnsMixin value = "INVOKE", target = "Ljava/util/Map$Entry;getKey()Ljava/lang/Object;" ), cancellable = true) - private void checkCMSpawns(Holder holder, StructureFeatureManager structureFeatureManager, MobCategory mobCategory, BlockPos blockPos, - CallbackInfoReturnable> cir, - Map, LongSet> map, Iterator var6, Map.Entry, LongSet> entry) + private void checkCMSpawns(Holder holder, StructureManager structureFeatureManager, MobCategory mobCategory, BlockPos blockPos, + CallbackInfoReturnable> cir, + Map map, Iterator var6, Map.Entry entry) { WeightedRandomList res = SpawnOverrides.test(structureFeatureManager, entry.getValue(), mobCategory, entry.getKey(), blockPos); if (res != null) diff --git a/src/main/java/carpet/mixins/ChunkGenerator_scarpetMixin.java b/src/main/java/carpet/mixins/ChunkGenerator_scarpetMixin.java index 9a16709c..1aae936b 100644 --- a/src/main/java/carpet/mixins/ChunkGenerator_scarpetMixin.java +++ b/src/main/java/carpet/mixins/ChunkGenerator_scarpetMixin.java @@ -2,8 +2,10 @@ package carpet.mixins; import carpet.fakes.ChunkGeneratorInterface; import net.minecraft.core.Holder; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; +import net.minecraft.world.level.levelgen.RandomState; +import net.minecraft.world.level.levelgen.structure.Structure; import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -14,18 +16,18 @@ import java.util.List; public abstract class ChunkGenerator_scarpetMixin implements ChunkGeneratorInterface { - @Shadow protected abstract List getPlacementsForFeature(Holder> holder); + @Shadow public abstract void ensureStructuresGenerated(RandomState randomState); - @Shadow public abstract void ensureStructuresGenerated(); + @Shadow protected abstract List getPlacementsForStructure(Holder holder, RandomState randomState); @Override - public void initStrongholds() + public void initStrongholds(final ServerLevel level) { - ensureStructuresGenerated(); + ensureStructuresGenerated(level.getChunkSource().randomState()); } @Override - public List getPlacementsForFeatureCM(ConfiguredStructureFeature structure) { - return getPlacementsForFeature(Holder.direct(structure)); + public List getPlacementsForFeatureCM(final ServerLevel level, Structure structure) { + return getPlacementsForStructure(Holder.direct(structure), level.getChunkSource().randomState()); } } diff --git a/src/main/java/carpet/mixins/Commands_customCommandsMixin.java b/src/main/java/carpet/mixins/Commands_customCommandsMixin.java index 47d40c4c..e1332fa4 100644 --- a/src/main/java/carpet/mixins/Commands_customCommandsMixin.java +++ b/src/main/java/carpet/mixins/Commands_customCommandsMixin.java @@ -3,6 +3,7 @@ package carpet.mixins; import carpet.CarpetServer; import carpet.CarpetSettings; import com.mojang.brigadier.CommandDispatcher; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import org.slf4j.Logger; @@ -25,9 +26,8 @@ public abstract class Commands_customCommandsMixin private CommandDispatcher dispatcher; @Inject(method = "", at = @At("RETURN")) - private void onRegister(Commands.CommandSelection arg, CallbackInfo ci) { - CarpetServer.registerCarpetCommands(this.dispatcher); - CarpetServer.registerCarpetCommands(this.dispatcher, arg); + private void onRegister(Commands.CommandSelection commandSelection, CommandBuildContext commandBuildContext, CallbackInfo ci) { + CarpetServer.registerCarpetCommands(this.dispatcher, commandSelection, commandBuildContext); } @Inject(method = "performCommand", at = @At("HEAD")) diff --git a/src/main/java/carpet/mixins/NaturalSpawnerMixin.java b/src/main/java/carpet/mixins/NaturalSpawnerMixin.java index 34cd1c5a..d59c5ab8 100644 --- a/src/main/java/carpet/mixins/NaturalSpawnerMixin.java +++ b/src/main/java/carpet/mixins/NaturalSpawnerMixin.java @@ -46,7 +46,8 @@ public class NaturalSpawnerMixin @Shadow @Final private static MobCategory[] SPAWNING_CATEGORIES; - @Redirect(method = "isValidSpawnPostitionForType(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/MobCategory;Lnet/minecraft/world/level/StructureFeatureManager;Lnet/minecraft/world/level/chunk/ChunkGenerator;Lnet/minecraft/world/level/biome/MobSpawnSettings$SpawnerData;Lnet/minecraft/core/BlockPos$MutableBlockPos;D)Z", at = @At( + @Redirect(method = "isValidSpawnPostitionForType", + at = @At( value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;noCollision(Lnet/minecraft/world/phys/AABB;)Z" )) diff --git a/src/main/java/carpet/mixins/SaplingBlock_desertShrubsMixin.java b/src/main/java/carpet/mixins/SaplingBlock_desertShrubsMixin.java index dc576dcd..fcde7ec7 100644 --- a/src/main/java/carpet/mixins/SaplingBlock_desertShrubsMixin.java +++ b/src/main/java/carpet/mixins/SaplingBlock_desertShrubsMixin.java @@ -2,6 +2,7 @@ package carpet.mixins; import carpet.CarpetSettings; import carpet.helpers.BlockSaplingHelper; +import net.minecraft.tags.BiomeTags; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -10,7 +11,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Random; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.SaplingBlock; import net.minecraft.world.level.block.state.BlockState; @@ -23,7 +23,7 @@ public abstract class SaplingBlock_desertShrubsMixin cancellable = true) private void onGenerate(ServerLevel serverWorld_1, BlockPos blockPos_1, BlockState blockState_1, Random random_1, CallbackInfo ci) { - if(CarpetSettings.desertShrubs && Biome.getBiomeCategory(serverWorld_1.getBiome(blockPos_1)) == Biome.BiomeCategory.DESERT && !BlockSaplingHelper.hasWater(serverWorld_1, blockPos_1)) + if(CarpetSettings.desertShrubs && serverWorld_1.getBiome(blockPos_1).is(BiomeTags.HAS_DESERT_PYRAMID) && !BlockSaplingHelper.hasWater(serverWorld_1, blockPos_1)) { serverWorld_1.setBlock(blockPos_1, Blocks.DEAD_BUSH.defaultBlockState(), 3); ci.cancel(); diff --git a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_interactionUpdatesMixin.java b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_interactionUpdatesMixin.java index 227c4e93..aebeb805 100644 --- a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_interactionUpdatesMixin.java +++ b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_interactionUpdatesMixin.java @@ -58,7 +58,7 @@ public class ServerGamePacketListenerImpl_interactionUpdatesMixin } @Inject(method = "handlePlayerAction", at = @At( value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerPlayerGameMode;handleBlockBreakAction(Lnet/minecraft/core/BlockPos;Lnet/minecraft/network/protocol/game/ServerboundPlayerActionPacket$Action;Lnet/minecraft/core/Direction;I)V", + target = "Lnet/minecraft/server/level/ServerPlayerGameMode;handleBlockBreakAction(Lnet/minecraft/core/BlockPos;Lnet/minecraft/network/protocol/game/ServerboundPlayerActionPacket$Action;Lnet/minecraft/core/Direction;II)V", shift = At.Shift.BEFORE )) private void beforeBlockBroken(ServerboundPlayerActionPacket packet, CallbackInfo ci) @@ -69,7 +69,7 @@ public class ServerGamePacketListenerImpl_interactionUpdatesMixin @Inject(method = "handlePlayerAction", at = @At( value = "INVOKE", - target ="Lnet/minecraft/server/level/ServerPlayerGameMode;handleBlockBreakAction(Lnet/minecraft/core/BlockPos;Lnet/minecraft/network/protocol/game/ServerboundPlayerActionPacket$Action;Lnet/minecraft/core/Direction;I)V", + target ="Lnet/minecraft/server/level/ServerPlayerGameMode;handleBlockBreakAction(Lnet/minecraft/core/BlockPos;Lnet/minecraft/network/protocol/game/ServerboundPlayerActionPacket$Action;Lnet/minecraft/core/Direction;II)V", shift = At.Shift.AFTER )) private void afterBlockBroken(ServerboundPlayerActionPacket packet, CallbackInfo ci) diff --git a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java index 56ae8126..7750cfde 100644 --- a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java +++ b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java @@ -106,7 +106,7 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin @Inject(method = "handlePlayerAction", at = @At( value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerPlayerGameMode;handleBlockBreakAction(Lnet/minecraft/core/BlockPos;Lnet/minecraft/network/protocol/game/ServerboundPlayerActionPacket$Action;Lnet/minecraft/core/Direction;I)V", + target = "Lnet/minecraft/server/level/ServerPlayerGameMode;handleBlockBreakAction(Lnet/minecraft/core/BlockPos;Lnet/minecraft/network/protocol/game/ServerboundPlayerActionPacket$Action;Lnet/minecraft/core/Direction;II)V", shift = At.Shift.BEFORE )) private void onClicked(ServerboundPlayerActionPacket packet, CallbackInfo ci) diff --git a/src/main/java/carpet/mixins/ServerPlayerGameMode_antiCheatMixin.java b/src/main/java/carpet/mixins/ServerPlayerGameMode_antiCheatMixin.java index 0985fb47..ac135780 100644 --- a/src/main/java/carpet/mixins/ServerPlayerGameMode_antiCheatMixin.java +++ b/src/main/java/carpet/mixins/ServerPlayerGameMode_antiCheatMixin.java @@ -14,58 +14,19 @@ import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(value = ServerPlayerGameMode.class, priority = 69420) // not that important for carpet public class ServerPlayerGameMode_antiCheatMixin { - // this is how it should be done - /* - @ModifyConstant(method = "processBlockBreakingAction", require = 0, - constant = @Constant(doubleValue = 36D)) - private double addDistance(double original) { - if (CarpetSettings.antiCheatDisabled) - return 1024D; // blocks 32 distance - return original; - } - */ - // that shoudn't've been a constant at the first place // resolves problems with mobs using reach entity attributes. @Redirect(method = "handleBlockBreakAction", at = @At( value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerPlayer;getX()D" - )) - private double getXX(ServerPlayer player, - BlockPos pos, ServerboundPlayerActionPacket.Action action, Direction direction, int worldHeight) - { - if (CarpetSettings.antiCheatDisabled && - player.position().add(0, 1.5, 0).distanceToSqr(Vec3.atCenterOf(pos)) < 1024 - ) return pos.getX()+0.5; - return player.getX(); - } - - @Redirect(method = "handleBlockBreakAction", at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerPlayer;getY()D" + target = "Lnet/minecraft/server/level/ServerPlayer;getEyePosition()Lnet/minecraft/world/phys/Vec3;" )) - private double getYY(ServerPlayer player, - BlockPos pos, ServerboundPlayerActionPacket.Action action, Direction direction, int worldHeight) + private Vec3 getEyePos(ServerPlayer instance, + final BlockPos pos, final ServerboundPlayerActionPacket.Action action, final Direction direction, final int maxBuildHeight, final int sequence) { if (CarpetSettings.antiCheatDisabled && - player.position().add(0, 1.5, 0).distanceToSqr(Vec3.atCenterOf(pos)) < 1024 - ) return pos.getY()-1.0; - return player.getY(); + instance.getEyePosition().distanceToSqr(Vec3.atCenterOf(pos)) < 1024 + ) return Vec3.atCenterOf(pos); + return instance.getEyePosition(); } - - @Redirect(method = "handleBlockBreakAction", at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerPlayer;getZ()D" - )) - private double getZZ(ServerPlayer player, - BlockPos pos, ServerboundPlayerActionPacket.Action action, Direction direction, int worldHeight) - { - if (CarpetSettings.antiCheatDisabled && - player.position().add(0, 1.5, 0).distanceToSqr(Vec3.atCenterOf(pos)) < 1024 - ) return pos.getZ()+0.5; - return player.getZ(); - } - - } diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java index 433ade10..86973741 100644 --- a/src/main/java/carpet/script/api/Auxiliary.java +++ b/src/main/java/carpet/script/api/Auxiliary.java @@ -775,11 +775,11 @@ public class Auxiliary { plopData.put(StringValue.of("configured_features"), ListValue.wrap(registryManager.registryOrThrow(Registry.CONFIGURED_FEATURE_REGISTRY).keySet().stream().sorted().map(ValueConversions::of).collect(Collectors.toList())) ); - plopData.put(StringValue.of("structures"), - ListValue.wrap(Registry.STRUCTURE_FEATURE.keySet().stream().sorted().map(ValueConversions::of).collect(Collectors.toList())) + plopData.put(StringValue.of("structure_types"), + ListValue.wrap(Registry.STRUCTURE_TYPES.keySet().stream().sorted().map(ValueConversions::of).collect(Collectors.toList())) ); - plopData.put(StringValue.of("configured_structures"), - ListValue.wrap(registryManager.registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY).keySet().stream().sorted().map(ValueConversions::of).collect(Collectors.toList())) + plopData.put(StringValue.of("structures"), + ListValue.wrap(registryManager.registryOrThrow(Registry.STRUCTURE_REGISTRY).keySet().stream().sorted().map(ValueConversions::of).collect(Collectors.toList())) ); return MapValue.wrap(plopData); } diff --git a/src/main/java/carpet/script/api/WorldAccess.java b/src/main/java/carpet/script/api/WorldAccess.java index 3f2480eb..1afe3d09 100644 --- a/src/main/java/carpet/script/api/WorldAccess.java +++ b/src/main/java/carpet/script/api/WorldAccess.java @@ -46,6 +46,8 @@ import net.minecraft.core.QuartPos; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; import net.minecraft.tags.TagKey; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureType; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -111,13 +113,10 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.levelgen.WorldgenRandom; -import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; -import net.minecraft.world.level.levelgen.feature.StructureFeature; import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.StructureStart; import net.minecraft.world.level.pathfinder.PathComputationType; @@ -237,11 +236,11 @@ public class WorldAccess { return (float) num; } - private static void BooYah(ChunkGenerator generator) + private static void BooYah(final ServerLevel level) { - synchronized (generator) + synchronized (level) { - ((ChunkGeneratorInterface)generator).initStrongholds(); + ((ChunkGeneratorInterface)level.getChunkSource().getGenerator()).initStrongholds(level); } } @@ -1285,15 +1284,15 @@ public class WorldAccess { BlockArgument locator = BlockArgument.findIn(cc, lv, 0); ServerLevel world = cc.s.getLevel(); BlockPos pos = locator.block.getPos(); - Map, LongSet> references = world.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); - Registry> reg = cc.s.getServer().registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY); + Map references = world.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); + Registry reg = cc.s.getServer().registryAccess().registryOrThrow(Registry.STRUCTURE_REGISTRY); if (lv.size() == locator.offset) return ListValue.wrap(references.entrySet().stream(). filter(e -> e.getValue()!= null && !e.getValue().isEmpty()). map(e -> new StringValue(NBTSerializableValue.nameFromRegistryId(reg.getKey(e.getKey())))).collect(Collectors.toList()) ); String simpleStructureName = lv.get(locator.offset).getString().toLowerCase(Locale.ROOT); - ConfiguredStructureFeature structureName = reg.get(InputValidator.identifierOf(simpleStructureName)); + Structure structureName = reg.get(InputValidator.identifierOf(simpleStructureName)); if (structureName == null) return Value.NULL; LongSet structureReferences = references.get(structureName); if (structureReferences == null || structureReferences.isEmpty()) return ListValue.of(); @@ -1311,13 +1310,13 @@ public class WorldAccess { ServerLevel world = cc.s.getLevel(); // well, because - BooYah(world.getChunkSource().getGenerator()); + BooYah(world); BlockPos pos = locator.block.getPos(); - final List> structure = new ArrayList<>(); + final List structure = new ArrayList<>(); boolean needSize = false; boolean singleOutput = false; - Registry> reg = cc.s.getServer().registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY); + Registry reg = cc.s.getServer().registryAccess().registryOrThrow(Registry.STRUCTURE_REGISTRY); if (lv.size() > locator.offset) { Value requested = lv.get(locator.offset+0); @@ -1325,7 +1324,7 @@ public class WorldAccess { { String reqString = requested.getString(); var id = InputValidator.identifierOf(reqString); - ConfiguredStructureFeature requestedStructure = reg.get(id); + Structure requestedStructure = reg.get(id); if (requestedStructure != null) { singleOutput = true; @@ -1333,10 +1332,8 @@ public class WorldAccess { } else { - Registry> reg1 = cc.s.getServer().registryAccess().registryOrThrow(Registry.STRUCTURE_FEATURE_REGISTRY); - StructureFeature sss = reg1.get(id); - // bad - reg.entrySet().stream().filter(e -> e.getValue().feature==sss).forEach(e -> structure.add(e.getValue())); + StructureType sss = Registry.STRUCTURE_TYPES.get(id); + reg.entrySet().stream().filter(e -> e.getValue().type() ==sss).forEach(e -> structure.add(e.getValue())); } if (structure.isEmpty()) { @@ -1365,7 +1362,7 @@ public class WorldAccess { return ValueConversions.of(start); } Map ret = new HashMap<>(); - for(ConfiguredStructureFeature str: structure) + for(Structure str: structure) { StructureStart start; try @@ -1392,12 +1389,12 @@ public class WorldAccess { ServerLevel world = cc.s.getLevel(); BlockPos pos = locator.block.getPos(); - Map, StructureStart> structures = world.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.STRUCTURE_STARTS).getAllStarts(); - Registry> reg = cc.s.getServer().registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY); + Map structures = world.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.STRUCTURE_STARTS).getAllStarts(); + Registry reg = cc.s.getServer().registryAccess().registryOrThrow(Registry.STRUCTURE_REGISTRY); if (lv.size() == locator.offset) { Map structureList = new HashMap<>(); - for (Map.Entry, StructureStart> entry : structures.entrySet()) + for (Map.Entry entry : structures.entrySet()) { StructureStart start = entry.getValue(); if (start == StructureStart.INVALID_START) @@ -1425,14 +1422,14 @@ public class WorldAccess { if (lv.size() == locator.offset) throw new InternalExpressionException("'set_structure requires at least position and a structure name"); String structureName = lv.get(locator.offset).getString().toLowerCase(Locale.ROOT); - ConfiguredStructureFeature configuredStructure = FeatureGenerator.resolveConfiguredStructure(structureName, world, pos); + Structure configuredStructure = FeatureGenerator.resolveConfiguredStructure(structureName, world, pos); if (configuredStructure == null) throw new ThrowStatement(structureName, Throwables.UNKNOWN_STRUCTURE); // good 'ol pointer Value[] result = new Value[]{Value.NULL}; // technically a world modification. Even if we could let it slide, we will still park it ((CarpetContext) c).s.getServer().executeBlocking(() -> { - Map, StructureStart> structures = world.getChunk(pos).getAllStarts(); + Map structures = world.getChunk(pos).getAllStarts(); if (lv.size() == locator.offset + 1) { Boolean res = FeatureGenerator.plopGrid(configuredStructure, ((CarpetContext) c).s.getLevel(), locator.block.getPos()); @@ -1443,7 +1440,7 @@ public class WorldAccess { Value newValue = lv.get(locator.offset+1); if (newValue.isNull()) // remove structure { - ConfiguredStructureFeature structure = configuredStructure; + Structure structure = configuredStructure; if (!structures.containsKey(structure)) { return; @@ -1457,7 +1454,7 @@ public class WorldAccess { { ChunkPos chpos = new ChunkPos(chx, chz); // getting a chunk will convert it to full, allowing to modify references - Map, LongSet> references = + Map references = world.getChunk(chpos.getWorldPosition()).getAllReferences(); if (references.containsKey(structure) && references.get(structure) != null) references.get(structure).remove(structureChunkPos.toLong()); @@ -1469,7 +1466,7 @@ public class WorldAccess { }); return result[0]; // preventing from lazy evaluating of the result in case a future completes later }); - +/* expression.addContextFunction("custom_dimension", -1, (c, t, lv) -> { if (lv.size() == 0) throw new InternalExpressionException("'custom_dimension' requires at least one argument"); @@ -1496,7 +1493,7 @@ public class WorldAccess { CarpetServer.settingsManager.notifyPlayersCommandsChanged(); return Value.TRUE; }); - +*/ // todo maybe enable chunk blending? expression.addContextFunction("reset_chunk", -1, (c, t, lv) -> { diff --git a/src/main/java/carpet/script/command/CommandArgument.java b/src/main/java/carpet/script/command/CommandArgument.java index b38e4fb7..a8cfa759 100644 --- a/src/main/java/carpet/script/command/CommandArgument.java +++ b/src/main/java/carpet/script/command/CommandArgument.java @@ -54,6 +54,7 @@ import java.util.stream.Collectors; import net.minecraft.ChatFormatting; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.critereon.MinMaxBounds; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.commands.arguments.AngleArgument; @@ -93,6 +94,7 @@ import net.minecraft.commands.synchronization.SuggestionProviders; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; import net.minecraft.network.chat.TextComponent; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -266,7 +268,7 @@ public abstract class CommandArgument new VanillaUnconfigurableArgument("uuid", UuidArgument::uuid, (c, p) -> StringValue.of(UuidArgument.getUuid(c, p).toString()), false ), - new VanillaUnconfigurableArgument("surfacelocation", Vec2Argument::vec2, // vec2 + new VanillaUnconfigurableArgument("surfacelocation", () -> Vec2Argument.vec2(), // vec2 (c, p) -> { Vec2 res = Vec2Argument.getVec2(c, p); return ListValue.of(NumericValue.of(res.x), NumericValue.of(res.y)); @@ -298,10 +300,10 @@ public abstract class CommandArgument public static RequiredArgumentBuilder argumentNode(String param, CarpetScriptHost host) throws CommandSyntaxException { CommandArgument arg = getTypeForArgument(param, host); - if (arg.suggestionProvider != null) return argument(param, arg.getArgumentType()).suggests(arg.suggestionProvider); - if (!arg.needsMatching) return argument(param, arg.getArgumentType()); + if (arg.suggestionProvider != null) return argument(param, arg.getArgumentType(host)).suggests(arg.suggestionProvider); + if (!arg.needsMatching) return argument(param, arg.getArgumentType(host)); String hostName = host.getName(); - return argument(param, arg.getArgumentType()).suggests((ctx, b) -> { + return argument(param, arg.getArgumentType(host)).suggests((ctx, b) -> { CarpetScriptHost cHost = CarpetServer.scriptServer.modules.get(hostName).retrieveOwnForExecution(ctx.getSource()); return arg.suggest(ctx, b, cHost); }); @@ -325,7 +327,7 @@ public abstract class CommandArgument this.needsMatching = suggestFromExamples; } - protected abstract ArgumentType getArgumentType() throws CommandSyntaxException; + protected abstract ArgumentType getArgumentType(CarpetScriptHost host) throws CommandSyntaxException; public static Value getValue(CommandContext context, String param, CarpetScriptHost host) throws CommandSyntaxException @@ -445,7 +447,7 @@ public abstract class CommandArgument } @Override - public ArgumentType getArgumentType() + public ArgumentType getArgumentType(CarpetScriptHost host) { return StringArgumentType.string(); } @@ -490,7 +492,7 @@ public abstract class CommandArgument { private WordArgument() { super(); suffix = "term"; examples = StringArgumentType.StringType.SINGLE_WORD.getExamples(); } @Override - public ArgumentType getArgumentType() { return StringArgumentType.word(); } + public ArgumentType getArgumentType(CarpetScriptHost host) { return StringArgumentType.word(); } @Override protected Supplier factory() { return WordArgument::new; } } @@ -499,7 +501,7 @@ public abstract class CommandArgument { private GreedyStringArgument() { super();suffix = "text"; examples = StringArgumentType.StringType.GREEDY_PHRASE.getExamples(); } @Override - public ArgumentType getArgumentType() { return StringArgumentType.greedyString(); } + public ArgumentType getArgumentType(CarpetScriptHost host) { return StringArgumentType.greedyString(); } @Override protected Supplier factory() { return GreedyStringArgument::new; } } @@ -514,7 +516,7 @@ public abstract class CommandArgument } @Override - public ArgumentType getArgumentType() + public ArgumentType getArgumentType(CarpetScriptHost host) { return net.minecraft.commands.arguments.coordinates.BlockPosArgument.blockPos(); } @@ -552,7 +554,7 @@ public abstract class CommandArgument blockCentered = true; } @Override - protected ArgumentType getArgumentType() + protected ArgumentType getArgumentType(CarpetScriptHost host) { return Vec3Argument.vec3(blockCentered); } @@ -589,7 +591,7 @@ public abstract class CommandArgument single = false; } @Override - protected ArgumentType getArgumentType() + protected ArgumentType getArgumentType(CarpetScriptHost host) { if (onlyFans) { @@ -636,7 +638,7 @@ public abstract class CommandArgument single = false; } @Override - protected ArgumentType getArgumentType() + protected ArgumentType getArgumentType(CarpetScriptHost host) { return GameProfileArgument.gameProfile(); } @@ -677,7 +679,7 @@ public abstract class CommandArgument suggestionProvider = ScoreHolderArgument.SUGGEST_SCORE_HOLDERS; } @Override - protected ArgumentType getArgumentType() + protected ArgumentType getArgumentType(CarpetScriptHost host) { return single?ScoreHolderArgument.scoreHolder():ScoreHolderArgument.scoreHolders(); } @@ -716,7 +718,7 @@ public abstract class CommandArgument mapRequired = true; } @Override - protected ArgumentType getArgumentType() + protected ArgumentType getArgumentType(CarpetScriptHost host) { return mapRequired?CompoundTagArgument.compoundTag(): NbtTagArgument.nbtTag(); } @@ -754,7 +756,7 @@ public abstract class CommandArgument } @Override - protected ArgumentType getArgumentType() + protected ArgumentType getArgumentType(CarpetScriptHost host) { return ResourceLocationArgument.id(); } @@ -799,7 +801,7 @@ public abstract class CommandArgument } @Override - public ArgumentType getArgumentType() + public ArgumentType getArgumentType(CarpetScriptHost host) { if (min != null) { @@ -850,7 +852,7 @@ public abstract class CommandArgument } @Override - public ArgumentType getArgumentType() + public ArgumentType getArgumentType(CarpetScriptHost host) { if (min != null) { @@ -944,7 +946,7 @@ public abstract class CommandArgument } @Override - protected ArgumentType getArgumentType() throws CommandSyntaxException + protected ArgumentType getArgumentType(CarpetScriptHost host) throws CommandSyntaxException { return net.minecraft.commands.arguments.SlotArgument.slot(); } @@ -998,11 +1000,19 @@ public abstract class CommandArgument ArgumentType get() throws CommandSyntaxException; } + @FunctionalInterface + private interface ArgumentProviderEx + { + ArgumentType get(CommandBuildContext regAccess) throws CommandSyntaxException; + } + public static class VanillaUnconfigurableArgument extends CommandArgument { private final ArgumentProvider argumentTypeSupplier; + private final ArgumentProviderEx argumentTypeSupplierEx; private final ValueExtractor valueExtractor; private final boolean providesExamples; + public VanillaUnconfigurableArgument( String suffix, ArgumentProvider argumentTypeSupplier, @@ -1022,6 +1032,7 @@ public abstract class CommandArgument this.providesExamples = suggestFromExamples; this.argumentTypeSupplier = argumentTypeSupplier; this.valueExtractor = valueExtractor; + this.argumentTypeSupplierEx = null; } public VanillaUnconfigurableArgument( String suffix, @@ -1035,12 +1046,38 @@ public abstract class CommandArgument this.providesExamples = false; this.argumentTypeSupplier = argumentTypeSupplier; this.valueExtractor = valueExtractor; + this.argumentTypeSupplierEx = null; + } + public VanillaUnconfigurableArgument( + String suffix, + ArgumentProviderEx argumentTypeSupplier, + ValueExtractor valueExtractor, + boolean suggestFromExamples + ) + { + super(suffix, null, suggestFromExamples); + try + { + final CommandBuildContext context = new CommandBuildContext(RegistryAccess.BUILTIN.get()); + context.missingTagAccessPolicy(CommandBuildContext.MissingTagAccessPolicy.RETURN_EMPTY); + this.examples = argumentTypeSupplier.get(context).getExamples(); + } + catch (CommandSyntaxException e) + { + this.examples = Collections.emptyList(); + } + this.providesExamples = suggestFromExamples; + this.argumentTypeSupplierEx = argumentTypeSupplier; + this.valueExtractor = valueExtractor; + this.argumentTypeSupplier = null; } @Override - protected ArgumentType getArgumentType() throws CommandSyntaxException + protected ArgumentType getArgumentType(CarpetScriptHost host) throws CommandSyntaxException { - return argumentTypeSupplier.get(); + if (argumentTypeSupplier != null) return argumentTypeSupplier.get(); + CommandBuildContext registryAccess = new CommandBuildContext(host.getScriptServer().server.registryAccess()); + return argumentTypeSupplierEx.get(registryAccess); } @Override @@ -1052,7 +1089,8 @@ public abstract class CommandArgument @Override protected Supplier factory() { - return () -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplier, valueExtractor, providesExamples); + if (argumentTypeSupplier != null) return () -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplier, valueExtractor, providesExamples); + return () -> new VanillaUnconfigurableArgument(getTypeSuffix(), argumentTypeSupplierEx, valueExtractor, providesExamples); } } } diff --git a/src/main/java/carpet/script/utils/BiomeInfo.java b/src/main/java/carpet/script/utils/BiomeInfo.java index 2e4663b4..330ec0f5 100644 --- a/src/main/java/carpet/script/utils/BiomeInfo.java +++ b/src/main/java/carpet/script/utils/BiomeInfo.java @@ -8,12 +8,11 @@ import carpet.script.value.StringValue; import carpet.script.value.Value; import carpet.script.value.ValueConversions; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.function.BiFunction; +import java.util.stream.Collectors; import net.minecraft.core.Holder; -import net.minecraft.core.HolderSet; import net.minecraft.core.Registry; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.biome.Biome; @@ -25,7 +24,12 @@ public class BiomeInfo public final static Map> biomeFeatures = new HashMap>(){{ //put("top_material", (w, b) -> new BlockValue( b.getGenerationSettings(). getSurfaceConfig().getTopMaterial(), null, null)); //put("under_material", (w, b) -> new BlockValue( b.getGenerationSettings().getSurfaceConfig().getUnderMaterial(), null, null)); - put("category", (w, b) -> StringValue.of(Biome.getBiomeCategory(Holder.direct(b)).getName())); + //put("category", (w, b) -> StringValue.of(Biome.getBiomeCategory(Holder.direct(b)).getName())); + put("biome_tags", (w, b) -> { + Holder direct = Holder.direct(b); + return ListValue.wrap(w.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getTags().filter(p -> p.getSecond().contains(direct)).map(p -> p.getFirst().location()).map(ValueConversions::of).collect(Collectors.toList())); + }); + put("temperature", (w, b) -> NumericValue.of(b.getBaseTemperature())); put("fog_color", (w, b) -> ValueConversions.ofRGB(b.getSpecialEffects().getFogColor())); put("foliage_color", (w, b) -> ValueConversions.ofRGB(b.getSpecialEffects().getFoliageColorOverride().orElse(4764952))); // client Biome.getDefaultFoliageColor diff --git a/src/main/java/carpet/script/utils/WorldTools.java b/src/main/java/carpet/script/utils/WorldTools.java index f46604a9..f0b2cee0 100644 --- a/src/main/java/carpet/script/utils/WorldTools.java +++ b/src/main/java/carpet/script/utils/WorldTools.java @@ -72,7 +72,7 @@ public class WorldTools catch (IOException ignored) { } return true; } - +/* public static boolean createWorld(MinecraftServer server, String worldKey, Long seed) { ResourceLocation worldId = new ResourceLocation(worldKey); @@ -137,7 +137,7 @@ public class WorldTools overWorld.getWorldBorder().addListener(new BorderChangeListener.DelegateBorderChangeListener(serverWorld.getWorldBorder())); ((MinecraftServerInterface) server).getCMWorlds().put(customWorld, serverWorld); return true; - } + }*/ public static void forceChunkUpdate(BlockPos pos, ServerLevel world) { diff --git a/src/main/java/carpet/script/value/BlockValue.java b/src/main/java/carpet/script/value/BlockValue.java index d8ec6e84..d6ac4898 100644 --- a/src/main/java/carpet/script/value/BlockValue.java +++ b/src/main/java/carpet/script/value/BlockValue.java @@ -18,6 +18,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; import net.minecraft.core.GlobalPos; +import net.minecraft.core.HolderLookup; import net.minecraft.core.Registry; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.StringTag; @@ -59,13 +60,13 @@ public class BlockValue extends Value { BlockValue bv = bvCache.get(str); if (bv != null) return bv; - BlockStateParser blockstateparser = (new BlockStateParser(new StringReader(str), false)).parse(true); - if (blockstateparser.getState() != null) + BlockStateParser.BlockResult foo = BlockStateParser.parseForBlock(HolderLookup.forRegistry(Registry.BLOCK), new StringReader(str), true ); + if (foo.blockState() != null) { - CompoundTag bd = blockstateparser.getNbt(); + CompoundTag bd = foo.nbt(); if (bd == null) bd = new CompoundTag(); - bv = new BlockValue(blockstateparser.getState(), null, null, bd ); + bv = new BlockValue(foo.blockState(), null, null, bd ); if (bvCache.size()>10000) bvCache.clear(); bvCache.put(str, bv); diff --git a/src/main/java/carpet/script/value/NBTSerializableValue.java b/src/main/java/carpet/script/value/NBTSerializableValue.java index 49aedff6..e898a433 100644 --- a/src/main/java/carpet/script/value/NBTSerializableValue.java +++ b/src/main/java/carpet/script/value/NBTSerializableValue.java @@ -22,6 +22,9 @@ import net.minecraft.commands.arguments.NbtPathArgument; import net.minecraft.commands.arguments.item.ItemInput; import net.minecraft.commands.arguments.item.ItemParser; import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.Registry; import net.minecraft.nbt.CollectionTag; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.EndTag; @@ -301,17 +304,17 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa if (customTag == null) return res; else - return new ItemInput(res.getItem(), customTag); + return new ItemInput(Holder.direct(res.getItem()), customTag); + ItemParser.ItemResult parser = ItemParser.parseForItem(HolderLookup.forRegistry(Registry.ITEM), new StringReader(itemString)); + res = new ItemInput(parser.item(), parser.nbt()); - ItemParser parser = (new ItemParser(new StringReader(itemString), false)).parse(); - res = new ItemInput(parser.getItem(), parser.getNbt()); itemCache.put(itemString, res); if (itemCache.size()>64000) itemCache.clear(); if (customTag == null) return res; else - return new ItemInput(res.getItem(), customTag); + return new ItemInput(Holder.direct(res.getItem()), customTag); } catch (CommandSyntaxException e) { diff --git a/src/main/java/carpet/settings/SettingsManager.java b/src/main/java/carpet/settings/SettingsManager.java index f1f490c0..86e8c693 100644 --- a/src/main/java/carpet/settings/SettingsManager.java +++ b/src/main/java/carpet/settings/SettingsManager.java @@ -17,15 +17,16 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import net.fabricmc.api.EnvType; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.SharedSuggestionProvider; +import net.minecraft.core.RegistryAccess; import net.minecraft.network.chat.BaseComponent; import net.minecraft.server.MinecraftServer; import net.minecraft.server.TickTask; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.storage.LevelResource; -import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.util.TriConsumer; import java.io.BufferedReader; @@ -574,12 +575,21 @@ public class SettingsManager return suggestionsBuilder.buildFuture(); } + @Deprecated(forRemoval = true) + public void registerCommand(CommandDispatcher dispatcher) + { + final CommandBuildContext context = new CommandBuildContext(RegistryAccess.BUILTIN.get()); + context.missingTagAccessPolicy(CommandBuildContext.MissingTagAccessPolicy.RETURN_EMPTY); + registerCommand(dispatcher, context); + } + /** - * Registers the the settings command for this {@link SettingsManager}.
+ * Registers the settings command for this {@link SettingsManager}.
* It is handled automatically by Carpet. * @param dispatcher The current {@link CommandDispatcher} + * @param commandBuildContext The current {@link CommandBuildContext} */ - public void registerCommand(CommandDispatcher dispatcher) + public void registerCommand(final CommandDispatcher dispatcher, final CommandBuildContext commandBuildContext) { if (dispatcher.getRoot().getChildren().stream().anyMatch(node -> node.getName().equalsIgnoreCase(identifier))) { diff --git a/src/main/java/carpet/utils/PerimeterDiagnostics.java b/src/main/java/carpet/utils/PerimeterDiagnostics.java index 79a1a029..eed13910 100644 --- a/src/main/java/carpet/utils/PerimeterDiagnostics.java +++ b/src/main/java/carpet/utils/PerimeterDiagnostics.java @@ -159,10 +159,10 @@ public class PerimeterDiagnostics private boolean check_entity_spawn(BlockPos pos) { - if (sle == null || !worldServer.getChunkSource().getGenerator().getMobsAt(worldServer.getBiome(pos), worldServer.structureFeatureManager(), ctype, pos).unwrap().contains(sle)) + if (sle == null || !worldServer.getChunkSource().getGenerator().getMobsAt(worldServer.getBiome(pos), worldServer.structureManager(), ctype, pos).unwrap().contains(sle)) { sle = null; - for (MobSpawnSettings.SpawnerData sle: worldServer.getChunkSource().getGenerator().getMobsAt(worldServer.getBiome(pos), worldServer.structureFeatureManager(), ctype, pos).unwrap()) + for (MobSpawnSettings.SpawnerData sle: worldServer.getChunkSource().getGenerator().getMobsAt(worldServer.getBiome(pos), worldServer.structureManager(), ctype, pos).unwrap()) { if (el.getType() == sle.type) { @@ -170,7 +170,7 @@ public class PerimeterDiagnostics break; } } - if (sle == null || !worldServer.getChunkSource().getGenerator().getMobsAt(worldServer.getBiome(pos), worldServer.structureFeatureManager(), ctype, pos).unwrap().contains(sle)) + if (sle == null || !worldServer.getChunkSource().getGenerator().getMobsAt(worldServer.getBiome(pos), worldServer.structureManager(), ctype, pos).unwrap().contains(sle)) { return false; } diff --git a/src/main/java/carpet/utils/SpawnOverrides.java b/src/main/java/carpet/utils/SpawnOverrides.java index 6e717e4a..391666cb 100644 --- a/src/main/java/carpet/utils/SpawnOverrides.java +++ b/src/main/java/carpet/utils/SpawnOverrides.java @@ -3,22 +3,22 @@ package carpet.utils; import carpet.CarpetSettings; import it.unimi.dsi.fastutil.longs.LongSet; import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.SectionPos; -import net.minecraft.data.worldgen.StructureFeatures; import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.random.WeightedRandomList; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; -import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.StructureManager; import net.minecraft.world.level.biome.MobSpawnSettings; import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; -import net.minecraft.world.level.levelgen.feature.StructureFeature; +import net.minecraft.world.level.levelgen.structure.BuiltinStructures; +import net.minecraft.world.level.levelgen.structure.Structure; import net.minecraft.world.level.levelgen.structure.StructureSpawnOverride; import net.minecraft.world.level.levelgen.structure.StructureStart; +import net.minecraft.world.level.levelgen.structure.StructureType; import org.apache.commons.lang3.tuple.Pair; import java.util.ArrayList; @@ -28,16 +28,16 @@ import java.util.Map; import java.util.function.BooleanSupplier; public class SpawnOverrides { - final private static Map>, Pair> carpetOverrides = new HashMap<>(); + final private static Map>, Pair> carpetOverrides = new HashMap<>(); static { - addOverride(() -> CarpetSettings.huskSpawningInTemples, MobCategory.MONSTER, StructureFeatures.DESERT_PYRAMID, StructureSpawnOverride.BoundingBoxType.STRUCTURE, + addOverride(() -> CarpetSettings.huskSpawningInTemples, MobCategory.MONSTER, BuiltinStructures.DESERT_PYRAMID, StructureSpawnOverride.BoundingBoxType.STRUCTURE, WeightedRandomList.create(new MobSpawnSettings.SpawnerData(EntityType.HUSK, 1, 1, 1)) ); - addOverride(() -> CarpetSettings.shulkerSpawningInEndCities, MobCategory.MONSTER, StructureFeatures.END_CITY, StructureSpawnOverride.BoundingBoxType.PIECE, + addOverride(() -> CarpetSettings.shulkerSpawningInEndCities, MobCategory.MONSTER, BuiltinStructures.END_CITY, StructureSpawnOverride.BoundingBoxType.PIECE, WeightedRandomList.create(new MobSpawnSettings.SpawnerData(EntityType.SHULKER, 10, 4, 4)) ); - addOverride(() -> CarpetSettings.piglinsSpawningInBastions, MobCategory.MONSTER, StructureFeatures.BASTION_REMNANT, StructureSpawnOverride.BoundingBoxType.PIECE, + addOverride(() -> CarpetSettings.piglinsSpawningInBastions, MobCategory.MONSTER, BuiltinStructures.BASTION_REMNANT, StructureSpawnOverride.BoundingBoxType.PIECE, WeightedRandomList.create( new MobSpawnSettings.SpawnerData(EntityType.PIGLIN_BRUTE, 5, 1, 2), new MobSpawnSettings.SpawnerData(EntityType.PIGLIN, 10, 2, 4), @@ -47,14 +47,16 @@ public class SpawnOverrides { } - public static void addOverride(BooleanSupplier when, MobCategory cat, Holder> poo, + public static void addOverride(BooleanSupplier when, MobCategory cat, ResourceKey poo, StructureSpawnOverride.BoundingBoxType type, WeightedRandomList spawns) { - carpetOverrides.put(Pair.of(cat, poo.value().feature), Pair.of(when, new StructureSpawnOverride(type, spawns))); + carpetOverrides.put(Pair.of(cat, poo), Pair.of(when, new StructureSpawnOverride(type, spawns))); } - public static WeightedRandomList test(StructureFeatureManager structureFeatureManager, LongSet foo, - MobCategory cat, ConfiguredStructureFeature confExisting, BlockPos where) { - final Pair spawnData = carpetOverrides.get(Pair.of(cat, confExisting.feature)); + public static WeightedRandomList test(StructureManager structureFeatureManager, LongSet foo, + MobCategory cat, Structure confExisting, BlockPos where) { + ResourceLocation resource = structureFeatureManager.registryAccess().registryOrThrow(Registry.STRUCTURE_REGISTRY).getKey(confExisting); + ResourceKey key = ResourceKey.create(Registry.STRUCTURE_REGISTRY, resource); + final Pair spawnData = carpetOverrides.get(Pair.of(cat, key)); if (spawnData == null || !spawnData.getKey().getAsBoolean()) return null; StructureSpawnOverride override = spawnData.getRight(); if (override.boundingBox() == StructureSpawnOverride.BoundingBoxType.STRUCTURE) { @@ -62,7 +64,7 @@ public class SpawnOverrides { return override.spawns(); } else { List starts = new ArrayList<>(1); - structureFeatureManager.fillStartsForFeature(confExisting, foo, starts::add); + structureFeatureManager.fillStartsForStructure(confExisting, foo, starts::add); for (StructureStart start : starts) { if (start != null && start.isValid() && structureFeatureManager.structureHasPieceAt(where, start)) { return override.spawns(); @@ -72,16 +74,16 @@ public class SpawnOverrides { return null; } - public static boolean isStructureAtPosition(ServerLevel level, ResourceKey> structureKey, BlockPos pos) + public static boolean isStructureAtPosition(ServerLevel level, ResourceKey structureKey, BlockPos pos) { - final ConfiguredStructureFeature fortressFeature = level.registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY).get(structureKey); + final Structure fortressFeature = level.registryAccess().registryOrThrow(Registry.STRUCTURE_REGISTRY).get(structureKey); if (fortressFeature == null) { return false; } - return level.structureFeatureManager().getStructureAt(pos, fortressFeature).isValid(); + return level.structureManager().getStructureAt(pos, fortressFeature).isValid(); } - public static boolean isStructureAtPosition(ServerLevel level, StructureFeature structure, BlockPos pos) + public static boolean isStructureAtPosition(ServerLevel level, StructureType structure, BlockPos pos) { for(StructureStart structureStart : startsForFeature(level, SectionPos.of(pos), structure)) { if (structureStart.getBoundingBox().isInside(pos) && structureStart.isValid()) { @@ -91,15 +93,15 @@ public class SpawnOverrides { return false; } - public static List startsForFeature(ServerLevel level, SectionPos sectionPos, StructureFeature structure) { - Map, LongSet> allrefs = level.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); + public static List startsForFeature(ServerLevel level, SectionPos sectionPos, StructureType structure) { + Map allrefs = level.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.STRUCTURE_REFERENCES).getAllReferences(); List result = new ArrayList<>(); for (var entry: allrefs.entrySet()) { - ConfiguredStructureFeature existing = entry.getKey(); - if (existing.feature == structure) + Structure existing = entry.getKey(); + if (existing.type() == structure) { - level.structureFeatureManager().fillStartsForFeature(existing, entry.getValue(), result::add); + level.structureManager().fillStartsForStructure(existing, entry.getValue(), result::add); } } return result; diff --git a/src/main/java/carpet/utils/SpawnReporter.java b/src/main/java/carpet/utils/SpawnReporter.java index 12d96bb5..5c6aecf5 100644 --- a/src/main/java/carpet/utils/SpawnReporter.java +++ b/src/main/java/carpet/utils/SpawnReporter.java @@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.objects.Object2LongMap; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; +import net.minecraft.core.Registry; import net.minecraft.network.chat.BaseComponent; import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; @@ -23,7 +24,7 @@ import net.minecraft.world.entity.animal.Ocelot; import net.minecraft.world.item.DyeColor; import net.minecraft.world.level.Level; import net.minecraft.world.level.NaturalSpawner; -import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.StructureManager; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.MobSpawnSettings; import net.minecraft.world.level.block.Blocks; @@ -32,8 +33,11 @@ import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.entity.EntityTypeTest; import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.feature.NetherFortressFeature; +import net.minecraft.world.level.levelgen.structure.BuiltinStructures; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.structures.NetherFortressStructure; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.HashMap; @@ -422,11 +426,17 @@ public class SpawnReporter } // yeeted from NaturalSpawner - temporary access fix - private static List getSpawnEntries(final ServerLevel level, final StructureFeatureManager structureFeatureManager, final ChunkGenerator generator, final MobCategory mobCategory, final BlockPos pos, final Holder biome) { - if (NaturalSpawner.isInNetherFortressBounds (pos, level, mobCategory, structureFeatureManager)) { - return NetherFortressFeature.FORTRESS_ENEMIES.unwrap(); + private static List getSpawnEntries(ServerLevel serverLevel, StructureManager structureManager, ChunkGenerator chunkGenerator, MobCategory mobCategory, BlockPos blockPos, @Nullable Holder holder) { + return isInNetherFortressBounds(blockPos, serverLevel, mobCategory, structureManager) ? NetherFortressStructure.FORTRESS_ENEMIES.unwrap() : chunkGenerator.getMobsAt(holder != null ? holder : serverLevel.getBiome(blockPos), structureManager, mobCategory, blockPos).unwrap(); + } + + public static boolean isInNetherFortressBounds(BlockPos blockPos, ServerLevel serverLevel, MobCategory mobCategory, StructureManager structureManager) { + if (mobCategory == MobCategory.MONSTER && serverLevel.getBlockState(blockPos.below()).is(Blocks.NETHER_BRICKS)) { + Structure structure = (Structure)structureManager.registryAccess().registryOrThrow(Registry.STRUCTURE_REGISTRY).get(BuiltinStructures.FORTRESS); + return structure == null ? false : structureManager.getStructureAt(blockPos, structure).isValid(); + } else { + return false; } - return generator.getMobsAt(biome != null ? biome : level.getBiome(pos), structureFeatureManager, mobCategory, pos).unwrap(); } public static List report(BlockPos pos, ServerLevel worldIn) @@ -442,7 +452,7 @@ public class SpawnReporter for (MobCategory enumcreaturetype : MobCategory.values()) { String type_code = String.format("%s", enumcreaturetype).substring(0, 3); - List lst = getSpawnEntries(worldIn, worldIn.structureFeatureManager(), worldIn.getChunkSource().getGenerator(), enumcreaturetype, pos, worldIn.getBiome(pos) );// ((ChunkGenerator)worldIn.getChunkManager().getChunkGenerator()).getEntitySpawnList(, worldIn.getStructureAccessor(), enumcreaturetype, pos); + List lst = getSpawnEntries(worldIn, worldIn.structureManager(), worldIn.getChunkSource().getGenerator(), enumcreaturetype, pos, worldIn.getBiome(pos) );// ((ChunkGenerator)worldIn.getChunkManager().getChunkGenerator()).getEntitySpawnList(, worldIn.getStructureAccessor(), enumcreaturetype, pos); if (lst != null && !lst.isEmpty()) { for (MobSpawnSettings.SpawnerData spawnEntry : lst) diff --git a/src/main/resources/assets/carpet/scripts/overlay.sc b/src/main/resources/assets/carpet/scripts/overlay.sc index f6313a84..ed05761e 100644 --- a/src/main/resources/assets/carpet/scripts/overlay.sc +++ b/src/main/resources/assets/carpet/scripts/overlay.sc @@ -44,7 +44,7 @@ __config() -> 'clear' -> 'clear', }, 'arguments' -> { - 'structure' -> {'type' -> 'term', 'suggest' -> plop():'configured_structures' }, + 'structure' -> {'type' -> 'term', 'suggest' -> plop():'structures' }, 'radius' -> {'type' -> 'int', 'min' -> 0, 'max' -> 1024, 'suggest' -> [128, 24, 32]}, 'shape' -> {'type' -> 'term', 'options' -> keys(global_shapes) }, 'color' -> {'type' -> 'teamcolor'} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 4e037ea4..f2c1084d 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -32,7 +32,7 @@ "accessWidener" : "carpet.accesswidener", "depends": { - "minecraft": "1.18.x", + "minecraft": "1.19.*", "fabricloader": ">=0.12.8", "java": ">=17" }