From 0075b90ee8845844e30026c2240d81a0fa111d04 Mon Sep 17 00:00:00 2001 From: URGG <91295255+URGG@users.noreply.github.com> Date: Sat, 22 Nov 2025 11:47:16 -0800 Subject: [PATCH] added dome scroll thingy --- .../java/com/example/ExampleModClient.java | 9 +- .../com/example/DevastationDomeEntity.java | 200 ++++++++++++++++++ .../example/DevastationDomeScrollItem.java | 166 +++++++++++++++ src/main/java/com/example/GodMod.java | 4 + src/main/java/com/example/ModEntities.java | 16 ++ src/main/java/com/example/ModItems.java | 4 + .../Models/item/devastation_dome_scroll.json | 6 + .../godmod/items/devastation_dome_scroll.json | 6 + .../resources/assets/godmod/lang/en_us.json | 3 +- .../textures/item/devastation_dome_scroll.png | Bin 0 -> 11267 bytes .../recipe/devastation_dome_scroll.json | 17 ++ 11 files changed, 429 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/example/DevastationDomeEntity.java create mode 100644 src/main/java/com/example/DevastationDomeScrollItem.java create mode 100644 src/main/resources/assets/godmod/Models/item/devastation_dome_scroll.json create mode 100644 src/main/resources/assets/godmod/items/devastation_dome_scroll.json create mode 100644 src/main/resources/assets/godmod/textures/item/devastation_dome_scroll.png create mode 100644 src/main/resources/data/godmod/recipe/devastation_dome_scroll.json diff --git a/src/client/java/com/example/ExampleModClient.java b/src/client/java/com/example/ExampleModClient.java index fa96838..7da2ee2 100644 --- a/src/client/java/com/example/ExampleModClient.java +++ b/src/client/java/com/example/ExampleModClient.java @@ -7,7 +7,8 @@ import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry; import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; import net.minecraft.client.render.entity.FlyingItemEntityRenderer; - +import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; +import net.minecraft.client.render.entity.EmptyEntityRenderer; public class ExampleModClient implements ClientModInitializer { @Override @@ -19,6 +20,12 @@ public void onInitializeClient() { EntityRendererRegistry.register(ModEntities.GOD_BOSS, GodBossEntityRenderer::new); + EntityRendererRegistry.register(ModEntities.GOD_BOSS, GodBossEntityRenderer::new); + + + EntityRendererRegistry.register(ModEntities.DEVASTATION_DOME_ENTITY, EmptyEntityRenderer::new); + + System.out.println("GodMod client initialized with entity renderers and custom boss model"); diff --git a/src/main/java/com/example/DevastationDomeEntity.java b/src/main/java/com/example/DevastationDomeEntity.java new file mode 100644 index 0000000..406d90c --- /dev/null +++ b/src/main/java/com/example/DevastationDomeEntity.java @@ -0,0 +1,200 @@ +package com.example; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.damage.DamageTypes; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.world.World; + +import java.util.List; + +public class DevastationDomeEntity extends Entity { + private static final int DOME_RADIUS = 15; + private static final int DOME_DURATION_TICKS = 200; + private static final float DAMAGE_PER_TICK = 100000.0F; + private static final int DAMAGE_INTERVAL = 1; + + private int lifeTicks = 0; + private BlockPos domeCenter; + + public DevastationDomeEntity(EntityType type, World world) { + super(type, world); + this.noClip = true; + this.setInvulnerable(true); + } + + public DevastationDomeEntity(EntityType type, World world, BlockPos center) { + this(type, world); + this.domeCenter = center; + this.setPosition(center.getX() + 0.5, center.getY() + 0.5, center.getZ() + 0.5); + } + + @Override + protected void initDataTracker(net.minecraft.entity.data.DataTracker.Builder builder) { + // No data to track + } + + @Override + public void tick() { + super.tick(); + + if (!this.getWorld().isClient) { + lifeTicks++; + + // Apply damage every tick + if (lifeTicks % DAMAGE_INTERVAL == 0) { + applyDomeDamage(); + } + + // Spawn particles every 5 ticks + if (lifeTicks % 5 == 0) { + spawnDomeParticles(); + } + + // Remove after duration + if (lifeTicks >= DOME_DURATION_TICKS) { + removeDome(); + this.discard(); + } + } + } + + private void applyDomeDamage() { + if (!(this.getWorld() instanceof ServerWorld serverWorld)) { + return; + } + + if (domeCenter == null) { + domeCenter = this.getBlockPos(); + } + + // Create damage box + Box damageBox = new Box(domeCenter).expand(DOME_RADIUS); + + // Find all living entities except players + List entities = this.getWorld().getEntitiesByClass( + LivingEntity.class, + damageBox, + entity -> { + double distance = entity.getPos().distanceTo(domeCenter.toCenterPos()); + return distance <= DOME_RADIUS && !(entity instanceof PlayerEntity); + } + ); + + // Create damage source using the server world's damage sources + DamageSource lethalDamage = serverWorld.getDamageSources().outOfWorld(); + + // Apply damage to all entities + for (LivingEntity entity : entities) { + entity.damage(serverWorld, lethalDamage, DAMAGE_PER_TICK); + } + } + + private void spawnDomeParticles() { + if (!(this.getWorld() instanceof ServerWorld serverWorld)) { + return; + } + + if (domeCenter == null) { + domeCenter = this.getBlockPos(); + } + + double spin = (lifeTicks % 360) * Math.PI / 180.0; + + // Create dome shell particles + for (int yStep = 2; yStep <= DOME_RADIUS; yStep += 3) { + double height = yStep; + double radius = Math.sqrt(DOME_RADIUS * DOME_RADIUS - height * height); + + for (int i = 0; i < 360; i += 24) { + double angle = Math.toRadians(i) + spin * 0.5; + double x = domeCenter.getX() + 0.5 + Math.cos(angle) * radius; + double z = domeCenter.getZ() + 0.5 + Math.sin(angle) * radius; + double y = domeCenter.getY() + height; + + serverWorld.spawnParticles( + ParticleTypes.SOUL_FIRE_FLAME, + x, y, z, 1, 0.0, 0.0, 0.0, 0.01 + ); + serverWorld.spawnParticles( + ParticleTypes.DRAGON_BREATH, + x, y + 0.2, z, 1, 0.0, 0.0, 0.0, 0.0 + ); + } + } + + // Create inner spiral + double progress = (double) lifeTicks / DOME_DURATION_TICKS; + int spiralPoints = (int) (30.0 + 50.0 * Math.sin(Math.min(progress, 1.0) * Math.PI)); + double spiralRadius = 6.75; + + for (int i = 0; i < spiralPoints; i++) { + double angle = spin + i * 0.35; + double x = domeCenter.getX() + 0.5 + Math.cos(angle) * spiralRadius * (0.9 + 0.1 * Math.sin(spin)); + double z = domeCenter.getZ() + 0.5 + Math.sin(angle) * spiralRadius * (0.9 + 0.1 * Math.cos(spin)); + double y = domeCenter.getY() + 4.5 + Math.sin(angle * 0.9) * 2.0; + + serverWorld.spawnParticles( + ParticleTypes.ENCHANT, + x, y, z, 1, 0.0, 0.02, 0.0, 0.0 + ); + serverWorld.spawnParticles( + ParticleTypes.WARPED_SPORE, + x, y, z, 1, 0.0, 0.0, 0.0, 0.01 + ); + } + } + + private void removeDome() { + if (!(this.getWorld() instanceof ServerWorld serverWorld)) { + return; + } + + if (domeCenter == null) { + domeCenter = this.getBlockPos(); + } + + // Spawn explosion particle + serverWorld.spawnParticles( + ParticleTypes.EXPLOSION_EMITTER, + domeCenter.getX(), domeCenter.getY(), domeCenter.getZ(), + 1, 0.0, 0.0, 0.0, 0.0 + ); + } + + @Override + protected void readCustomDataFromNbt(NbtCompound nbt) { + lifeTicks = nbt.getInt("LifeTicks"); + + if (nbt.contains("DomeCenterX")) { + domeCenter = new BlockPos( + nbt.getInt("DomeCenterX"), + nbt.getInt("DomeCenterY"), + nbt.getInt("DomeCenterZ") + ); + } + } + + @Override + protected void writeCustomDataToNbt(NbtCompound nbt) { + nbt.putInt("LifeTicks", lifeTicks); + + if (domeCenter != null) { + nbt.putInt("DomeCenterX", domeCenter.getX()); + nbt.putInt("DomeCenterY", domeCenter.getY()); + nbt.putInt("DomeCenterZ", domeCenter.getZ()); + } + } + + @Override + public boolean damage(ServerWorld world, DamageSource source, float amount) { + return false; // Invulnerable + } +} \ No newline at end of file diff --git a/src/main/java/com/example/DevastationDomeScrollItem.java b/src/main/java/com/example/DevastationDomeScrollItem.java new file mode 100644 index 0000000..172f5c0 --- /dev/null +++ b/src/main/java/com/example/DevastationDomeScrollItem.java @@ -0,0 +1,166 @@ +package com.example; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.tooltip.TooltipType; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Hand; +import net.minecraft.util.ActionResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +import java.util.List; + +public class DevastationDomeScrollItem extends Item { + private static final int DOME_RADIUS = 15; + public static final SoundEvent DEVASTATION_SOUND = registerSound("destructive_dome_burst"); + + public DevastationDomeScrollItem(Settings settings) { + super(settings); + } + + private static SoundEvent registerSound(String name) { + Identifier id = Identifier.of("godmod", name); + return Registry.register(Registries.SOUND_EVENT, id, SoundEvent.of(id)); + } + + @Override + public ActionResult use(World world, PlayerEntity user, Hand hand) { + ItemStack stack = user.getStackInHand(hand); + + if (!world.isClient) { + ServerWorld serverWorld = (ServerWorld) world; + BlockPos centerPos = user.getBlockPos(); + + // Play sound (will be silent for now without sound file) + world.playSound(null, centerPos, DEVASTATION_SOUND, SoundCategory.PLAYERS, 2.0F, 1.0F); + + // Spawn particle burst + spawnParticleBurst(serverWorld, centerPos); + + // Spawn dome entity + DevastationDomeEntity domeEntity = new DevastationDomeEntity( + ModEntities.DEVASTATION_DOME_ENTITY, + serverWorld, + centerPos + ); + serverWorld.spawnEntity(domeEntity); + + // Send message to player + user.sendMessage( + Text.literal("Devastation Dome Activated!") + .formatted(Formatting.RED, Formatting.BOLD), + true + ); + + // Consume item if not in creative + if (!user.getAbilities().creativeMode) { + stack.decrement(1); + } + } + + return ActionResult.SUCCESS; + } + + private void spawnParticleBurst(ServerWorld world, BlockPos center) { + // Main explosion burst + for (int i = 0; i < 600; i++) { + double angle = Math.random() * Math.PI * 2.0; + double pitch = Math.random() * Math.PI; + double speed = 0.6 + Math.random(); + + double velX = Math.sin(pitch) * Math.cos(angle) * speed; + double velY = Math.cos(pitch) * speed; + double velZ = Math.sin(pitch) * Math.sin(angle) * speed; + + world.spawnParticles( + ParticleTypes.FLAME, + center.getX() + 0.5, center.getY() + 0.5, center.getZ() + 0.5, + 1, velX, velY, velZ, 0.08 + ); + world.spawnParticles( + ParticleTypes.SMOKE, + center.getX() + 0.5, center.getY() + 0.5, center.getZ() + 0.5, + 1, velX, velY, velZ, 0.08 + ); + world.spawnParticles( + ParticleTypes.SOUL_FIRE_FLAME, + center.getX() + 0.5, center.getY() + 0.5, center.getZ() + 0.5, + 1, velX * 0.6, velY * 0.6, velZ * 0.6, 0.02 + ); + world.spawnParticles( + ParticleTypes.WARPED_SPORE, + center.getX() + 0.5, center.getY() + 0.5, center.getZ() + 0.5, + 1, velX * 0.4, velY * 0.4, velZ * 0.4, 0.01 + ); + } + + // Ring particles + double innerRadius = 8.25; + double outerRadius = 12.75; + + for (int i = 0; i < 360; i += 8) { + double radians = Math.toRadians(i); + double innerX = center.getX() + 0.5 + Math.cos(radians) * innerRadius; + double innerZ = center.getZ() + 0.5 + Math.sin(radians) * innerRadius; + double outerX = center.getX() + 0.5 + Math.cos(radians) * outerRadius; + double outerZ = center.getZ() + 0.5 + Math.sin(radians) * outerRadius; + + world.spawnParticles( + ParticleTypes.ENCHANT, + innerX, center.getY() + 0.5, innerZ, + 2, 0.0, 0.02, 0.0, 0.0 + ); + world.spawnParticles( + ParticleTypes.DRAGON_BREATH, + outerX, center.getY() + 1.0, outerZ, + 1, 0.0, 0.02, 0.0, 0.0 + ); + } + + // Vertical pillars + for (int i = 0; i < 15; i += 2) { + world.spawnParticles( + ParticleTypes.END_ROD, + center.getX() + 0.5 + innerRadius, center.getY() + i, center.getZ() + 0.5, + 8, 0.02, 0.02, 0.02, 0.01 + ); + world.spawnParticles( + ParticleTypes.END_ROD, + center.getX() + 0.5 - innerRadius, center.getY() + i, center.getZ() + 0.5, + 8, 0.02, 0.02, 0.02, 0.01 + ); + world.spawnParticles( + ParticleTypes.END_ROD, + center.getX() + 0.5, center.getY() + i, center.getZ() + 0.5 + innerRadius, + 8, 0.02, 0.02, 0.02, 0.01 + ); + world.spawnParticles( + ParticleTypes.END_ROD, + center.getX() + 0.5, center.getY() + i, center.getZ() + 0.5 - innerRadius, + 8, 0.02, 0.02, 0.02, 0.01 + ); + } + } + + @Override + public void appendTooltip(ItemStack stack, TooltipContext context, List tooltip, TooltipType type) { + tooltip.add(Text.translatable("item.godmod.devastation_dome_scroll.tooltip").formatted(Formatting.GRAY)); + tooltip.add(Text.translatable("item.godmod.devastation_dome_scroll.tooltip2").formatted(Formatting.DARK_RED)); + tooltip.add(Text.translatable("item.godmod.devastation_dome_scroll.tooltip3").formatted(Formatting.DARK_GRAY)); + } + + @Override + public boolean hasGlint(ItemStack stack) { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/GodMod.java b/src/main/java/com/example/GodMod.java index 6b271f4..6859f97 100644 --- a/src/main/java/com/example/GodMod.java +++ b/src/main/java/com/example/GodMod.java @@ -21,6 +21,10 @@ public void onInitialize() { ModScrolls.initialize(); // This was missing! LOGGER.info("ModScrolls.initialize() completed!"); ModEntities.initialize(); + LOGGER.info("ModEntities.initialize() completed!"); + LOGGER.info("DEVASTATION_DOME_SCROLL is: " + (ModItems.Devastation_DOME_SCROLL != null ? "NOT NULL" : "NULL")); + + //ModBlocks.initialize(); diff --git a/src/main/java/com/example/ModEntities.java b/src/main/java/com/example/ModEntities.java index 5e048c1..9323c42 100644 --- a/src/main/java/com/example/ModEntities.java +++ b/src/main/java/com/example/ModEntities.java @@ -14,6 +14,7 @@ public class ModEntities { public static final EntityType THROWABLE_GOD_AXE; public static final EntityType GOD_BOSS; + public static final EntityType DEVASTATION_DOME_ENTITY; static { // Register Throwable God Axe Entity @@ -43,6 +44,20 @@ public class ModEntities { .trackedUpdateRate(1) // Boss entities should update frequently .build(bossKey) ); + + // Register Devastation Dome Entity + Identifier domeId = Identifier.of(GodMod.MOD_ID, "devastation_dome"); + RegistryKey> domeKey = RegistryKey.of(Registries.ENTITY_TYPE.getKey(), domeId); + + DEVASTATION_DOME_ENTITY = Registry.register( + Registries.ENTITY_TYPE, + domeId, + FabricEntityTypeBuilder.create(SpawnGroup.MISC, DevastationDomeEntity::new) + .dimensions(EntityDimensions.fixed(0.5f, 0.5f)) + .trackRangeBlocks(64) + .trackedUpdateRate(20) + .build(domeKey) + ); } public static void initialize() { @@ -52,6 +67,7 @@ public static void initialize() { FabricDefaultAttributeRegistry.register(GOD_BOSS, GodBossEntity.createAttributes()); // Note: ThrowableGodAxeEntity doesn't need attributes as it's a projectile + // Note: DevastationDomeEntity doesn't need attributes as it's not a living entity System.out.println("Entity registration complete!"); } diff --git a/src/main/java/com/example/ModItems.java b/src/main/java/com/example/ModItems.java index 3b324bb..b12b481 100644 --- a/src/main/java/com/example/ModItems.java +++ b/src/main/java/com/example/ModItems.java @@ -34,6 +34,7 @@ public class ModItems { public static Item MAGIC_CRYSTAL; public static Item GOD_AXE; public static Item SUMMONING_CRYSTAL; + public static Item Devastation_DOME_SCROLL; public static void initialize() { System.out.println("Registering items for " + GodMod.MOD_ID); @@ -42,6 +43,7 @@ public static void initialize() { GOD_SWORD = registerItem("god_sword", key -> new GodSwordItem(GOD_MATERIAL, new Item.Settings().registryKey(key).maxCount(1))); MAGIC_CRYSTAL = registerItem("magic_crystal", key -> new Item(new Item.Settings().registryKey(key))); GOD_AXE = registerItem("god_axe", key ->new GodAxe(GOD_MATERIAL, new Item.Settings().registryKey(key).maxCount(1))); + Devastation_DOME_SCROLL = registerItem("devastation_dome_scroll", key -> new DevastationDomeScrollItem(new Item.Settings().registryKey(key).maxCount(16))); SUMMONING_CRYSTAL = registerItem("summoning_crystal", key -> new SummoningCrystalItem(new Item.Settings().registryKey(key).maxCount(1))); @@ -56,6 +58,8 @@ public static void initialize() { ItemGroupEvents.modifyEntriesEvent(ItemGroups.INGREDIENTS) .register(entries -> entries.add(new ItemStack(SUMMONING_CRYSTAL))); + ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT) + .register(entries -> entries.add(new ItemStack(Devastation_DOME_SCROLL))); } public static Item registerItem(String name, Function, Item> function) { diff --git a/src/main/resources/assets/godmod/Models/item/devastation_dome_scroll.json b/src/main/resources/assets/godmod/Models/item/devastation_dome_scroll.json new file mode 100644 index 0000000..8e8cfda --- /dev/null +++ b/src/main/resources/assets/godmod/Models/item/devastation_dome_scroll.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "godmod:item/devastation_dome_scroll" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/godmod/items/devastation_dome_scroll.json b/src/main/resources/assets/godmod/items/devastation_dome_scroll.json new file mode 100644 index 0000000..4beee3b --- /dev/null +++ b/src/main/resources/assets/godmod/items/devastation_dome_scroll.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "godmod:item/devastation_dome_scroll" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/godmod/lang/en_us.json b/src/main/resources/assets/godmod/lang/en_us.json index ea370e6..716ec06 100644 --- a/src/main/resources/assets/godmod/lang/en_us.json +++ b/src/main/resources/assets/godmod/lang/en_us.json @@ -4,5 +4,6 @@ "item.godmod.fireball_scroll": "Fireball Scroll", "item.godmod.god_axe": "God Axe", "item.godmod.god_boss_spawn_egg": "God Boss Spawner", - "item.godmod.summoning_crystal": "Summonning Eye" + "item.godmod.summoning_crystal": "Summonning Eye", + "item.godmod.devastation_dome": "Devastation Dome" } \ No newline at end of file diff --git a/src/main/resources/assets/godmod/textures/item/devastation_dome_scroll.png b/src/main/resources/assets/godmod/textures/item/devastation_dome_scroll.png new file mode 100644 index 0000000000000000000000000000000000000000..1831f0eda0d1e8c545444ee820e885c3d34ed46b GIT binary patch literal 11267 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