Puddles 2.0.0: Now fully server-sided!

- Port to 1.21
- Utilize Polymer and ServerTranslationsAPI for fully server-side functionality (Doesn't even require resourcepacks)
- Instead of breaking, puddles will now create a splash effect when mined
- Puddles no longer slow down walking (Sprinting still gets interrupted; this is not fixable, closes #2)
- Fixed #13
- Fixed #11
This commit is contained in:
Martin Prokoph
2024-08-18 23:25:05 +02:00
parent f414be04ce
commit d115aadfe8
18 changed files with 225 additions and 209 deletions

View File

@@ -1,16 +1,26 @@
plugins {
id 'fabric-loom' version '1.3-SNAPSHOT'
id 'fabric-loom' version '1.7-SNAPSHOT'
id 'maven-publish'
id "me.shedaniel.unified-publishing" version "0.1.+"
}
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
archivesBaseName = project.archives_base_name
version = project.mod_version
group = project.maven_group
base {
archivesName = project.archives_base_name
loom {
}
repositories {
maven { url "https://api.modrinth.com/maven" }
maven { url "https://maven.terraformersmc.com/releases" }
maven { url "https://jitpack.io" }
maven {
url = "https://api.modrinth.com/maven"
}
maven { url 'https://maven.nucleoid.xyz' }
}
dependencies {
@@ -19,10 +29,15 @@ dependencies {
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modImplementation "maven.modrinth:midnightlib:${midnightlib_version}"
include "maven.modrinth:midnightlib:${midnightlib_version}"
modImplementation "maven.modrinth:midnightlib:${midnightlib_version}"
modImplementation include("eu.pb4:polymer-core:${polymer_version}")
modImplementation include("eu.pb4:polymer-blocks:${polymer_version}")
modImplementation include("eu.pb4:polymer-virtual-entity:${polymer_version}")
modImplementation include("xyz.nucleoid:server-translations-api:${server_translation_version}")
}
processResources {
@@ -34,7 +49,13 @@ processResources {
}
tasks.withType(JavaCompile).configureEach {
it.options.release = 17
// ensure that the encoding is set to UTF-8, no matter what the system default is
// this fixes some edge cases with special characters not displaying correctly
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
// If Javadoc is generated, this must be specified in that task too.
it.options.encoding = "UTF-8"
it.options.release = 21
}
java {
@@ -42,14 +63,11 @@ java {
// if it is present.
// If you remove this line, sources will not be generated.
withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
jar {
from("LICENSE") {
rename { "${it}_${project.base.archivesName.get()}"}
rename { "${it}_${project.archivesBaseName}"}
}
}
@@ -57,7 +75,13 @@ jar {
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
// add all the jars that should be included when publishing to maven
artifact(remapJar) {
builtBy remapJar
}
artifact(sourcesJar) {
builtBy remapSourcesJar
}
}
}
@@ -68,4 +92,56 @@ publishing {
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}
ext {
releaseChangelog = {
def changes = new StringBuilder()
changes << "## Puddles v$project.version for $project.minecraft_version\n[View the changelog](https://www.github.com/TeamMidnightDust/Puddles/commits/)"
def proc = "git log --max-count=1 --pretty=format:%s".execute()
proc.in.eachLine { line ->
def processedLine = line.toString()
if (!processedLine.contains("New translations") && !processedLine.contains("Merge") && !processedLine.contains("branch")) {
changes << "\n- ${processedLine.capitalize()}"
}
}
proc.waitFor()
return changes.toString()
}
}
unifiedPublishing {
project {
displayName = "Puddles v$project.version - Fabric $project.minecraft_version"
releaseType = "$project.release_type"
changelog = releaseChangelog()
gameVersions = []
gameLoaders = ["fabric","quilt"]
mainPublication remapJar
relations {
depends {
curseforge = "midnightlib"
modrinth = "midnightlib"
}
}
var CURSEFORGE_TOKEN = project.findProperty("CURSEFORGE_TOKEN") ?: System.getenv("CURSEFORGE_TOKEN")
if (CURSEFORGE_TOKEN != null) {
curseforge {
token = CURSEFORGE_TOKEN
id = rootProject.curseforge_id
gameVersions.addAll "Java 21", project.minecraft_version, project.supported_versions
}
}
var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN")
if (MODRINTH_TOKEN != null) {
modrinth {
token = MODRINTH_TOKEN
id = rootProject.modrinth_id
version = "$project.version"
gameVersions.addAll project.minecraft_version, project.supported_versions
}
}
}
}

View File

@@ -3,16 +3,21 @@ org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version=1.20.1
yarn_mappings=1.20.1+build.10
loader_version=0.14.21
minecraft_version=1.21
supported_versions=1.21.1
yarn_mappings=1.21+build.9
loader_version=0.15.11
# Mod Properties
mod_version = 1.2.2
mod_version = 2.0.0
maven_group = eu.midnightdust
archives_base_name = puddles
release_type=release
curseforge_id=463169
modrinth_id=535D1YoA
# Dependencies
fabric_version=0.86.1+1.20.1
midnightlib_version=0.5.2
fabric_version=0.100.7+1.21
midnightlib_version=1.5.8-fabric
polymer_version=0.9.6+1.21
server_translation_version=2.3.1+1.21-pre2

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View File

@@ -4,7 +4,7 @@ pluginManagement {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
mavenCentral()
maven { url "https://maven.architectury.dev/" }
gradlePluginPortal()
}
}
}

View File

@@ -2,26 +2,47 @@ package eu.midnightdust.puddles;
import eu.midnightdust.puddles.block.PuddleBlock;
import eu.midnightdust.puddles.config.PuddlesConfig;
import eu.pb4.polymer.core.api.item.PolymerBlockItem;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.BlockItem;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.entity.attribute.EntityAttributeInstance;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.network.packet.s2c.play.ParticleS2CPacket;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Identifier;
public class Puddles implements ModInitializer {
public static final String MOD_ID = "puddles";
private static final String ITEM_NAME = "puddle";
public static final Block Puddle = new PuddleBlock(Fluids.WATER, FabricBlockSettings.create());
public static final PuddleBlock Puddle = new PuddleBlock();
private final static EntityAttributeModifier entityAttributeModifier = new EntityAttributeModifier(id("puddle_speed"), 100, EntityAttributeModifier.Operation.ADD_VALUE);
@Override
public void onInitialize() {
PuddlesConfig.init(MOD_ID, PuddlesConfig.class);
Registry.register(Registries.BLOCK, new Identifier(MOD_ID, ITEM_NAME), Puddle);
Registry.register(Registries.ITEM, new Identifier(MOD_ID, ITEM_NAME), new BlockItem(Puddle, new Item.Settings()));
Registry.register(Registries.BLOCK, id("puddle"), Puddle);
Registry.register(Registries.ITEM, id("puddle"), new PolymerBlockItem(Puddle, new Item.Settings(), Items.POTION));
ServerTickEvents.END_WORLD_TICK.register(world -> world.getPlayers().forEach(player -> {
EntityAttributeInstance entityAttributeInstance = player.getAttributes().getCustomInstance(EntityAttributes.GENERIC_WATER_MOVEMENT_EFFICIENCY);
if (player.getBlockStateAtPos().getBlock() instanceof PuddleBlock) {
if (entityAttributeInstance != null) {
entityAttributeInstance.removeModifier(entityAttributeModifier);
entityAttributeInstance.addTemporaryModifier(entityAttributeModifier);
}
if (world.random.nextInt(30) == 0) player.playSoundToPlayer(SoundEvents.ENTITY_PLAYER_SWIM, SoundCategory.BLOCKS, 0.5f, 1.2f);
player.networkHandler.sendPacket(new ParticleS2CPacket(ParticleTypes.SPLASH, false, player.getBlockX() + 0.5f, player.getBlockY() + 0.1f, player.getBlockZ() + 0.5f, 0.5f, 0.1f, 0.5f, 1, 2));
} else if (player.isInFluid()) {
if (entityAttributeInstance != null) entityAttributeInstance.removeModifier(entityAttributeModifier);
}
}));
}
public static Identifier id(String path) {
return Identifier.of(MOD_ID, path);
}
}

View File

@@ -1,31 +0,0 @@
package eu.midnightdust.puddles;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
import net.fabricmc.fabric.impl.client.rendering.ColorProviderRegistryImpl;
import net.minecraft.block.Blocks;
import net.minecraft.world.biome.Biome;
import java.util.Objects;
import static eu.midnightdust.puddles.Puddles.*;
public class PuddlesClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
// Colored Puddle Items & Blocks
ClientTickEvents.END_CLIENT_TICK.register(client -> {
int waterColor;
if (client.world != null && client.player != null) {
Biome biome = client.world.getBiome(client.player.getBlockPos()).value();
waterColor = biome.getWaterColor();
} else waterColor = 4159204;
ColorProviderRegistry.ITEM.register((stack, tintIndex) -> waterColor, Puddles.Puddle);
});
ColorProviderRegistry.BLOCK.register((state, view, pos, tintIndex) -> Objects.requireNonNull(ColorProviderRegistryImpl.BLOCK.get(Blocks.WATER)).getColor(state, view, pos, tintIndex), Puddle);
}
}

View File

@@ -1,27 +1,38 @@
package eu.midnightdust.puddles.block;
import eu.midnightdust.puddles.Puddles;
import eu.midnightdust.puddles.config.PuddlesConfig;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.*;
import eu.pb4.polymer.core.api.block.PolymerBlock;
import eu.pb4.polymer.virtualentity.api.BlockWithElementHolder;
import eu.pb4.polymer.virtualentity.api.ElementHolder;
import eu.pb4.polymer.virtualentity.api.elements.InteractionElement;
import eu.pb4.polymer.virtualentity.api.elements.VirtualElement;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.FluidBlock;
import net.minecraft.block.ShapeContext;
import net.minecraft.component.ComponentMap;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.PotionContentsComponent;
import net.minecraft.entity.ai.pathing.NavigationType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.*;
import net.minecraft.item.*;
import net.minecraft.loot.context.LootContext;
import net.minecraft.potion.PotionUtil;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.network.packet.s2c.play.ParticleS2CPacket;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.potion.Potions;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.stat.Stats;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
@@ -30,32 +41,22 @@ import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.WorldView;
import java.util.Collections;
import java.util.List;
@SuppressWarnings("deprecation")
public class PuddleBlock extends Block {
protected final FlowableFluid fluid;
public static final VoxelShape COLLISION_SHAPE;
public PuddleBlock(FlowableFluid fluid, AbstractBlock.Settings settings) {
super(settings);
this.fluid = fluid;
public class PuddleBlock extends Block implements PolymerBlock, BlockWithElementHolder {
public PuddleBlock() {
super(AbstractBlock.Settings.copy(Blocks.SHORT_GRASS));
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
public ItemActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
ItemStack itemStack = player.getStackInHand(hand);
if (itemStack.isEmpty()) {
return ActionResult.PASS;
return ItemActionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
} else {
Item item = itemStack.getItem();
ItemStack waterBottleStack;
if (item == Items.GLASS_BOTTLE) {
if (itemStack.getItem() == Items.GLASS_BOTTLE) {
if (!world.isClient) {
if (!player.isCreative()) {
waterBottleStack = PotionUtil.setPotion(new ItemStack(Items.POTION), Potions.WATER);
player.incrementStat(Stats.USE_CAULDRON);
ItemStack waterBottleStack = new ItemStack(Items.POTION);
waterBottleStack.applyComponentsFrom(ComponentMap.builder().add(DataComponentTypes.POTION_CONTENTS, PotionContentsComponent.DEFAULT.with(Potions.WATER)).build());
itemStack.decrement(1);
if (itemStack.isEmpty()) {
player.setStackInHand(hand, waterBottleStack);
@@ -69,19 +70,20 @@ public class PuddleBlock extends Block {
world.playSound(null, pos, SoundEvents.ITEM_BOTTLE_FILL, SoundCategory.BLOCKS, 1.0F, 1.0F);
world.setBlockState(pos, Blocks.AIR.getDefaultState());
}
return ActionResult.success(world.isClient);
return ItemActionResult.success(world.isClient);
}
else return ActionResult.FAIL;
else return ItemActionResult.FAIL;
}
}
@Override
public boolean hasRandomTicks(BlockState state) {
return true;
}
@Override
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
if (!world.isRaining() && random.nextInt(10000 / PuddlesConfig.evaporationChance) == 0) {
if (!world.isRaining() && random.nextInt(1000 / PuddlesConfig.evaporationChance) == 0) {
world.setBlockState(pos, Blocks.AIR.getDefaultState());
}
@@ -92,77 +94,67 @@ public class PuddleBlock extends Block {
public VoxelShape getCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return VoxelShapes.empty();
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return COLLISION_SHAPE;
}
@Override
public VoxelShape getCullingShape(BlockState state, BlockView world, BlockPos pos) {
return VoxelShapes.empty();
}
public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) {
@Override
public boolean canPathfindThrough(BlockState state, NavigationType type) {
return true;
}
public FluidState getFluidState(BlockState state) {
return fluid.getFlowing(1,false);
}
@Environment(EnvType.CLIENT)
public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) {
return stateFrom.getFluidState().getFluid().matchesType(this.fluid);
}
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.INVISIBLE;
}
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
return Collections.emptyList();
}
@Override
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
if (world.getBlockState(pos) == Blocks.AIR.getDefaultState() || world.getBlockState(pos) == Puddles.Puddle.getDefaultState()) {
if (world.getBlockState(pos).getBlock() == Blocks.AIR) {
int i;
// Check if there are fluids on the sides or corners of the block above
// Check if there are puddles on the sides of the block above
for (i = 2; i < 6; ++i) {
BlockPos pos1 = pos.up();
BlockPos pos2 = pos1.offset(Direction.byId(i));
if (!world.getFluidState(pos1.offset(Direction.byId(i))).isEmpty()) {
// When sides of the block above have water don't place the puddle
return false;
}
if (!world.getFluidState(pos2.offset(Direction.byId(i).rotateYClockwise())).isEmpty()) {
// When corners of the block above have water don't place the puddle
if (world.getBlockState(pos1.offset(Direction.byId(i))).getBlock() instanceof PuddleBlock) {
// When sides of the block above have a puddle, don't place the puddle
return false;
}
}
// Check if there are fluids on the sides or corners of the block below
// Check if there are puddles on the sides of the block below
for (i = 2; i < 6; ++i) {
BlockPos pos1 = pos.down();
BlockPos pos2 = pos1.offset(Direction.byId(i));
if (!world.getFluidState(pos1.offset(Direction.byId(i))).isEmpty()) {
// When sides of the block below have water don't place the puddle
return false;
}
if (!world.getFluidState(pos2.offset(Direction.byId(i).rotateYClockwise())).isEmpty()) {
// When corners of the block below have water don't place the puddle
if (world.getBlockState(pos1.offset(Direction.byId(i))).getBlock() instanceof PuddleBlock) {
// When sides of the block below have a puddle, don't place the puddle
return false;
}
}
return world.getBlockState(pos.down()).isSideSolidFullSquare(world, pos, Direction.UP);
}
// When there's already another block at the position don't place the puddle
else return false;
return world.getBlockState(pos.down()).isSideSolidFullSquare(world, pos, Direction.UP);
}
public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom) {
return !state.canPlaceAt(world, pos) ? Blocks.AIR.getDefaultState() : super.getStateForNeighborUpdate(state, direction, newState, world, pos, posFrom);
}
static {
COLLISION_SHAPE = net.minecraft.block.Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 0.5D, 16.0D);
@Override
public BlockState getPolymerBlockState(BlockState state) {
return Blocks.WATER.getDefaultState().with(FluidBlock.LEVEL, 7);
}
public ElementHolder createElementHolder(ServerWorld world, BlockPos pos, BlockState initialBlockState) {
ElementHolder holder = new ElementHolder();
var interactionElement = new InteractionElement(new VirtualElement.InteractionHandler() {
@Override
public void interact(ServerPlayerEntity player, Hand hand) {
world.getBlockState(pos).onUseWithItem(player.getStackInHand(hand), world, player, hand, new BlockHitResult(pos.toCenterPos(), Direction.UP, pos, false));
}
@Override
public void attack(ServerPlayerEntity player) {
player.playSoundToPlayer(SoundEvents.ENTITY_PLAYER_SPLASH, SoundCategory.BLOCKS, 0.8f, 1.3f);
player.networkHandler.sendPacket(new ParticleS2CPacket(ParticleTypes.SPLASH, false, pos.getX() + 0.5f, pos.getY() + 0.1f, pos.getZ() + 0.5f, 0.5f, 0.1f, 0.5f, 1, 2));
}
});
interactionElement.setSize(1f, 0.06241f);
interactionElement.setOffset(new Vec3d(0d, -0.5d, 0d));
holder.addElement(interactionElement);
return holder;
}
}

View File

@@ -3,10 +3,8 @@ package eu.midnightdust.puddles.config;
import eu.midnightdust.lib.config.MidnightConfig;
public class PuddlesConfig extends MidnightConfig {
@Entry(max = 10000) // Enable or disable hats for contributors, friends and donors.
public static int puddleSpawnRate = 1;
@Entry(max = 10000)
public static int snowStackChance = 1;
@Entry(max = 10000)
public static int evaporationChance = 5;
}
@Entry(isSlider = true, min = 0, max = 1000)
public static int puddleSpawnRate = 10;
@Entry(isSlider = true, min = 0, max = 1000)
public static int evaporationChance = 100;
}

View File

@@ -2,17 +2,17 @@ package eu.midnightdust.puddles.mixin;
import eu.midnightdust.puddles.Puddles;
import eu.midnightdust.puddles.config.PuddlesConfig;
import net.minecraft.block.Blocks;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.profiler.Profiler;
import net.minecraft.world.*;
import net.minecraft.world.Heightmap;
import net.minecraft.world.MutableWorldProperties;
import net.minecraft.world.World;
import net.minecraft.world.chunk.WorldChunk;
import net.minecraft.world.dimension.DimensionType;
import org.spongepowered.asm.mixin.Mixin;
@@ -24,8 +24,6 @@ import java.util.function.Supplier;
@Mixin(ServerWorld.class)
public abstract class MixinServerWorld extends World {
protected MixinServerWorld(MutableWorldProperties properties, RegistryKey<World> registryRef, DynamicRegistryManager registryManager, RegistryEntry<DimensionType> dimensionEntry, Supplier<Profiler> profiler, boolean isClient, boolean debugWorld, long biomeAccess, int maxChainedNeighborUpdates) {
super(properties, registryRef, registryManager, dimensionEntry, profiler, isClient, debugWorld, biomeAccess, maxChainedNeighborUpdates);
}
@@ -41,27 +39,14 @@ public abstract class MixinServerWorld extends World {
if (PuddlesConfig.puddleSpawnRate != 0) {
profiler.push("puddles");
if (bl && random.nextInt(10000 / PuddlesConfig.puddleSpawnRate) == 0) {
if (bl && random.nextInt(100000 / PuddlesConfig.puddleSpawnRate) == 0) {
pos = this.getTopPosition(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, getRandomPosInChunk(x, 0, z, 15));
if (this.hasRain(pos) && getBlockState(pos.down()).isSideSolidFullSquare(this, pos, Direction.UP) && Puddles.Puddle.canPlaceAt(null,this,pos)) {
if (this.hasRain(pos) && getBlockState(pos.down()).isSideSolidFullSquare(this, pos, Direction.UP) &&
Puddles.Puddle.canPlaceAt(null,this,pos)) {
setBlockState(pos, Puddles.Puddle.getDefaultState());
}
}
profiler.pop();
}
if (PuddlesConfig.snowStackChance != 0) {
profiler.push("extra_snow");
if (bl && random.nextInt(10000 / PuddlesConfig.snowStackChance) == 0) {
pos = this.getTopPosition(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, getRandomPosInChunk(x, 0, z, 15));
if (this.getBlockState(pos).getBlock() == Blocks.SNOW && getBlockState(pos.down()).isSideSolidFullSquare(this, pos, Direction.UP)) {
int layer = getBlockState(pos).get(Properties.LAYERS);
if (layer < 5) {
setBlockState(pos, Blocks.SNOW.getDefaultState().with(Properties.LAYERS, layer + 1));
}
}
}
profiler.pop();
}
}
}

View File

@@ -1,7 +0,0 @@
{
"variants": {
"": {
"model": "puddles:block/puddle"
}
}
}

View File

@@ -0,0 +1,5 @@
{
"puddles.midnightconfig.title": "Puddles Konfiguration",
"puddles.midnightconfig.puddleSpawnRate": "Pfützen-Häufigkeit",
"puddles.midnightconfig.evaporationChance": "Verdunstungswahrscheinlichkeit"
}

View File

@@ -1,7 +1,5 @@
{
"block.puddles.puddle":"Puddle",
"puddles.midnightconfig.title": "Puddles Config",
"puddles.midnightconfig.puddleSpawnRate": "Puddle Spawn Rate",
"puddles.midnightconfig.snowStackChance": "Snow Stack Chance",
"puddles.midnightconfig.evaporationChance": "Evaporation Chance"
}

View File

@@ -1,7 +0,0 @@
{
"credit": "made by Motschen",
"parent": "block/block",
"textures": {
"particle": "block/water_still"
}
}

View File

@@ -1,22 +0,0 @@
{
"credit": "made by Motschen",
"parent": "block/block",
"textures": {
"0": "block/water_still",
"particle": "block/water_still"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 1, 16],
"faces": {
"north": {"uv": [0, 0, 16, 1], "texture": "#0", "tintindex": 0},
"east": {"uv": [0, 0, 16, 1], "texture": "#0", "tintindex": 0},
"south": {"uv": [0, 0, 16, 1], "texture": "#0", "tintindex": 0},
"west": {"uv": [0, 0, 16, 1], "texture": "#0", "tintindex": 0},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "tintindex": 0},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "tintindex": 0}
}
}
]
}

View File

@@ -0,0 +1,3 @@
{
"block.puddles.puddle":"Pfütze"
}

View File

@@ -0,0 +1,3 @@
{
"block.puddles.puddle":"Puddle"
}

View File

@@ -4,7 +4,7 @@
"version": "${version}",
"name": "Puddles",
"description": "Adds puddles. Compatible with your favorite shaderpacks & mods!",
"description": "Adds puddles. Now fully server-sided!",
"authors": [
"Motschen",
"TeamMidnightDust",
@@ -23,9 +23,6 @@
"entrypoints": {
"main": [
"eu.midnightdust.puddles.Puddles"
],
"client": [
"eu.midnightdust.puddles.PuddlesClient"
]
},

View File

@@ -1,7 +1,7 @@
{
"required": true,
"package": "eu.midnightdust.puddles.mixin",
"compatibilityLevel": "JAVA_8",
"compatibilityLevel": "JAVA_21",
"mixins": [
"MixinServerWorld"
],