diff --git a/src/main/java/astrinox/stellum/Stellum.java b/src/main/java/astrinox/stellum/Stellum.java index 24a3838..7e3c75a 100644 --- a/src/main/java/astrinox/stellum/Stellum.java +++ b/src/main/java/astrinox/stellum/Stellum.java @@ -2,11 +2,14 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; +import net.fabricmc.fabric.api.resource.ResourceManagerHelper; +import net.minecraft.resource.ResourceType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import astrinox.stellum.command.DebugCommand; +import astrinox.stellum.command.StellumDebugCommand; +import astrinox.stellum.resource.StellumResourceReloadListener; public class Stellum implements ModInitializer { public static final String MOD_ID = "stellum"; @@ -16,6 +19,7 @@ public class Stellum implements ModInitializer { public void onInitialize() { LOGGER.info("✨"); - CommandRegistrationCallback.EVENT.register(DebugCommand::register); + CommandRegistrationCallback.EVENT.register(StellumDebugCommand::register); + ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new StellumResourceReloadListener()); } } \ No newline at end of file diff --git a/src/main/java/astrinox/stellum/command/DebugCommand.java b/src/main/java/astrinox/stellum/command/DebugCommand.java deleted file mode 100644 index 6775459..0000000 --- a/src/main/java/astrinox/stellum/command/DebugCommand.java +++ /dev/null @@ -1,115 +0,0 @@ -package astrinox.stellum.command; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.arguments.BoolArgumentType; -import com.mojang.brigadier.arguments.DoubleArgumentType; -import com.mojang.brigadier.arguments.FloatArgumentType; -import com.mojang.brigadier.arguments.IntegerArgumentType; -import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; - -import astrinox.stellum.handlers.explosion.ExplosionHandler; -import astrinox.stellum.handlers.screenshake.Screenshake; -import astrinox.stellum.handlers.screenshake.ScreenshakeHandler; -import astrinox.stellum.util.PerlinNoiseHelper; -import net.minecraft.block.Blocks; -import net.minecraft.command.CommandRegistryAccess; -import net.minecraft.server.command.CommandManager; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.Text; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -import static net.minecraft.server.command.CommandManager.*; - -public class DebugCommand { - public static final SimpleCommandExceptionType NON_PLAYER = new SimpleCommandExceptionType( - Text.literal("This command can only be used by players")); - - public static void register(CommandDispatcher serverCommandSourceDispatcher, - CommandRegistryAccess commandRegistryAccess, - CommandManager.RegistrationEnvironment registrationEnvironment) { - serverCommandSourceDispatcher.register(literal("stellum") - .then(literal("debug") - .requires(source -> source.hasPermissionLevel(2)) - .then(literal("screenshake") - .then(argument("intensity", - FloatArgumentType.floatArg()) - .then(argument("durationMs", - IntegerArgumentType - .integer()) - .then(argument("fade", - BoolArgumentType.bool()) - .executes(DebugCommand::executeScreenshake))))) - .then(literal("noise").then(argument("size", IntegerArgumentType.integer()) - .then(argument("noiseScale", DoubleArgumentType.doubleArg()) - .then(argument("seed", IntegerArgumentType.integer()) - .executes(DebugCommand::executeNoise))))) - .then(literal("explosion") - .then(argument("size", IntegerArgumentType.integer()) - .then(argument("noiseScale", DoubleArgumentType.doubleArg()) - .then(argument("noiseMultiplier", FloatArgumentType.floatArg()) - .then(argument("damage", FloatArgumentType.floatArg()) - .executes( - DebugCommand::executeExplosion)))))))); - } - - public static int executeScreenshake(CommandContext context) - throws CommandSyntaxException { - ServerCommandSource source = context.getSource(); - if (!(source.getEntity().isPlayer())) { - throw NON_PLAYER.create(); - } - float intensity = context.getArgument("intensity", float.class); - int durationMs = context.getArgument("durationMs", int.class); - boolean fade = context.getArgument("fade", boolean.class); - ScreenshakeHandler.addScreenshake(new Screenshake(intensity, durationMs, fade)); - return 1; - } - - public static int executeNoise(CommandContext context) throws CommandSyntaxException { - ServerCommandSource source = context.getSource(); - World world = source.getWorld(); - double x = source.getPosition().x; - double y = source.getPosition().y; - double z = source.getPosition().z; - PerlinNoiseHelper noise = new PerlinNoiseHelper(context.getArgument("seed", int.class), - context.getArgument("noiseScale", double.class)); - int size = context.getArgument("size", int.class); - for (int i = 0; i < size; i++) { - for (int j = 0; j < size; j++) { - for (int k = 0; k < size; k++) { - if (noise.noise(x + i, y + j, z + k) > 0) { - world.setBlockState(new BlockPos((int) x + i, (int) y + j, (int) z + k), - Blocks.STONE.getDefaultState()); - } - } - } - } - return 1; - } - - public static int executeExplosion(CommandContext context) throws CommandSyntaxException { - ServerCommandSource source = context.getSource(); - World world = source.getWorld(); - double noiseScale = context.getArgument("noiseScale", double.class); - float noiseMultiplier = context.getArgument("noiseMultiplier", float.class); - - ExplosionHandler explosion = new ExplosionHandler() - .setPos(new BlockPos( - (int) source.getPosition().x, - (int) source.getPosition().y, - (int) source.getPosition().z)) - .setSize(context.getArgument("size", int.class)) - .setNoiseScale(noiseScale) - .setNoiseMultiplier(noiseMultiplier) - .setHurtEntities(true) - .setBreakBlocks(true) - .setDamage(context.getArgument("damage", float.class)); - - explosion.trigger(world); - - return 1; - } -} diff --git a/src/main/java/astrinox/stellum/command/StellumDebugCommand.java b/src/main/java/astrinox/stellum/command/StellumDebugCommand.java new file mode 100644 index 0000000..290b855 --- /dev/null +++ b/src/main/java/astrinox/stellum/command/StellumDebugCommand.java @@ -0,0 +1,271 @@ +package astrinox.stellum.command; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.DoubleArgumentType; +import com.mojang.brigadier.arguments.FloatArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; + +import astrinox.stellum.handlers.explosion.BurnMap; +import astrinox.stellum.handlers.explosion.BurnZone; +import astrinox.stellum.handlers.explosion.Burnable; +import astrinox.stellum.handlers.explosion.BurnableIO; +import astrinox.stellum.handlers.explosion.ExplosionHandler; +import astrinox.stellum.handlers.screenshake.Screenshake; +import astrinox.stellum.handlers.screenshake.ScreenshakeHandler; +import astrinox.stellum.util.PerlinNoiseHelper; +import net.minecraft.block.Blocks; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.registry.tag.BlockTags; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.state.property.Properties; +import net.minecraft.text.Text; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import static net.minecraft.server.command.CommandManager.*; + +public class StellumDebugCommand { + public static final SimpleCommandExceptionType NON_PLAYER = new SimpleCommandExceptionType( + Text.literal("This command can only be used by players")); + + public static void register(CommandDispatcher serverCommandSourceDispatcher, + CommandRegistryAccess commandRegistryAccess, + CommandManager.RegistrationEnvironment registrationEnvironment) { + serverCommandSourceDispatcher.register(literal("stellum") + .then(literal("debug") + .requires(source -> source.hasPermissionLevel(2)) + .then(literal("screenshake") + .then(argument("intensity", + FloatArgumentType.floatArg()) + .then(argument("durationMs", + IntegerArgumentType + .integer()) + .then(argument("fade", + BoolArgumentType.bool()) + .executes(StellumDebugCommand::executeScreenshake))))) + .then(literal("noise").then(argument("size", + IntegerArgumentType.integer()) + .then(argument("noiseScale", + DoubleArgumentType.doubleArg()) + .then(argument("seed", + IntegerArgumentType + .integer()) + .executes(StellumDebugCommand::executeNoise))))) + .then(literal("explosion") + .then(argument("size", IntegerArgumentType.integer()) + .then(argument("noiseScale", + DoubleArgumentType + .doubleArg()) + .then(argument("noiseMultiplier", + FloatArgumentType + .floatArg()) + .then(argument("damage", + FloatArgumentType + .floatArg()) + .then(argument("burnBlocks", + BoolArgumentType.bool()) + .then(argument("burnSize", + IntegerArgumentType + .integer()) + .executes( + StellumDebugCommand::executeExplosion)))))))) + .then(literal("burnzone") + .then(argument("size", IntegerArgumentType.integer()) + .then(argument("explosionSize", + IntegerArgumentType + .integer()) + .then(argument("noiseScale", + DoubleArgumentType + .doubleArg()) + .then(argument("noiseMultiplier", + FloatArgumentType + .floatArg()) + .executes( + StellumDebugCommand::executeBurnzone)))))))); + } + + public static int executeScreenshake(CommandContext context) + throws CommandSyntaxException { + ServerCommandSource source = context.getSource(); + if (!(source.getEntity().isPlayer())) { + throw NON_PLAYER.create(); + } + float intensity = context.getArgument("intensity", float.class); + int durationMs = context.getArgument("durationMs", int.class); + boolean fade = context.getArgument("fade", boolean.class); + ScreenshakeHandler.addScreenshake(new Screenshake(intensity, durationMs, fade)); + return 1; + } + + public static int executeNoise(CommandContext context) throws CommandSyntaxException { + ServerCommandSource source = context.getSource(); + World world = source.getWorld(); + double x = source.getPosition().x; + double y = source.getPosition().y; + double z = source.getPosition().z; + PerlinNoiseHelper noise = new PerlinNoiseHelper(context.getArgument("seed", int.class), + context.getArgument("noiseScale", double.class)); + int size = context.getArgument("size", int.class); + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + for (int k = 0; k < size; k++) { + if (noise.noise(x + i, y + j, z + k) > 0) { + world.setBlockState(new BlockPos((int) x + i, (int) y + j, (int) z + k), + Blocks.STONE.getDefaultState()); + } + } + } + } + return 1; + } + + public static int executeExplosion(CommandContext context) throws CommandSyntaxException { + ServerCommandSource source = context.getSource(); + World world = source.getWorld(); + double noiseScale = context.getArgument("noiseScale", double.class); + float noiseMultiplier = context.getArgument("noiseMultiplier", float.class); + + BurnMap burnMap = new BurnMap() + .addBurnables( + new BurnableIO( + new Burnable().addTag(BlockTags.LEAVES), + new Burnable().addBlock(Blocks.MANGROVE_ROOTS + .getDefaultState()))) + .addBurnables( + new BurnableIO( + new Burnable().addTag(BlockTags.BASE_STONE_OVERWORLD), + new Burnable().addBlock( + Blocks.COBBLESTONE.getDefaultState()) + .addBlock(Blocks.COBBLED_DEEPSLATE + .getDefaultState()) + .addBlock(Blocks.MAGMA_BLOCK + .getDefaultState()))) + .addBurnables( + new BurnableIO( + new Burnable().addTag(BlockTags.LOGS), + new Burnable().addBlock(Blocks.POLISHED_BASALT + .getDefaultState()))) + .addBurnables( + new BurnableIO( + new Burnable().addTag(BlockTags.DIRT), + new Burnable().addBlock(Blocks.DEAD_FIRE_CORAL_BLOCK + .getDefaultState()) + .addBlock(Blocks.COARSE_DIRT + .getDefaultState()) + .addBlock(Blocks.MAGMA_BLOCK + .getDefaultState()))) + .addBurnables( + new BurnableIO( + new Burnable().addTag(BlockTags.FLOWERS) + .addBlock(Blocks.SHORT_GRASS + .getDefaultState()) + .addBlock(Blocks.TALL_GRASS + .getDefaultState()), + new Burnable() + .addBlock(Blocks.DEAD_BUBBLE_CORAL + .getDefaultState() + .with(Properties.WATERLOGGED, + false)) + .addBlock(Blocks.DEAD_BUSH + .getDefaultState()))); + + ExplosionHandler explosion = new ExplosionHandler() + .setPos(new BlockPos( + (int) source.getPosition().x, + (int) source.getPosition().y, + (int) source.getPosition().z)) + .setSize(context.getArgument("size", int.class)) + .setNoiseScale(noiseScale) + .setNoiseMultiplier(noiseMultiplier) + .setHurtEntities(true) + .setBreakBlocks(true) + .setDamage(context.getArgument("damage", float.class)) + .setBurnBlocks(context.getArgument("burnBlocks", boolean.class)) + .setBurnSize(context.getArgument("burnSize", int.class)) + .setBurnMap(burnMap); + + explosion.trigger(world); + + return 1; + } + + public static int executeBurnzone(CommandContext context) throws CommandSyntaxException { + ServerCommandSource source = context.getSource(); + try { + World world = source.getWorld(); + double noiseScale = context.getArgument("noiseScale", double.class); + float noiseMultiplier = context.getArgument("noiseMultiplier", float.class); + int size = context.getArgument("size", int.class); + int explosionSize = context.getArgument("explosionSize", int.class); + + BurnMap burnMap = new BurnMap() + .addBurnables( + new BurnableIO( + new Burnable().addTag(BlockTags.LEAVES), + new Burnable().addBlock(Blocks.MANGROVE_ROOTS + .getDefaultState()))) + .addBurnables( + new BurnableIO( + new Burnable().addTag( + BlockTags.BASE_STONE_OVERWORLD), + new Burnable().addBlock(Blocks.COBBLESTONE + .getDefaultState()) + .addBlock(Blocks.COBBLED_DEEPSLATE + .getDefaultState()) + .addBlock(Blocks.MAGMA_BLOCK + .getDefaultState()))) + .addBurnables( + new BurnableIO( + new Burnable().addTag(BlockTags.LOGS), + new Burnable().addBlock(Blocks.POLISHED_BASALT + .getDefaultState()))) + .addBurnables( + new BurnableIO( + new Burnable().addTag(BlockTags.DIRT), + new Burnable().addBlock( + Blocks.DEAD_FIRE_CORAL_BLOCK + .getDefaultState()) + .addBlock(Blocks.COARSE_DIRT + .getDefaultState()) + .addBlock(Blocks.MAGMA_BLOCK + .getDefaultState()))) + .addBurnables( + new BurnableIO( + new Burnable().addTag(BlockTags.FLOWERS) + .addBlock(Blocks.SHORT_GRASS + .getDefaultState()) + .addBlock(Blocks.TALL_GRASS + .getDefaultState()), + new Burnable() + .addBlock(Blocks.DEAD_BUBBLE_CORAL + .getDefaultState() + .with(Properties.WATERLOGGED, + false)) + .addBlock(Blocks.DEAD_BUSH + .getDefaultState()))); + + BurnZone burnzone = new BurnZone() + .setPos(new BlockPos( + (int) source.getPosition().x, + (int) source.getPosition().y, + (int) source.getPosition().z)) + .setSize(size) + .setExplosionSize(explosionSize) + .setNoiseScale(noiseScale) + .setNoiseMultiplier(noiseMultiplier) + .setBurnMap(burnMap); + + burnzone.trigger(world); + } catch (Exception e) { + source.sendError(Text.literal( + "An error occurred while executing the burnzone command: " + e.getMessage())); + } + + return 1; + } +} diff --git a/src/main/java/astrinox/stellum/handlers/explosion/BurnMap.java b/src/main/java/astrinox/stellum/handlers/explosion/BurnMap.java new file mode 100644 index 0000000..d90be02 --- /dev/null +++ b/src/main/java/astrinox/stellum/handlers/explosion/BurnMap.java @@ -0,0 +1,43 @@ +package astrinox.stellum.handlers.explosion; + +import java.util.ArrayList; +import java.util.Random; + +import net.minecraft.block.BlockState; +import net.minecraft.state.property.Property; + +public class BurnMap { + ArrayList burnMap = new ArrayList<>(); + + public BurnMap addBurnables(BurnableIO burnable) { + burnMap.add(burnable); + return this; + } + + public ArrayList getBurnMap() { + return burnMap; + } + + private > BlockState applyProperty(BlockState state, Property property, + Comparable value) { + return state.with(property, property.getType().cast(value)); + } + + public BlockState getOutput(BlockState state) { + BlockState outputState = state; + for (BurnableIO burnable : burnMap) { + if (burnable.getIn().getPossibleBlockStates().contains(state.getBlock().getDefaultState())) { + outputState = burnable.getOut().getPossibleBlockStates() + .get(new Random().nextInt(burnable.getOut().getPossibleBlockStates().size())); + + for (Property property : state.getProperties()) { + if (outputState.getProperties().contains(property)) { + outputState = applyProperty(outputState, property, state.get(property)); + } + } + return outputState; + } + } + return outputState; + } +} diff --git a/src/main/java/astrinox/stellum/handlers/explosion/BurnZone.java b/src/main/java/astrinox/stellum/handlers/explosion/BurnZone.java new file mode 100644 index 0000000..12063dc --- /dev/null +++ b/src/main/java/astrinox/stellum/handlers/explosion/BurnZone.java @@ -0,0 +1,100 @@ +package astrinox.stellum.handlers.explosion; + +import java.util.Random; +import java.util.function.Function; + +import astrinox.stellum.util.EasingHelper; +import astrinox.stellum.util.MathHelper; +import astrinox.stellum.util.PerlinNoiseHelper; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockPos.Mutable; +import net.minecraft.world.World; + +public class BurnZone { + private BlockPos pos = new BlockPos(0, 0, 0); + private int size = 10; + private int explosionSize = 16; + private double noiseScale = 0.3; + private float noiseMultiplier = 100; + private BurnMap burnMap; + private Function falloffFunction = EasingHelper::easeInSine; + + public BurnZone setPos(BlockPos pos) { + this.pos = pos; + return this; + } + + public BurnZone setSize(int size) { + this.size = size; + return this; + } + + public BurnZone setExplosionSize(int explosionSize) { + this.explosionSize = explosionSize; + return this; + } + + public BurnZone setNoiseScale(double noiseScale) { + this.noiseScale = noiseScale; + return this; + } + + public BurnZone setNoiseMultiplier(float noiseMultiplier) { + this.noiseMultiplier = noiseMultiplier; + return this; + } + + public BurnZone setBurnMap(BurnMap burnMap) { + this.burnMap = burnMap; + return this; + } + + public BurnZone setFalloffFunction(Function falloffFunction) { + this.falloffFunction = falloffFunction; + return this; + } + + public void trigger(World world) { + int trueSize = size + explosionSize; + int trueSizeSquared = trueSize * trueSize; + int explosionSizeSquared = explosionSize * explosionSize; + Mutable blockPos = new Mutable(); + PerlinNoiseHelper noise = new PerlinNoiseHelper(new Random().nextLong(), noiseScale); + + for (int y = pos.getY() + trueSize; y >= pos.getY() - trueSize; y--) { + for (int x = pos.getX() - trueSize; x <= pos.getX() + trueSize; x++) { + for (int z = pos.getZ() - trueSize; z <= pos.getZ() + trueSize; z++) { + int dx = x - pos.getX(); + int dy = y - pos.getY(); + int dz = z - pos.getZ(); + + int distanceSquared = dx * dx + dy * dy + dz * dz; + + double noisePoint = noise.noise(x, y, z) * noiseMultiplier; + + if (distanceSquared <= trueSizeSquared + noisePoint) { + blockPos.set(x, y, z); + if (distanceSquared >= explosionSizeSquared + noisePoint) { + double percent = MathHelper.map(distanceSquared, explosionSizeSquared, trueSizeSquared, 1, + 0); + if (falloffFunction != null) { + percent = falloffFunction.apply(percent); + } + if (Math.random() < percent) { + if (burnMap != null) { + world.setBlockState(blockPos, burnMap.getOutput(world.getBlockState(blockPos)), + 0b01100010); + } + } + } else { + if (burnMap != null) { + world.setBlockState(blockPos, burnMap.getOutput(world.getBlockState(blockPos)), + 0b01100010); + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/astrinox/stellum/handlers/explosion/Burnable.java b/src/main/java/astrinox/stellum/handlers/explosion/Burnable.java new file mode 100644 index 0000000..65aed44 --- /dev/null +++ b/src/main/java/astrinox/stellum/handlers/explosion/Burnable.java @@ -0,0 +1,26 @@ +package astrinox.stellum.handlers.explosion; + +import java.util.ArrayList; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.registry.Registries; +import net.minecraft.registry.tag.TagKey; + +public class Burnable { + private ArrayList blocks = new ArrayList<>(); + + public Burnable addBlock(BlockState block) { + blocks.add(block); + return this; + } + + public Burnable addTag(TagKey tag) { + Registries.BLOCK.iterateEntries(tag).forEach((block) -> blocks.add(block.comp_349().getDefaultState())); + return this; + } + + public ArrayList getPossibleBlockStates() { + return blocks; + } +} diff --git a/src/main/java/astrinox/stellum/handlers/explosion/BurnableIO.java b/src/main/java/astrinox/stellum/handlers/explosion/BurnableIO.java new file mode 100644 index 0000000..4f70016 --- /dev/null +++ b/src/main/java/astrinox/stellum/handlers/explosion/BurnableIO.java @@ -0,0 +1,30 @@ +package astrinox.stellum.handlers.explosion; + +import java.util.Random; + +import net.minecraft.block.BlockState; + +public class BurnableIO { + private Burnable in; + private Burnable out; + + public BurnableIO(Burnable in, Burnable out) { + this.in = in; + this.out = out; + } + + public BlockState getOutput(BlockState state) { + if (in.getPossibleBlockStates().contains(state)) { + return out.getPossibleBlockStates().get(new Random().nextInt(out.getPossibleBlockStates().size())); + } + return state; + } + + public Burnable getIn() { + return in; + } + + public Burnable getOut() { + return out; + } +} diff --git a/src/main/java/astrinox/stellum/handlers/explosion/ExplosionHandler.java b/src/main/java/astrinox/stellum/handlers/explosion/ExplosionHandler.java index e7355e2..5e2b153 100644 --- a/src/main/java/astrinox/stellum/handlers/explosion/ExplosionHandler.java +++ b/src/main/java/astrinox/stellum/handlers/explosion/ExplosionHandler.java @@ -2,7 +2,9 @@ import java.util.List; import java.util.Random; +import java.util.function.Function; +import astrinox.stellum.util.EasingHelper; import astrinox.stellum.util.PerlinNoiseHelper; import net.minecraft.block.Blocks; import net.minecraft.entity.LivingEntity; @@ -19,6 +21,10 @@ public class ExplosionHandler { private boolean breakBlocks = true; private boolean hurtEntities = true; private float damage = 10; + private boolean burnBlocks = false; + private BurnMap burnMap; + private int burnSize; + private Function burnFalloffFunction = (Double x) -> EasingHelper.easeInSine(x); public ExplosionHandler setPos(BlockPos pos) { this.pos = pos; @@ -55,13 +61,33 @@ public ExplosionHandler setDamage(float damage) { return this; } + public ExplosionHandler setBurnBlocks(boolean burnBlocks) { + this.burnBlocks = burnBlocks; + return this; + } + + public ExplosionHandler setBurnMap(BurnMap burnMap) { + this.burnMap = burnMap; + return this; + } + + public ExplosionHandler setBurnSize(int burnSize) { + this.burnSize = burnSize; + return this; + } + + public ExplosionHandler setBurnFalloffFunction(Function burnFalloffFunction) { + this.burnFalloffFunction = burnFalloffFunction; + return this; + } + public void trigger(World world) { int sizeSquared = size * size; Mutable blockPos = new Mutable(); - PerlinNoiseHelper mainNoise = new PerlinNoiseHelper(new Random().nextLong(), noiseScale); + PerlinNoiseHelper noise = new PerlinNoiseHelper(new Random().nextLong(), noiseScale); - for (int x = pos.getX() - size; x <= pos.getX() + size; x++) { - for (int y = pos.getY() - size; y <= pos.getY() + size; y++) { + for (int y = pos.getY() + size; y >= pos.getY() - size; y--) { + for (int x = pos.getX() - size; x <= pos.getX() + size; x++) { for (int z = pos.getZ() - size; z <= pos.getZ() + size; z++) { int dx = x - pos.getX(); int dy = y - pos.getY(); @@ -69,10 +95,10 @@ public void trigger(World world) { int distanceSquared = dx * dx + dy * dy + dz * dz; - if (distanceSquared <= sizeSquared + mainNoise.noise(x, y, z) * noiseMultiplier) { + if (distanceSquared <= sizeSquared + noise.noise(x, y, z) * noiseMultiplier) { blockPos.set(x, y, z); if (breakBlocks) { - world.setBlockState(blockPos, Blocks.AIR.getDefaultState()); + world.setBlockState(blockPos, Blocks.AIR.getDefaultState(), 0b01100010); } if (hurtEntities) { Box box = new Box(x - 0.5, y - 0.5, z - 0.5, x + 0.5, y + 0.5, z + 0.5); @@ -87,7 +113,18 @@ public void trigger(World world) { } } - // TODO: Add effects pass, for things like fire and scorching + if (burnBlocks) { + BurnZone burnZone = new BurnZone() + .setPos(pos) + .setSize(burnSize) + .setExplosionSize(size) + .setNoiseScale(noiseScale) + .setNoiseMultiplier(noiseMultiplier) + .setBurnMap(burnMap) + .setFalloffFunction(burnFalloffFunction == null ? EasingHelper::easeInSine : burnFalloffFunction); + + burnZone.trigger(world); + } } } diff --git a/src/main/java/astrinox/stellum/registry/BurnMapRegistry.java b/src/main/java/astrinox/stellum/registry/BurnMapRegistry.java new file mode 100644 index 0000000..42d3bf1 --- /dev/null +++ b/src/main/java/astrinox/stellum/registry/BurnMapRegistry.java @@ -0,0 +1,22 @@ +package astrinox.stellum.registry; + +import java.util.HashMap; +import java.util.Map; + +import astrinox.stellum.handlers.explosion.BurnMap; + +public class BurnMapRegistry { + private static final Map burnMapRegistry = new HashMap<>(); + + public static void registerBurnMap(String id, BurnMap burnMap) { + burnMapRegistry.put(id, burnMap); + } + + public static BurnMap getBurnMap(String id) { + return burnMapRegistry.get(id); + } + + public static void clear() { + burnMapRegistry.clear(); + } +} \ No newline at end of file diff --git a/src/main/java/astrinox/stellum/resource/StellumResourceReloadListener.java b/src/main/java/astrinox/stellum/resource/StellumResourceReloadListener.java new file mode 100644 index 0000000..9a3f36f --- /dev/null +++ b/src/main/java/astrinox/stellum/resource/StellumResourceReloadListener.java @@ -0,0 +1,35 @@ +package astrinox.stellum.resource; + +import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; +import net.minecraft.resource.ResourceManager; +import net.minecraft.util.Identifier; + +import java.io.InputStream; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import astrinox.stellum.Stellum; + +public class StellumResourceReloadListener implements SimpleSynchronousResourceReloadListener { + + @Override + public Identifier getFabricId() { + return Identifier.of(Stellum.MOD_ID, "stellum_resources"); + } + + @Override + public void reload(ResourceManager manager) { + Stellum.LOGGER.info("Reloading resources"); + for (Identifier id : manager.findResources("burnmap", path -> path.getPath().endsWith(".json")).keySet()) { + try (InputStream stream = manager.getResourceOrThrow(id).getInputStream()) { + Stellum.LOGGER.info("Loaded burnmap: " + id.toString()); + Gson gson = new Gson(); + JsonObject jsonObject = gson.fromJson(new String(stream.readAllBytes()), JsonObject.class); + } catch (Exception e) { + Stellum.LOGGER.error("Error occurred while loading resource json" + id.toString(), e); + } + } + } + +} diff --git a/src/main/resources/data/stellum/burnmap/test.json b/src/main/resources/data/stellum/burnmap/test.json new file mode 100644 index 0000000..62b9a4d --- /dev/null +++ b/src/main/resources/data/stellum/burnmap/test.json @@ -0,0 +1,3 @@ +{ + "burnmap": { "test": "yippe it laoded" } +}