end update vol 1
@@ -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=26.3.27
|
||||
mod_version=26.3.28
|
||||
maven_group=dev.tggamesyt
|
||||
archives_base_name=szar
|
||||
# Dependencies
|
||||
|
||||
84
src/main/java/dev/tggamesyt/szar/ChorusEndStone.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package dev.tggamesyt.szar;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.Fertilizable;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldView;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.feature.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ChorusEndStone extends EndSpreadableBlock implements Fertilizable {
|
||||
|
||||
public ChorusEndStone(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFertilizable(WorldView world, BlockPos pos, BlockState state, boolean isClient) {
|
||||
return world.getBlockState(pos.up()).isAir();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canGrow(World world, Random random, BlockPos pos, BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
|
||||
BlockPos start = pos.up();
|
||||
|
||||
// your custom placed feature (we'll register this next)
|
||||
var registry = world.getRegistryManager().get(RegistryKeys.PLACED_FEATURE);
|
||||
|
||||
var smallChorusFeature = registry.getEntry(Szar.SMALL_CHORUS_PLACED);
|
||||
|
||||
outer:
|
||||
for (int i = 0; i < 128; i++) {
|
||||
BlockPos target = start;
|
||||
|
||||
for (int j = 0; j < i / 16; j++) {
|
||||
target = target.add(
|
||||
random.nextInt(3) - 1,
|
||||
(random.nextInt(3) - 1) * random.nextInt(3) / 2,
|
||||
random.nextInt(3) - 1
|
||||
);
|
||||
|
||||
if (!world.getBlockState(target.down()).isOf(this)
|
||||
|| world.getBlockState(target).isFullCube(world, target)) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
BlockState targetState = world.getBlockState(target);
|
||||
|
||||
if (targetState.isAir()) {
|
||||
|
||||
// 🌟 Rare: spawn chorus flower (~1/12 chance)
|
||||
if (random.nextInt(12) == 0) {
|
||||
world.setBlockState(target, Blocks.CHORUS_FLOWER.getDefaultState());
|
||||
continue;
|
||||
}
|
||||
|
||||
// 🌿 Common: spawn your custom feature
|
||||
if (smallChorusFeature.isPresent()) {
|
||||
smallChorusFeature.get().value().generateUnregistered(
|
||||
world,
|
||||
world.getChunkManager().getChunkGenerator(),
|
||||
random,
|
||||
target
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
77
src/main/java/dev/tggamesyt/szar/EndSpreadableBlock.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package dev.tggamesyt.szar;
|
||||
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.registry.tag.FluidTags;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.WorldView;
|
||||
import net.minecraft.world.chunk.light.ChunkLightProvider;
|
||||
|
||||
public abstract class EndSpreadableBlock extends SnowyBlock {
|
||||
|
||||
protected EndSpreadableBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
private static boolean canSurvive(BlockState state, WorldView world, BlockPos pos) {
|
||||
BlockPos up = pos.up();
|
||||
BlockState upState = world.getBlockState(up);
|
||||
|
||||
if (upState.isOf(Blocks.SNOW) && upState.get(SnowBlock.LAYERS) == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (upState.getFluidState().getLevel() == 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int opacity = ChunkLightProvider.getRealisticOpacity(
|
||||
world, state, pos, upState, up, Direction.UP,
|
||||
upState.getOpacity(world, up)
|
||||
);
|
||||
|
||||
return opacity < world.getMaxLightLevel();
|
||||
}
|
||||
|
||||
private static boolean canSpread(BlockState state, WorldView world, BlockPos pos) {
|
||||
BlockPos up = pos.up();
|
||||
return canSurvive(state, world, pos)
|
||||
&& !world.getFluidState(up).isIn(FluidTags.WATER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
||||
|
||||
// ❌ Decay (like grass → dirt)
|
||||
if (!canSurvive(state, world, pos)) {
|
||||
world.setBlockState(pos, Blocks.END_STONE.getDefaultState());
|
||||
return;
|
||||
}
|
||||
|
||||
// 🌱 Spread
|
||||
if (world.getLightLevel(pos.up()) >= 9) {
|
||||
BlockState spreadState = this.getDefaultState();
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
BlockPos target = pos.add(
|
||||
random.nextInt(3) - 1,
|
||||
random.nextInt(5) - 3,
|
||||
random.nextInt(3) - 1
|
||||
);
|
||||
|
||||
if (world.getBlockState(target).isOf(Blocks.END_STONE)
|
||||
&& canSpread(spreadState, world, target)) {
|
||||
|
||||
world.setBlockState(
|
||||
target,
|
||||
spreadState.with(SNOWY,
|
||||
world.getBlockState(target.up()).isOf(Blocks.SNOW)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/main/java/dev/tggamesyt/szar/SmallChorusBlock.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package dev.tggamesyt.szar;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.PlantBlock;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockView;
|
||||
|
||||
public class SmallChorusBlock extends PlantBlock {
|
||||
|
||||
public SmallChorusBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canPlantOnTop(BlockState floor, BlockView world, BlockPos pos) {
|
||||
return floor.isOf(Szar.CHORUS_ENDSTONE);
|
||||
}
|
||||
}
|
||||
@@ -386,6 +386,9 @@ public class Szar implements ModInitializer {
|
||||
entries.add(Szar.BEAN);
|
||||
entries.add(Szar.CAN_OF_BEANS);
|
||||
entries.add(Szar.ALMOND_WATER);
|
||||
// end update
|
||||
entries.add(Szar.CHORUS_ENDSTONE_ITEM);
|
||||
entries.add(Szar.SMALL_CHORUS_ITEM);
|
||||
// blueprint stuff
|
||||
entries.add(BlueprintBlocks.BLUEPRINT);
|
||||
entries.add(BlueprintBlocks.BLUEPRINT_DOOR_ITEM);
|
||||
@@ -1026,7 +1029,7 @@ public class Szar implements ModInitializer {
|
||||
});
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||
dispatcher.register(
|
||||
LiteralArgumentBuilder.<ServerCommandSource>literal("szar")
|
||||
LiteralArgumentBuilder.<ServerCommandSource>literal(MOD_ID)
|
||||
.requires(context -> context.hasPermissionLevel(2))
|
||||
|
||||
// /szar ny
|
||||
@@ -1444,7 +1447,30 @@ public class Szar implements ModInitializer {
|
||||
public static final Identifier CHESS_CLOSE_SCREEN = new Identifier(MOD_ID, "chess_close");
|
||||
|
||||
public static final Map<UUID, BlockPos> chessActivePlayers = new java.util.HashMap<>();
|
||||
|
||||
public static final RegistryKey<ConfiguredFeature<?, ?>> SMALL_CHORUS_CONFIGURED =
|
||||
RegistryKey.of(RegistryKeys.CONFIGURED_FEATURE, new Identifier(MOD_ID, "small_chorus"));
|
||||
public static final RegistryKey<PlacedFeature> SMALL_CHORUS_PLACED =
|
||||
RegistryKey.of(RegistryKeys.PLACED_FEATURE, new Identifier(MOD_ID, "small_chorus_patch"));
|
||||
public static final Block CHORUS_ENDSTONE = Registry.register(
|
||||
Registries.BLOCK,
|
||||
new Identifier(MOD_ID, "chorus_endstone"),
|
||||
new Block(FabricBlockSettings.copyOf(Blocks.END_STONE))
|
||||
);
|
||||
public static final Item CHORUS_ENDSTONE_ITEM = Registry.register(
|
||||
Registries.ITEM,
|
||||
new Identifier(MOD_ID, "chorus_endstone"),
|
||||
new BlockItem(CHORUS_ENDSTONE, new FabricItemSettings())
|
||||
);
|
||||
public static final Block SMALL_CHORUS = Registry.register(
|
||||
Registries.BLOCK,
|
||||
new Identifier(MOD_ID, "small_chorus"),
|
||||
new SmallChorusBlock(FabricBlockSettings.copyOf(Blocks.GRASS))
|
||||
);
|
||||
public static final Item SMALL_CHORUS_ITEM = Registry.register(
|
||||
Registries.ITEM,
|
||||
new Identifier(MOD_ID, "small_chorus"),
|
||||
new BlockItem(SMALL_CHORUS, new FabricItemSettings())
|
||||
);
|
||||
// Blocks
|
||||
public static final TrackerBlock TRACKER_BLOCK = Registry.register(
|
||||
Registries.BLOCK, new Identifier(MOD_ID, "tracker"),
|
||||
@@ -2532,7 +2558,7 @@ public class Szar implements ModInitializer {
|
||||
MinecraftServer server = serverPlayer.getServer();
|
||||
if (server == null) return;
|
||||
|
||||
if (!advancement.equals("szar")) {
|
||||
if (!advancement.equals(MOD_ID)) {
|
||||
grantAdvancement(player, "szar");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package dev.tggamesyt.szar.mixin;
|
||||
|
||||
import dev.tggamesyt.szar.Szar;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.ChorusFlowerBlock;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.tag.TagKey;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.WorldView;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ChorusFlowerBlock.class)
|
||||
public abstract class ChorusFlowerBlockMixin {
|
||||
|
||||
@Unique
|
||||
private static final TagKey<Block> ENDSTONES =
|
||||
TagKey.of(RegistryKeys.BLOCK, new Identifier(Szar.MOD_ID, "endstones"));
|
||||
|
||||
/**
|
||||
* 🔥 Redirect EVERY BlockState.isOf call inside ChorusFlowerBlock
|
||||
* and replace END_STONE checks with tag checks
|
||||
*/
|
||||
@Redirect(
|
||||
method = {
|
||||
"canPlaceAt",
|
||||
"randomTick",
|
||||
"generate*",
|
||||
"scheduledTick"
|
||||
},
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/block/BlockState;isOf(Lnet/minecraft/block/Block;)Z"
|
||||
)
|
||||
)
|
||||
private boolean replaceEndStoneChecks(BlockState state, Block block) {
|
||||
|
||||
// Replace ONLY END_STONE checks
|
||||
if (block == Blocks.END_STONE) {
|
||||
return state.isIn(ENDSTONES);
|
||||
}
|
||||
|
||||
// Everything else stays vanilla
|
||||
return state.isOf(block);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package dev.tggamesyt.szar.mixin;
|
||||
|
||||
import dev.tggamesyt.szar.Szar;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.ChorusPlantBlock;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.tag.TagKey;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(ChorusPlantBlock.class)
|
||||
public abstract class ChorusPlantBlockMixin {
|
||||
|
||||
@Unique
|
||||
private static final TagKey<Block> ENDSTONES =
|
||||
TagKey.of(RegistryKeys.BLOCK, new Identifier(Szar.MOD_ID, "endstones"));
|
||||
|
||||
/**
|
||||
* 🔥 Replace ALL END_STONE checks in ChorusPlantBlock
|
||||
*/
|
||||
@Redirect(
|
||||
method = {
|
||||
"withConnectionProperties",
|
||||
"getStateForNeighborUpdate",
|
||||
"canPlaceAt"
|
||||
},
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/block/BlockState;isOf(Lnet/minecraft/block/Block;)Z"
|
||||
)
|
||||
)
|
||||
private boolean replaceEndStoneChecks(BlockState state, Block block) {
|
||||
|
||||
// Replace END_STONE with your tag
|
||||
if (block == Blocks.END_STONE) {
|
||||
return state.isIn(ENDSTONES);
|
||||
}
|
||||
|
||||
return state.isOf(block);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "szar:block/chorus_endstone"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "szar:block/small_chorus"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -198,5 +198,8 @@
|
||||
"block.szar.blueprint_trapdoor": "Blueprint Trapdoor",
|
||||
"block.szar.blueprint_wall": "Blueprint Wall",
|
||||
"block.szar.blueprint_fence": "Blueprint Fence",
|
||||
"item.szar.blueprint": "Blueprint"
|
||||
"item.szar.blueprint": "Blueprint",
|
||||
|
||||
"block.szar.chorus_endstone": "Chorus EndStone",
|
||||
"block.szar.small_chorus": "Small Chorus"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_bottom_top",
|
||||
"textures": {
|
||||
"side": "szar:block/end_stone_grass",
|
||||
"bottom": "szar:block/end_stone",
|
||||
"top": "szar:block/chorus_top"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "block/cross",
|
||||
"textures": {
|
||||
"cross": "szar:block/small_chorus"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"parent": "szar:block/chorus_endstone"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "szar:block/small_chorus"
|
||||
}
|
||||
}
|
||||
BIN
src/main/resources/assets/szar/textures/block/chorus_flower.png
Normal file
|
After Width: | Height: | Size: 325 B |
|
After Width: | Height: | Size: 328 B |
BIN
src/main/resources/assets/szar/textures/block/chorus_plant.png
Normal file
|
After Width: | Height: | Size: 300 B |
BIN
src/main/resources/assets/szar/textures/block/chorus_shuffle.png
Normal file
|
After Width: | Height: | Size: 604 B |
|
After Width: | Height: | Size: 664 B |
BIN
src/main/resources/assets/szar/textures/block/chorus_top.png
Normal file
|
After Width: | Height: | Size: 645 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 823 B |
BIN
src/main/resources/assets/szar/textures/block/choruscolor.png
Normal file
|
After Width: | Height: | Size: 904 B |
BIN
src/main/resources/assets/szar/textures/block/end_stone.png
Normal file
|
After Width: | Height: | Size: 270 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 177 B |
|
After Width: | Height: | Size: 560 B |
|
After Width: | Height: | Size: 795 B |
BIN
src/main/resources/assets/szar/textures/block/small_chorus.png
Normal file
|
After Width: | Height: | Size: 612 B |
7
src/main/resources/data/szar/tags/blocks/endstones.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"minecraft:end_stone",
|
||||
"szar:chorus_endstone"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"type": "minecraft:random_patch",
|
||||
"config": {
|
||||
"feature": {
|
||||
"feature": {
|
||||
"type": "minecraft:simple_block",
|
||||
"config": {
|
||||
"to_place": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "szar:small_chorus_block"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"placement": [
|
||||
{
|
||||
"type": "minecraft:block_predicate_filter",
|
||||
"predicate": {
|
||||
"type": "minecraft:matching_blocks",
|
||||
"blocks": "minecraft:air"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tries": 32,
|
||||
"xz_spread": 7,
|
||||
"y_spread": 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"feature": "szar:small_chorus",
|
||||
"placement": [
|
||||
{ "type": "minecraft:count", "count": 5 },
|
||||
{ "type": "minecraft:in_square" },
|
||||
{ "type": "minecraft:heightmap", "heightmap": "WORLD_SURFACE_WG" },
|
||||
{ "type": "minecraft:biome" }
|
||||
]
|
||||
}
|
||||
@@ -4,6 +4,8 @@
|
||||
"package": "dev.tggamesyt.szar.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"ChorusFlowerBlockMixin",
|
||||
"ChorusPlantBlockMixin",
|
||||
"CraftingScreenHandlerMixin",
|
||||
"CraftingScreenHandlerMixin2",
|
||||
"EntityCollisionMixin",
|
||||
|
||||