Last active
February 22, 2024 03:38
-
-
Save Ensamisten/f5af6e5c846dbd31105f254f265007e0 to your computer and use it in GitHub Desktop.
FireworkCommand. (Tested for Forge in Minecraft: 1,18, 1.18.1, 1.18.2, 1.19.1, 1.19.2, 1.19.3, 1.19.4, 1.20, 1.20.1, 1.20.2, 1.20.2, 1.21). The mixin allows for firework to pass through blocks, although it does not allow for all fireworks issued by the firework command.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package io.github.ensamisten.fireworkmod; | |
| import com.mojang.brigadier.Command; | |
| import com.mojang.brigadier.CommandDispatcher; | |
| import com.mojang.brigadier.arguments.IntegerArgumentType; | |
| import com.mojang.brigadier.context.CommandContext; | |
| import io.github.ensamisten.forgient.mixin.FireworkRocketEntityMixin; | |
| import net.minecraft.commands.CommandSourceStack; | |
| import net.minecraft.commands.Commands; | |
| import net.minecraft.commands.arguments.EntityArgument; | |
| import net.minecraft.commands.arguments.coordinates.BlockPosArgument; | |
| import net.minecraft.core.BlockPos; | |
| import net.minecraft.nbt.CompoundTag; | |
| import net.minecraft.nbt.ListTag; | |
| import net.minecraft.world.entity.Entity; | |
| import net.minecraft.world.entity.EntityType; | |
| import net.minecraft.world.entity.projectile.FireworkRocketEntity; | |
| import net.minecraft.world.item.ItemStack; | |
| import net.minecraft.world.item.Items; | |
| import net.minecraft.world.level.Level; | |
| import org.jetbrains.annotations.NotNull; | |
| import java.util.Random; | |
| import static net.minecraft.world.item.Items.FIREWORK_ROCKET; | |
| /** | |
| * Firework command for Firework Mod | |
| * License: Free for all use. | |
| **/ | |
| public class FireworkCommand { | |
| public static void register(CommandDispatcher<CommandSourceStack> dispatcher) { | |
| dispatcher.register(Commands.literal("firework") | |
| .then(Commands.argument("pos", BlockPosArgument.blockPos()) | |
| .executes(context -> execute(context, BlockPosArgument.getLoadedBlockPos(context, "pos"), 1, 0xFFFFFF, 1,1)) | |
| .then(Commands.argument("count", IntegerArgumentType.integer(1)) | |
| .then(Commands.argument("shape", IntegerArgumentType.integer(0, 2)) | |
| .then(Commands.argument("colors", IntegerArgumentType.integer(0, 16777215)) | |
| .then(Commands.argument("flight", IntegerArgumentType.integer(1, 3)) | |
| .executes(context -> execute(context, BlockPosArgument.getLoadedBlockPos(context, "pos"), IntegerArgumentType.getInteger(context, "count"), IntegerArgumentType.getInteger(context, "shape"), IntegerArgumentType.getInteger(context, "colors"), IntegerArgumentType.getInteger(context, "flight"))) | |
| ) | |
| ) | |
| ) | |
| ) | |
| ) | |
| .then(Commands.literal("entity") | |
| .then(Commands.argument("targets", EntityArgument.entities()) | |
| .then(Commands.argument("count", IntegerArgumentType.integer(1)) | |
| .then(Commands.argument("shape", IntegerArgumentType.integer(0, 2)) | |
| .then(Commands.argument("colors", IntegerArgumentType.integer(0, 16777215)) | |
| .then(Commands.argument("flight", IntegerArgumentType.integer(1, 3)) | |
| .executes(context -> executeFromEntities(context, EntityArgument.getEntities(context, "targets"), IntegerArgumentType.getInteger(context, "count"), IntegerArgumentType.getInteger(context, "shape"), IntegerArgumentType.getInteger(context, "colors"), IntegerArgumentType.getInteger(context, "flight"))) | |
| ) | |
| ) | |
| ) | |
| ) | |
| ) | |
| ) | |
| ); | |
| } | |
| private static int execute(CommandContext<CommandSourceStack> context, BlockPos pos, int count, int shape, int colors, int flight) { | |
| Level level = context.getSource().getLevel(); | |
| for (int i = 0; i < count; i++) { | |
| double offsetX = (new Random().nextDouble() - 0.5) * 5.0; | |
| double offsetY = (new Random().nextDouble() - 0.5) * 5.0; | |
| double offsetZ = (new Random().nextDouble() - 0.5) * 5.0; | |
| ItemStack fireworkStar = createFireworkStar(shape, colors, flight); | |
| // Create a new instance of FireworkRocketEntity | |
| FireworkRocketEntity firework = new FireworkRocketEntity(level, pos.getX() + 0.5 + offsetX, pos.getY() + 0.5 + offsetY, pos.getZ() + 0.5 + offsetZ, fireworkStar); | |
| // Apply mixin logic here if needed | |
| firework.setDeltaMovement(firework.getDeltaMovement().add(0.0D, 0.05D, 0.0D)); | |
| level.addFreshEntity(firework); | |
| } | |
| return Command.SINGLE_SUCCESS; | |
| } | |
| private static int executeFromEntities(CommandContext<CommandSourceStack> context, Iterable<? extends Entity> targets, int count, int shape, int colors, int flight) { | |
| Level level = context.getSource().getLevel(); | |
| for (Entity target : targets) { | |
| for (int i = 0; i < count; i++) { | |
| double offsetX = (new Random().nextDouble() - 0.5) * 5.0; | |
| double offsetY = (new Random().nextDouble() - 0.5) * 5.0; | |
| double offsetZ = (new Random().nextDouble() - 0.5) * 5.0; | |
| ItemStack fireworkStar = createFireworkStar(shape, colors, flight); | |
| FireworkRocketEntity firework = new FireworkRocketEntity(level, target.getX() + 0.5 + offsetX, target.getY() + target.getBbHeight() + 0.5 + offsetY, target.getZ() + 0.5 + offsetZ, fireworkStar); | |
| level.addFreshEntity(firework); | |
| } | |
| } | |
| return Command.SINGLE_SUCCESS; | |
| } | |
| private static ItemStack createFireworkStar(int shape, int colors, int flight) { | |
| ItemStack fireworkStar = new ItemStack(FIREWORK_ROCKET); | |
| CompoundTag fireworksNBT = new CompoundTag(); | |
| ListTag explosionsList = new ListTag(); | |
| CompoundTag explosionTag = getCompoundTag(shape); | |
| explosionTag.putIntArray("Colors", new int[]{colors}); // Set the desired color | |
| explosionTag.putIntArray("FadeColors", new int[]{0xFFFFFF}); // White fade color | |
| explosionsList.add(explosionTag); | |
| fireworksNBT.put("Explosions", explosionsList); | |
| fireworkStar.addTagElement("Fireworks", fireworksNBT); | |
| // Set the flight duration | |
| CompoundTag fireworkItemNBT = fireworkStar.getOrCreateTagElement("Fireworks"); | |
| fireworkItemNBT.putInt("Flight", flight); | |
| return fireworkStar; | |
| } | |
| @NotNull | |
| private static CompoundTag getCompoundTag(int shape) { | |
| CompoundTag explosionTag = new CompoundTag(); | |
| switch (shape) { | |
| // Small ball explosion | |
| case 1 -> explosionTag.putInt("Type", 1); // Large ball explosion | |
| case 2 -> explosionTag.putInt("Type", 2); // Star-shaped explosion | |
| // Add more shapes as needed | |
| default -> explosionTag.putInt("Type", 0); // Default to small ball explosion | |
| } | |
| explosionTag.putBoolean("Flicker", true); // Flickering effect | |
| explosionTag.putBoolean("Trail", true); // Trail effect | |
| return explosionTag; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package io.github.ensamisten.fireworkmod; | |
| import com.mojang.brigadier.CommandDispatcher; | |
| import net.minecraft.commands.CommandSourceStack; | |
| import net.minecraftforge.event.RegisterCommandsEvent; | |
| import net.minecraftforge.eventbus.api.SubscribeEvent; | |
| public class FreworkCommandRegistry { | |
| /** | |
| * Register FireworkCommand | |
| * License: Free for all use. | |
| **/ | |
| @SubscribeEvent | |
| public static void registerCommandsEvent(RegisterCommandsEvent event) { | |
| CommandDispatcher<CommandSourceStack> commandDispatcher = event.getDispatcher(); | |
| FireworkCommand.register(commandDispatcher); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class FireworkMod { | |
| public FireworkMod() { | |
| // Register the FireworkCommandRegistry | |
| MinecraftForge.EVENT_BUS.register(FreworkCommandRegistry.class); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package io.github.ensamisten.fireworkmod.mixin; | |
| import net.minecraft.world.entity.EntityType; | |
| import net.minecraft.world.level.Level; | |
| import net.minecraft.world.phys.HitResult; | |
| import org.spongepowered.asm.mixin.Mixin; | |
| import org.spongepowered.asm.mixin.injection.At; | |
| import org.spongepowered.asm.mixin.injection.Inject; | |
| import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | |
| import net.minecraft.world.entity.Entity; | |
| import net.minecraft.world.entity.projectile.FireworkRocketEntity; | |
| import net.minecraft.world.level.ClipContext; | |
| import net.minecraft.world.phys.Vec3; | |
| @Mixin(FireworkRocketEntity.class) | |
| public abstract class FireworkRocketEntityMixin extends Entity { | |
| protected FireworkRocketEntityMixin(EntityType<?> entityType, Level level) { | |
| super(entityType, level); | |
| } | |
| @Inject(method = "tick", at = @At("HEAD"), cancellable = true) | |
| private void allowPassingThroughBlocks(CallbackInfo ci) { | |
| // Get the rocket's current position and motion | |
| Vec3 currentPosition = this.position(); | |
| Vec3 motion = this.getDeltaMovement(); | |
| // Calculate the next position after applying the motion | |
| Vec3 nextPosition = currentPosition.add(motion); | |
| // Check if the rocket's movement would result in a collision with a block | |
| HitResult hitResult = this.level().clip(new ClipContext(currentPosition, nextPosition, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)); | |
| // If the rocket is colliding with a block, cancel the collision and move the rocket | |
| if (hitResult.getType() != HitResult.Type.MISS) { | |
| ci.cancel(); | |
| this.setPos(nextPosition.x, nextPosition.y, nextPosition.z); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment