From a7f11c96363f3aeedb60b5b9948da847acf9d622 Mon Sep 17 00:00:00 2001 From: TGdoesCode Date: Fri, 30 Jan 2026 12:51:54 +0100 Subject: [PATCH] twin --- gradle.properties | 2 +- .../dev/tggamesyt/szar/ObeliskCoreBlock.java | 23 ++++ src/main/java/dev/tggamesyt/szar/Szar.java | 27 ++++ .../dev/tggamesyt/szar/TntObeliskPiece.java | 117 ++++++++++++++++++ .../tggamesyt/szar/TntObeliskStructure.java | 68 ++++++++++ .../dev/tggamesyt/szar/TwoTowersUtil.java | 46 +++++++ .../assets/szar/blockstates/obelisk_core.json | 7 ++ .../szar/models/block/obelisk_core.json | 6 + .../szar/textures/block/obelisk_core.png | Bin 0 -> 175 bytes .../advancements/two_towers_explosion.json | 15 +++ .../data/szar/recipes/police_handcuff.json | 14 ++- .../data/szar/recipes/police_key.json | 6 +- .../szar/worldgen/structure/two_towers.json | 7 ++ .../worldgen/structure_set/two_towers.json | 14 +++ 14 files changed, 343 insertions(+), 9 deletions(-) create mode 100644 src/main/java/dev/tggamesyt/szar/ObeliskCoreBlock.java create mode 100644 src/main/java/dev/tggamesyt/szar/TntObeliskPiece.java create mode 100644 src/main/java/dev/tggamesyt/szar/TntObeliskStructure.java create mode 100644 src/main/java/dev/tggamesyt/szar/TwoTowersUtil.java create mode 100644 src/main/resources/assets/szar/blockstates/obelisk_core.json create mode 100644 src/main/resources/assets/szar/models/block/obelisk_core.json create mode 100644 src/main/resources/assets/szar/textures/block/obelisk_core.png create mode 100644 src/main/resources/data/szar/advancements/two_towers_explosion.json create mode 100644 src/main/resources/data/szar/worldgen/structure/two_towers.json create mode 100644 src/main/resources/data/szar/worldgen/structure_set/two_towers.json diff --git a/gradle.properties b/gradle.properties index 816dd0d..17c6aac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ minecraft_version=1.20.1 yarn_mappings=1.20.1+build.10 loader_version=0.18.3 # Mod Properties -mod_version=1.0.11 +mod_version=1.0.12 maven_group=dev.tggamesyt archives_base_name=szar # Dependencies diff --git a/src/main/java/dev/tggamesyt/szar/ObeliskCoreBlock.java b/src/main/java/dev/tggamesyt/szar/ObeliskCoreBlock.java new file mode 100644 index 0000000..b9851e3 --- /dev/null +++ b/src/main/java/dev/tggamesyt/szar/ObeliskCoreBlock.java @@ -0,0 +1,23 @@ +package dev.tggamesyt.szar; + +import net.minecraft.block.Block; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.explosion.Explosion; + +public class ObeliskCoreBlock extends Block { + + public ObeliskCoreBlock(Settings settings) { + super(settings); + } + + @Override + public void onDestroyedByExplosion(World world, BlockPos pos, Explosion explosion) { + super.onDestroyedByExplosion(world, pos, explosion); + + if (!(world instanceof ServerWorld serverWorld)) return; + + TwoTowersUtil.grantNearbyAdvancement(serverWorld, pos, 100); + } +} diff --git a/src/main/java/dev/tggamesyt/szar/Szar.java b/src/main/java/dev/tggamesyt/szar/Szar.java index 593ca33..47d419a 100644 --- a/src/main/java/dev/tggamesyt/szar/Szar.java +++ b/src/main/java/dev/tggamesyt/szar/Szar.java @@ -29,6 +29,7 @@ import net.minecraft.registry.*; import net.minecraft.registry.tag.BiomeTags; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.sound.SoundEvents; +import net.minecraft.structure.StructurePieceType; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Formatting; @@ -46,6 +47,7 @@ import net.minecraft.world.gen.placementmodifier.CountPlacementModifier; import net.minecraft.world.gen.placementmodifier.SquarePlacementModifier; import net.minecraft.world.gen.stateprovider.BlockStateProvider; import net.minecraft.world.gen.stateprovider.WeightedBlockStateProvider; +import net.minecraft.world.gen.structure.StructureType; import net.minecraft.world.poi.PointOfInterestType; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -379,6 +381,31 @@ public class Szar implements ModInitializer { }); } + public static final StructurePieceType TNT_OBELISK_PIECE = + Registry.register( + Registries.STRUCTURE_PIECE, + new Identifier(MOD_ID, "tower"), + TntObeliskPiece::new + ); + public static final StructureType TNT_OBELISK_TYPE = + Registry.register( + Registries.STRUCTURE_TYPE, + new Identifier(MOD_ID, "two_towers"), + () -> TntObeliskStructure.CODEC + ); + public static final Block OBELISK_CORE = Registry.register( + Registries.BLOCK, + new Identifier(MOD_ID, "obelisk_core"), + new ObeliskCoreBlock( + AbstractBlock.Settings + .copy(Blocks.DIRT) // soft block + .strength(0.5f, 1.0f) // very easy to break, low blast resistance + ) + ); + + + + public static final Feature CANNABIS_PATCH = Registry.register( Registries.FEATURE, diff --git a/src/main/java/dev/tggamesyt/szar/TntObeliskPiece.java b/src/main/java/dev/tggamesyt/szar/TntObeliskPiece.java new file mode 100644 index 0000000..f957ff3 --- /dev/null +++ b/src/main/java/dev/tggamesyt/szar/TntObeliskPiece.java @@ -0,0 +1,117 @@ +package dev.tggamesyt.szar; + +import net.minecraft.block.Blocks; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.structure.StructureContext; +import net.minecraft.structure.StructurePiece; +import net.minecraft.util.math.BlockBox; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.StructureWorldAccess; +import net.minecraft.world.gen.StructureAccessor; +import net.minecraft.world.gen.chunk.ChunkGenerator; + +public class TntObeliskPiece extends StructurePiece { + + private final BlockPos base; + private final int height; + private final int size; // width of the tower (square) + + /* ===== NORMAL CONSTRUCTOR ===== */ + public TntObeliskPiece(BlockPos base, int height, int size) { + super( + Szar.TNT_OBELISK_PIECE, + 0, + new BlockBox( + base.getX(), + base.getY(), + base.getZ(), + base.getX() + size - 1, + base.getY() + height - 1, + base.getZ() + size - 1 + ) + ); + this.base = base; + this.height = height; + this.size = size; + } + + /* ===== NBT CONSTRUCTOR ===== */ + public TntObeliskPiece(StructureContext context, NbtCompound nbt) { + super(Szar.TNT_OBELISK_PIECE, nbt); + this.base = BlockPos.fromLong(nbt.getLong("Base")); + this.height = nbt.getInt("Height"); + this.size = nbt.getInt("Size"); + } + + /* ===== SAVE DATA ===== */ + @Override + protected void writeNbt(StructureContext context, NbtCompound nbt) { + nbt.putLong("Base", base.asLong()); + nbt.putInt("Height", height); + nbt.putInt("Size", size); + } + + /* ===== PLACE BLOCKS ===== */ + @Override + public void generate( + StructureWorldAccess world, + StructureAccessor accessor, + ChunkGenerator chunkGenerator, + Random random, + BlockBox box, + ChunkPos chunkPos, + BlockPos pivot + ) { + // Core position (centered) + int coreY = height / 2; + int coreX = size / 2; + int coreZ = size / 2; + + for (int y = 0; y < height; y++) { + for (int dx = 0; dx < size; dx++) { + for (int dz = 0; dz < size; dz++) { + + BlockPos pos = base.add(dx, y, dz); + if (!box.contains(pos)) continue; + + boolean isEdge = + dx == 0 || dz == 0 || + dx == size - 1 || dz == size - 1; + + boolean isTopOrBottom = + y == 0 || y == height - 1; + + // === PLACE CORE BLOCK (EXACTLY ONCE) === + if (y == coreY && dx == coreX && dz == coreZ) { + world.setBlockState( + pos, + Szar.OBELISK_CORE.getDefaultState(), + 2 + ); + continue; + } + + // === SHELL + CAPS === + if (isEdge || isTopOrBottom) { + world.setBlockState( + pos, + Blocks.ANDESITE.getDefaultState(), + 2 + ); + } + // === INTERIOR === + else { + world.setBlockState( + pos, + Blocks.TNT.getDefaultState(), + 2 + ); + } + } + } + } + } + +} diff --git a/src/main/java/dev/tggamesyt/szar/TntObeliskStructure.java b/src/main/java/dev/tggamesyt/szar/TntObeliskStructure.java new file mode 100644 index 0000000..ae5ea28 --- /dev/null +++ b/src/main/java/dev/tggamesyt/szar/TntObeliskStructure.java @@ -0,0 +1,68 @@ +package dev.tggamesyt.szar; + +import com.mojang.serialization.Codec; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.random.ChunkRandom; +import net.minecraft.world.Heightmap; +import net.minecraft.world.gen.structure.Structure; +import net.minecraft.world.gen.structure.StructureType; + +import java.util.Optional; + +public class TntObeliskStructure extends Structure { + + public static final Codec CODEC = + Structure.createCodec(TntObeliskStructure::new); + + public TntObeliskStructure(Config config) { + super(config); + } + + @Override + protected Optional getStructurePosition(Context context) { + return Structure.getStructurePosition( + context, + Heightmap.Type.WORLD_SURFACE_WG, + collector -> { + + ChunkRandom random = context.random(); + ChunkPos chunkPos = context.chunkPos(); + + int x = chunkPos.getCenterX(); + int z = chunkPos.getCenterZ(); + + int y = context.chunkGenerator().getHeightInGround( + x, z, + Heightmap.Type.WORLD_SURFACE_WG, + context.world(), + context.noiseConfig() + ); + + BlockPos base1 = new BlockPos(x, y, z); + + int size = 6 + random.nextInt(2); // 6–7 wide + + int height1 = 50 + random.nextInt(51); // 50–100 + int height2 = height1 - (8 + random.nextInt(5)); // ~10 diff + + int gap = 4 + random.nextInt(3); // 4–6 gap + + // Parallel: offset ONLY on X axis + BlockPos base2 = base1.add(size + gap, 0, 0); + + collector.addPiece( + new TntObeliskPiece(base1, height1, size) + ); + collector.addPiece( + new TntObeliskPiece(base2, height2, size) + ); + } + ); + } + + @Override + public StructureType getType() { + return Szar.TNT_OBELISK_TYPE; + } +} diff --git a/src/main/java/dev/tggamesyt/szar/TwoTowersUtil.java b/src/main/java/dev/tggamesyt/szar/TwoTowersUtil.java new file mode 100644 index 0000000..dbdef1d --- /dev/null +++ b/src/main/java/dev/tggamesyt/szar/TwoTowersUtil.java @@ -0,0 +1,46 @@ +package dev.tggamesyt.szar; + +import net.minecraft.advancement.Advancement; +import net.minecraft.advancement.AdvancementProgress; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; + +public class TwoTowersUtil { + + public static void grantNearbyAdvancement( + ServerWorld world, + BlockPos center, + int radius + ) { + double radiusSq = radius * radius; + + for (ServerPlayerEntity player : world.getPlayers()) { + if (player.getPos().squaredDistanceTo( + center.getX() + 0.5, + center.getY() + 0.5, + center.getZ() + 0.5 + ) <= radiusSq) { + + grant(player); + } + } + } + + private static void grant(ServerPlayerEntity player) { + Identifier id = new Identifier(Szar.MOD_ID, "two_towers_explosion"); + Advancement adv = player.server.getAdvancementLoader().get(id); + if (adv == null) return; + + AdvancementProgress progress = + player.getAdvancementTracker().getProgress(adv); + + if (progress.isDone()) return; + + for (String criterion : progress.getUnobtainedCriteria()) { + player.getAdvancementTracker().grantCriterion(adv, criterion); + } + } +} + diff --git a/src/main/resources/assets/szar/blockstates/obelisk_core.json b/src/main/resources/assets/szar/blockstates/obelisk_core.json new file mode 100644 index 0000000..d4176a3 --- /dev/null +++ b/src/main/resources/assets/szar/blockstates/obelisk_core.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "szar:block/obelisk_core" + } + } +} diff --git a/src/main/resources/assets/szar/models/block/obelisk_core.json b/src/main/resources/assets/szar/models/block/obelisk_core.json new file mode 100644 index 0000000..af9edb0 --- /dev/null +++ b/src/main/resources/assets/szar/models/block/obelisk_core.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "szar:block/obelisk_core" + } +} diff --git a/src/main/resources/assets/szar/textures/block/obelisk_core.png b/src/main/resources/assets/szar/textures/block/obelisk_core.png new file mode 100644 index 0000000000000000000000000000000000000000..434a59ce49d63be733830e38d9719747d01115cc GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1en(8bfmF~q_@x#p?P$N7vLcKZ^Oc6{rZelY00 za)-Cce9j{cg>oKym^OPpG;Zu&%+Mockj22!BgJ6CFlDua1e?cWV*>^T_FoP^lI+E& Q0nKCZboFyt=akR{00AN~qyPW_ literal 0 HcmV?d00001 diff --git a/src/main/resources/data/szar/advancements/two_towers_explosion.json b/src/main/resources/data/szar/advancements/two_towers_explosion.json new file mode 100644 index 0000000..72523e3 --- /dev/null +++ b/src/main/resources/data/szar/advancements/two_towers_explosion.json @@ -0,0 +1,15 @@ +{ + "criteria": { + "boom": { + "trigger": "minecraft:impossible" + } + }, + "display": { + "icon": { "item": "minecraft:tnt" }, + "title": "Too Close", + "description": "You were there when the towers fell", + "frame": "challenge", + "show_toast": true, + "announce_to_chat": true + } +} diff --git a/src/main/resources/data/szar/recipes/police_handcuff.json b/src/main/resources/data/szar/recipes/police_handcuff.json index 00ffa80..176eaa3 100644 --- a/src/main/resources/data/szar/recipes/police_handcuff.json +++ b/src/main/resources/data/szar/recipes/police_handcuff.json @@ -1,15 +1,19 @@ { "type": "minecraft:crafting_shaped", "pattern": [ - "###", - "i i" + "NNN", + "I I" ], "key": { - "#": "minecraft:iron_nugget", - "i": "minecraft:iron_ingot" + "I": { + "item": "minecraft:iron_ingot" + }, + "N": { + "item": "minecraft:iron_nugget" + } }, "result": { - "id": "szar:police_handcuff", + "item": "szar:police_handcuff", "count": 1 } } diff --git a/src/main/resources/data/szar/recipes/police_key.json b/src/main/resources/data/szar/recipes/police_key.json index 3daf55b..b0f543c 100644 --- a/src/main/resources/data/szar/recipes/police_key.json +++ b/src/main/resources/data/szar/recipes/police_key.json @@ -1,11 +1,11 @@ { "type": "minecraft:crafting_shaped", "pattern": [ - "BBB", - "NNB" + "III", + "NNI" ], "key": { - "B": { + "I": { "item": "minecraft:iron_ingot" }, "N": { diff --git a/src/main/resources/data/szar/worldgen/structure/two_towers.json b/src/main/resources/data/szar/worldgen/structure/two_towers.json new file mode 100644 index 0000000..a872c48 --- /dev/null +++ b/src/main/resources/data/szar/worldgen/structure/two_towers.json @@ -0,0 +1,7 @@ +{ + "type": "szar:two_towers", + "biomes": "#minecraft:is_overworld", + "spawn_overrides": {}, + "step": "surface_structures", + "terrain_adaptation": "beard_thin" +} diff --git a/src/main/resources/data/szar/worldgen/structure_set/two_towers.json b/src/main/resources/data/szar/worldgen/structure_set/two_towers.json new file mode 100644 index 0000000..8877f33 --- /dev/null +++ b/src/main/resources/data/szar/worldgen/structure_set/two_towers.json @@ -0,0 +1,14 @@ +{ + "structures": [ + { + "structure": "szar:two_towers", + "weight": 1 + } + ], + "placement": { + "type": "minecraft:random_spread", + "spacing": 40, + "separation": 28, + "salt": 987654321 + } +}