twin
This commit is contained in:
@@ -6,7 +6,7 @@ minecraft_version=1.20.1
|
|||||||
yarn_mappings=1.20.1+build.10
|
yarn_mappings=1.20.1+build.10
|
||||||
loader_version=0.18.3
|
loader_version=0.18.3
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=1.0.11
|
mod_version=1.0.12
|
||||||
maven_group=dev.tggamesyt
|
maven_group=dev.tggamesyt
|
||||||
archives_base_name=szar
|
archives_base_name=szar
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|||||||
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.registry.tag.BiomeTags;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.sound.SoundEvents;
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.structure.StructurePieceType;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.util.ActionResult;
|
||||||
import net.minecraft.util.Formatting;
|
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.placementmodifier.SquarePlacementModifier;
|
||||||
import net.minecraft.world.gen.stateprovider.BlockStateProvider;
|
import net.minecraft.world.gen.stateprovider.BlockStateProvider;
|
||||||
import net.minecraft.world.gen.stateprovider.WeightedBlockStateProvider;
|
import net.minecraft.world.gen.stateprovider.WeightedBlockStateProvider;
|
||||||
|
import net.minecraft.world.gen.structure.StructureType;
|
||||||
import net.minecraft.world.poi.PointOfInterestType;
|
import net.minecraft.world.poi.PointOfInterestType;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
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 =
|
public static final Feature<CannabisPatchFeatureConfig> CANNABIS_PATCH =
|
||||||
Registry.register(
|
Registry.register(
|
||||||
Registries.FEATURE,
|
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",
|
"type": "minecraft:crafting_shaped",
|
||||||
"pattern": [
|
"pattern": [
|
||||||
"###",
|
"NNN",
|
||||||
"i i"
|
"I I"
|
||||||
],
|
],
|
||||||
"key": {
|
"key": {
|
||||||
"#": "minecraft:iron_nugget",
|
"I": {
|
||||||
"i": "minecraft:iron_ingot"
|
"item": "minecraft:iron_ingot"
|
||||||
|
},
|
||||||
|
"N": {
|
||||||
|
"item": "minecraft:iron_nugget"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"result": {
|
"result": {
|
||||||
"id": "szar:police_handcuff",
|
"item": "szar:police_handcuff",
|
||||||
"count": 1
|
"count": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"type": "minecraft:crafting_shaped",
|
"type": "minecraft:crafting_shaped",
|
||||||
"pattern": [
|
"pattern": [
|
||||||
"BBB",
|
"III",
|
||||||
"NNB"
|
"NNI"
|
||||||
],
|
],
|
||||||
"key": {
|
"key": {
|
||||||
"B": {
|
"I": {
|
||||||
"item": "minecraft:iron_ingot"
|
"item": "minecraft:iron_ingot"
|
||||||
},
|
},
|
||||||
"N": {
|
"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