-
-
Save Densamisten/dd6f20133499db76ef8b7b0cee01f3be to your computer and use it in GitHub Desktop.
FireworkCommand. (Tested for Forge in Minecraft: 1,18-1.20.4). The mixin allows for firework to pass through blocks sometimes. Usage: /firework
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 FireworkCommand(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(Items.FIREWORK_ROCKET.asItem()); | |
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; | |
/** | |
* Firework command registry for Firework Mod | |
* License: Free for all use. | |
**/ | |
@Mod.EventBusSubscriber(modid = Firework.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) | |
public class FreworkCommandRegistry { | |
/** | |
* Register FireworkCommand | |
* License: Free for all use. | |
**/ | |
@SubscribeEvent | |
public static void registerCommandsEvent(RegisterCommandsEvent event) { | |
new FireworkCommand(event.getDispatcher()); | |
} | |
} |
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; | |
/** | |
* Firework rocket entity mixin for Firework Mod | |
* License: Free for all use. | |
**/ | |
@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