twin
This commit is contained in:
23
src/main/java/dev/tggamesyt/szar/ObeliskCoreBlock.java
Normal file
23
src/main/java/dev/tggamesyt/szar/ObeliskCoreBlock.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
117
src/main/java/dev/tggamesyt/szar/TntObeliskPiece.java
Normal file
117
src/main/java/dev/tggamesyt/szar/TntObeliskPiece.java
Normal 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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
68
src/main/java/dev/tggamesyt/szar/TntObeliskStructure.java
Normal file
68
src/main/java/dev/tggamesyt/szar/TntObeliskStructure.java
Normal 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); // 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;
|
||||
}
|
||||
}
|
||||
46
src/main/java/dev/tggamesyt/szar/TwoTowersUtil.java
Normal file
46
src/main/java/dev/tggamesyt/szar/TwoTowersUtil.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "szar:block/obelisk_core"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "szar:block/obelisk_core"
|
||||
}
|
||||
}
|
||||
BIN
src/main/resources/assets/szar/textures/block/obelisk_core.png
Normal file
BIN
src/main/resources/assets/szar/textures/block/obelisk_core.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 175 B |
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"BBB",
|
||||
"NNB"
|
||||
"III",
|
||||
"NNI"
|
||||
],
|
||||
"key": {
|
||||
"B": {
|
||||
"I": {
|
||||
"item": "minecraft:iron_ingot"
|
||||
},
|
||||
"N": {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "szar:two_towers",
|
||||
"biomes": "#minecraft:is_overworld",
|
||||
"spawn_overrides": {},
|
||||
"step": "surface_structures",
|
||||
"terrain_adaptation": "beard_thin"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"structures": [
|
||||
{
|
||||
"structure": "szar:two_towers",
|
||||
"weight": 1
|
||||
}
|
||||
],
|
||||
"placement": {
|
||||
"type": "minecraft:random_spread",
|
||||
"spacing": 40,
|
||||
"separation": 28,
|
||||
"salt": 987654321
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user