diff --git a/src/main/java/net/dylan/magicmod/MagicMod.java b/src/main/java/net/dylan/magicmod/MagicMod.java index 6ff19e0..dcc147f 100644 --- a/src/main/java/net/dylan/magicmod/MagicMod.java +++ b/src/main/java/net/dylan/magicmod/MagicMod.java @@ -4,7 +4,6 @@ import net.dylan.magicmod.item.ModItems; import net.dylan.magicmod.item.ModItemsGroups; import net.fabricmc.api.ModInitializer; - import net.fabricmc.fabric.api.biome.v1.BiomeModifications; import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; import net.minecraft.registry.RegistryKey; @@ -25,11 +24,9 @@ public class MagicMod implements ModInitializer { RegistryKey.of(RegistryKeys.PLACED_FEATURE, Identifier.of("magicmod", "magic_crystal_deepslate_ore")); - @Override public void onInitialize() { ModItemsGroups.registerItemGroups(); - ModItems.registerModItems(); ModBlocks.registerModBlocks(); @@ -39,11 +36,12 @@ public void onInitialize() { MAGIC_CRYSTAL_ORE_PLACED_KEY ); - // Add magic crystal deepslate ore to overworld generation BiomeModifications.addFeature( BiomeSelectors.foundInOverworld(), GenerationStep.Feature.UNDERGROUND_ORES, MAGIC_CRYSTAL_DEEPSLATE_ORE_PLACED_KEY ); } -} \ No newline at end of file +} + + diff --git a/src/main/java/net/dylan/magicmod/entity/BoulderEntity.java b/src/main/java/net/dylan/magicmod/entity/BoulderEntity.java new file mode 100644 index 0000000..12838d4 --- /dev/null +++ b/src/main/java/net/dylan/magicmod/entity/BoulderEntity.java @@ -0,0 +1,54 @@ +package net.dylan.magicmod.entity; + +import net.minecraft.entity.EntityType; +import net.minecraft.entity.data.DataTracker; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.entity.damage.DamageSources; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.world.World; + +public class BoulderEntity extends ProjectileEntity { + + public BoulderEntity(EntityType<? extends BoulderEntity> entityType, World world) { + super(entityType, world); + } + + protected void initDataTracker() { + // Initialize data parameters if needed + } + + @Override + protected void initDataTracker(DataTracker.Builder builder) { + + } + + @Override + public void tick() { + super.tick(); + // Add custom behavior here + } + + @Override + protected void onCollision(HitResult hitResult) { + super.onCollision(hitResult); + if (!this.getWorld().isClient()) { + if (hitResult.getType() == HitResult.Type.ENTITY) { + EntityHitResult entityHitResult = (EntityHitResult) hitResult; + entityHitResult.getEntity().damage(this.getWorld().getDamageSources().thrown(this, this.getOwner()), 10.0F); + } + this.discard(); + } + } + + @Override + public void writeCustomDataToNbt(NbtCompound nbt) { + // Write custom data to NBT + } + + @Override + public void readCustomDataFromNbt(NbtCompound nbt) { + // Read custom data from NBT + } +} diff --git a/src/main/java/net/dylan/magicmod/item/custom/PowerstaffItem.java b/src/main/java/net/dylan/magicmod/item/custom/PowerstaffItem.java index d6b56bd..38e2c81 100644 --- a/src/main/java/net/dylan/magicmod/item/custom/PowerstaffItem.java +++ b/src/main/java/net/dylan/magicmod/item/custom/PowerstaffItem.java @@ -1,9 +1,14 @@ package net.dylan.magicmod.item.custom; +import net.dylan.magicmod.MagicMod; +import net.dylan.magicmod.entity.BoulderEntity; +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.LightningEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.FireballEntity; +import net.minecraft.entity.projectile.ProjectileUtil; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.sound.SoundCategory; @@ -12,11 +17,17 @@ import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + public class PowerstaffItem extends Item { private Element currentElement = Element.FIRE; private long lastToggleTime = 0; @@ -29,7 +40,13 @@ public PowerstaffItem(Settings settings) { // Enum for different elements private enum Element { FIRE, - LIGHTNING + LIGHTNING, + ICE; + + @Override + public String toString() { + return super.toString(); + } } @Override @@ -52,6 +69,9 @@ public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand h case LIGHTNING: useLightningElement(world, player); break; + case ICE: + useIceElement(world, player); + break; } } @@ -60,12 +80,19 @@ public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand h } private void toggleElement(PlayerEntity player) { - if (currentElement == Element.FIRE) { - currentElement = Element.LIGHTNING; - player.sendMessage(Text.literal("Changed element to Lightning"), true); - } else { - currentElement = Element.FIRE; - player.sendMessage(Text.literal("Changed element to Fire"), true); + switch (currentElement) { + case FIRE -> { + currentElement = Element.LIGHTNING; + player.sendMessage(Text.literal("Changed element to Lightning"), true); + } + case LIGHTNING -> { + currentElement = Element.ICE; + player.sendMessage(Text.literal("Changed element to Ice"), true); + } + case ICE -> { + currentElement = Element.FIRE; + player.sendMessage(Text.literal("Changed element to Fire"), true); + } } } @@ -100,7 +127,7 @@ private void useLightningElement(World world, PlayerEntity player) { Vec3d startPos = player.getCameraPosVec(1.0F); Vec3d endPos = startPos.add(player.getRotationVec(1.0F).multiply(100)); // Adjust distance as needed - BlockHitResult hitResult = world.raycast(new net.minecraft.world.RaycastContext( + HitResult hitResult = world.raycast(new net.minecraft.world.RaycastContext( startPos, endPos, net.minecraft.world.RaycastContext.ShapeType.OUTLINE, net.minecraft.world.RaycastContext.FluidHandling.NONE, @@ -108,14 +135,81 @@ private void useLightningElement(World world, PlayerEntity player) { )); if (hitResult.getType() == HitResult.Type.BLOCK) { - BlockPos targetPos = hitResult.getBlockPos(); + BlockHitResult blockHitResult = (BlockHitResult) hitResult; + BlockPos targetPos = blockHitResult.getBlockPos(); // Spawn a lightning bolt at the target position - LightningEntity lightning = new LightningEntity(EntityType.LIGHTNING_BOLT, world); - lightning.setPosition(targetPos.getX(), targetPos.getY(), targetPos.getZ()); + LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(world); + if (lightning != null) { + lightning.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(targetPos)); + world.spawnEntity(lightning); + } + } + } + } + + private void useIceElement(World world, PlayerEntity player) { + // Play ice sound + world.playSound(null, player.getX(), player.getY(), player.getZ(), + SoundEvents.BLOCK_GLASS_PLACE, SoundCategory.PLAYERS, 1.0F, 1.0F); - world.spawnEntity(lightning); + if (!world.isClient) { + // Perform a ray trace to find the targeted entity with extended range (50 blocks) + Vec3d startPos = player.getCameraPosVec(1.0F); + Vec3d direction = player.getRotationVec(1.0F); + Vec3d endPos = startPos.add(direction.multiply(50)); // Extended range to 50 blocks + + EntityHitResult entityHitResult = ProjectileUtil.raycast(player, startPos, endPos, + player.getBoundingBox().stretch(direction.multiply(50)).expand(1.0D), + entity -> !entity.isSpectator() && entity.isAlive(), + 50); + + if (entityHitResult != null) { + Entity target = entityHitResult.getEntity(); + BlockPos targetPos = target.getBlockPos(); + + // Determine the size of the encasement based on the entity's bounding box + Box boundingBox = target.getBoundingBox(); + double targetWidth = boundingBox.maxX - boundingBox.minX; + double targetHeight = boundingBox.maxY - boundingBox.minY; + int encasementRadius = (int) Math.ceil(targetWidth / 2); + int encasementHeight = (int) Math.ceil(targetHeight); + + // Define the area around the entity to encase in ice, scaling with the entity's size + BlockPos.Mutable mutablePos = new BlockPos.Mutable(); + for (int x = -encasementRadius; x <= encasementRadius; x++) { + for (int y = 0; y <= encasementHeight; y++) { + for (int z = -encasementRadius; z <= encasementRadius; z++) { + mutablePos.set(targetPos.getX() + x, targetPos.getY() + y, targetPos.getZ() + z); + if (world.getBlockState(mutablePos).isAir()) { + world.setBlockState(mutablePos, Blocks.ICE.getDefaultState()); + } + } + } + } + + // Schedule the ice to melt after a delay (e.g., 5 seconds) + ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + scheduler.schedule(() -> { + for (int x = -encasementRadius; x <= encasementRadius; x++) { + for (int y = 0; y <= encasementHeight; y++) { + for (int z = -encasementRadius; z <= encasementRadius; z++) { + mutablePos.set(targetPos.getX() + x, targetPos.getY() + y, targetPos.getZ() + z); + if (world.getBlockState(mutablePos).isOf(Blocks.ICE)) { + world.setBlockState(mutablePos, Blocks.AIR.getDefaultState()); + } + } + } + } + }, 5, TimeUnit.SECONDS); + + // Shutdown the scheduler after task completion + scheduler.shutdown(); } } } } + + + +