diff --git a/gradle.properties b/gradle.properties index ebf852059..7855cdb43 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ modName=DynamicTrees modId=dynamictrees -modVersion=1.3.0-BETA15 +modVersion=1.3.2 group=com.ferreusveritas.dynamictrees @@ -16,7 +16,7 @@ ccVersion=1.109.4 ssVersion=4761603 jadeVersion=4986594 -versionType=beta +versionType=release # Path of update checker relative to version info file updateCheckerPath=DynamicTrees.json diff --git a/src/main/java/com/ferreusveritas/dynamictrees/api/registry/TypedRegistry.java b/src/main/java/com/ferreusveritas/dynamictrees/api/registry/TypedRegistry.java index 4141668bb..ecbe3c8e3 100644 --- a/src/main/java/com/ferreusveritas/dynamictrees/api/registry/TypedRegistry.java +++ b/src/main/java/com/ferreusveritas/dynamictrees/api/registry/TypedRegistry.java @@ -159,7 +159,7 @@ public V decode(final JsonObject jsonObject) { } - public static JsonObject putJsonRegistryName(final JsonObject jsonObject, final ResourceLocation registryName) { + public synchronized static JsonObject putJsonRegistryName(final JsonObject jsonObject, final ResourceLocation registryName) { jsonObject.add(Resources.RESOURCE_LOCATION.toString(), new JsonPrimitive(registryName.toString())); return jsonObject; } diff --git a/src/main/java/com/ferreusveritas/dynamictrees/block/branch/BranchBlock.java b/src/main/java/com/ferreusveritas/dynamictrees/block/branch/BranchBlock.java index 8d646d864..8ee47c37b 100644 --- a/src/main/java/com/ferreusveritas/dynamictrees/block/branch/BranchBlock.java +++ b/src/main/java/com/ferreusveritas/dynamictrees/block/branch/BranchBlock.java @@ -24,6 +24,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.BlockTags; import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionHand; @@ -576,19 +577,30 @@ public void onRemove(BlockState state, Level level, BlockPos pos, BlockState new return; } - if (toBlock == Blocks.AIR) { // Block was set to air improperly. - level.setBlock(pos, state, 0); // Set the block back and attempt a proper breaking. - this.sloppyBreak(level, pos, DestroyType.VOID); - this.setBlockStateIgnored(level, pos, BlockStates.AIR, 2); // Set back to air in case the sloppy break failed to do so. - return; + boolean foundFire = toBlockState.is(BlockTags.FIRE); + if (!foundFire){ + for (Direction offset : Direction.values()){ + BlockPos offPos = pos.offset(offset.getNormal()); + if (level.getBlockState(offPos).is(BlockTags.FIRE)){ + foundFire = true; + break; + } + } } - if (toBlock == Blocks.FIRE) { // Block has burned. + + if (foundFire) { // Block has burned. level.setBlock(pos, state, 0); // Set the branch block back and attempt a proper breaking. this.sloppyBreak(level, pos, DestroyType.FIRE); // Applies fire effects to falling branches. //this.setBlockStateIgnored(level, pos, Blocks.FIRE.getDefaultState(), 2); // Disabled because the fire is too aggressive. this.setBlockStateIgnored(level, pos, BlockStates.AIR, 2); // Set back to air instead. return; + } else if (toBlock == Blocks.AIR){ + level.setBlock(pos, state, 0); // Set the block back and attempt a proper breaking. + this.sloppyBreak(level, pos, DestroyType.VOID); + this.setBlockStateIgnored(level, pos, BlockStates.AIR, 2); // Set back to air in case the sloppy break failed to do so. + return; } + if (/*!toBlock.entity(toBlockState) && */level.getBlockEntity(pos) == null) { // Block seems to be a pure BlockState based block. level.setBlock(pos, state, 0); // Set the branch block back and attempt a proper breaking. this.sloppyBreak(level, pos, DestroyType.VOID); diff --git a/src/main/java/com/ferreusveritas/dynamictrees/entity/animation/FalloverAnimationHandler.java b/src/main/java/com/ferreusveritas/dynamictrees/entity/animation/FalloverAnimationHandler.java index 07f7ccfa7..151f8b233 100644 --- a/src/main/java/com/ferreusveritas/dynamictrees/entity/animation/FalloverAnimationHandler.java +++ b/src/main/java/com/ferreusveritas/dynamictrees/entity/animation/FalloverAnimationHandler.java @@ -7,12 +7,16 @@ import com.ferreusveritas.dynamictrees.entity.FallingTreeEntity; import com.ferreusveritas.dynamictrees.init.DTConfigs; import com.ferreusveritas.dynamictrees.tree.species.Species; +import com.ferreusveritas.dynamictrees.util.BranchDestructionData; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Axis; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.particles.BlockParticleOption; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.sounds.SoundEvent; import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; @@ -22,7 +26,6 @@ import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import org.joml.Vector3f; import java.util.HashSet; import java.util.List; @@ -77,6 +80,79 @@ protected void playFallThroughWaterSound(FallingTreeEntity entity){ } } + private Vec3 rotateAroundAxis(Vec3 in, Vec3 axis, double theta){ + double x = in.x; + double y = in.y; + double z = in.z; + double u = axis.x; + double v = axis.y; + double w = axis.z; + double v1 = u * x + v * y + w * z; + double xPrime = u* v1 *(1d - Math.cos(theta)) + + x*Math.cos(theta) + + (-w*y + v*z)*Math.sin(theta); + double yPrime = v* v1 *(1d - Math.cos(theta)) + + y*Math.cos(theta) + + (w*x - u*z)*Math.sin(theta); + double zPrime = w* v1 *(1d - Math.cos(theta)) + + z*Math.cos(theta) + + (-v*x + u*y)*Math.sin(theta); + return new Vec3(xPrime, yPrime, zPrime); + } + + protected void flingLeavesParticles(FallingTreeEntity entity, float fallSpeed){ + int bounces = getData(entity).bounces; + if (bounces > 1) return; + int maxParticleBlocks = DTConfigs.MAX_FALLING_TREE_LEAVES_PARTICLES.get(); + if (maxParticleBlocks == 0) return; + + BranchDestructionData data = entity.getDestroyData(); + Direction.Axis toolAxis = data.toolDir.getAxis(); + if (toolAxis == Direction.Axis.Y) return; //this one isn't possible anyways + + double limitChance = 1; + if (entity.getDestroyData().getNumLeaves() > maxParticleBlocks) + limitChance = maxParticleBlocks / (double)entity.getDestroyData().getNumLeaves(); + limitChance *= Math.exp(-bounces); + + RandomSource rand = entity.level().random; + int particleCount = bounces == 0 ? (int)(fallSpeed*5) : 1; + + Vec3 angularVel = entity.getForward().scale(fallSpeed * -data.toolDir.getAxisDirection().getStep()); + //on the X axis, the entity forward is rotated, so we rotate the angular velocity back + if (toolAxis == Direction.Axis.X) angularVel = new Vec3(angularVel.z, angularVel.x, angularVel.y); + + for (int i=0; i 0 && testCollision(entity)) { playEndSound(entity); + flingLeavesParticles(entity, fallSpeed); addRotation(entity, -fallSpeed);//pull back to before the collision getData(entity).bounces++; fallSpeed *= -AnimationConstants.TREE_ELASTICITY;//bounce with elasticity diff --git a/src/main/java/com/ferreusveritas/dynamictrees/init/DTConfigs.java b/src/main/java/com/ferreusveritas/dynamictrees/init/DTConfigs.java index 9faf84044..432077200 100644 --- a/src/main/java/com/ferreusveritas/dynamictrees/init/DTConfigs.java +++ b/src/main/java/com/ferreusveritas/dynamictrees/init/DTConfigs.java @@ -8,7 +8,6 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.config.ModConfigEvent; -import net.minecraftforge.fml.loading.FMLEnvironment; import net.minecraftforge.fml.loading.FMLPaths; import java.io.File; @@ -62,6 +61,7 @@ public class DTConfigs { public static final ForgeConfigSpec.BooleanValue REPLACE_VANILLA_SAPLING; public static final ForgeConfigSpec.BooleanValue REPLACE_NYLIUM_FUNGI; public static final ForgeConfigSpec.BooleanValue CANCEL_VANILLA_VILLAGE_TREES; + public static final ForgeConfigSpec.IntValue MAX_FALLING_TREE_LEAVES_PARTICLES; public static final ForgeConfigSpec.BooleanValue PODZOL_GEN; @@ -167,6 +167,8 @@ public class DTConfigs { define("replaceNyliumFungi", true); CANCEL_VANILLA_VILLAGE_TREES = COMMON_BUILDER.comment("If enabled, cancels the non-dynamic trees that spawn with vanilla villages."). define("cancelVanillaVillageTrees", true); + MAX_FALLING_TREE_LEAVES_PARTICLES = SERVER_BUILDER.comment("The maximum number of leaves blocks that will fling particles when a falling tree crashes into the ground. Higher values might have a performance impact."). + defineInRange("growthFolding", 400, 0, 4096); COMMON_BUILDER.pop(); SERVER_BUILDER.comment("World Generation Settings").push("world");