This commit is contained in:
2026-01-30 12:51:54 +01:00
parent 488d1c13dd
commit a7f11c9636
14 changed files with 343 additions and 9 deletions

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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<TntObeliskStructure> 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<CannabisPatchFeatureConfig> CANNABIS_PATCH =
Registry.register(
Registries.FEATURE,

View File

@@ -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
);
}
}
}
}
}
}

View File

@@ -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<TntObeliskStructure> CODEC =
Structure.createCodec(TntObeliskStructure::new);
public TntObeliskStructure(Config config) {
super(config);
}
@Override
protected Optional<StructurePosition> 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); // 67 wide
int height1 = 50 + random.nextInt(51); // 50100
int height2 = height1 - (8 + random.nextInt(5)); // ~10 diff
int gap = 4 + random.nextInt(3); // 46 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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "szar:block/obelisk_core"
}
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "szar:block/obelisk_core"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -1,11 +1,11 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"BBB",
"NNB"
"III",
"NNI"
],
"key": {
"B": {
"I": {
"item": "minecraft:iron_ingot"
},
"N": {

View File

@@ -0,0 +1,7 @@
{
"type": "szar:two_towers",
"biomes": "#minecraft:is_overworld",
"spawn_overrides": {},
"step": "surface_structures",
"terrain_adaptation": "beard_thin"
}

View File

@@ -0,0 +1,14 @@
{
"structures": [
{
"structure": "szar:two_towers",
"weight": 1
}
],
"placement": {
"type": "minecraft:random_spread",
"spacing": 40,
"separation": 28,
"salt": 987654321
}
}