113 lines
4.1 KiB
Kotlin
113 lines
4.1 KiB
Kotlin
package mods.betterfoliage.render.particle
|
|
|
|
import mods.betterfoliage.BetterFoliage
|
|
import mods.betterfoliage.ClientWorldLoadCallback
|
|
import mods.betterfoliage.render.AbstractParticle
|
|
import mods.betterfoliage.render.block.vanilla.LeafKey
|
|
import mods.betterfoliage.util.*
|
|
import net.fabricmc.fabric.api.event.world.WorldTickCallback
|
|
import net.minecraft.client.MinecraftClient
|
|
import net.minecraft.client.render.BufferBuilder
|
|
import net.minecraft.client.world.ClientWorld
|
|
import net.minecraft.util.math.BlockPos
|
|
import net.minecraft.util.math.MathHelper
|
|
import net.minecraft.world.World
|
|
import java.util.*
|
|
import kotlin.math.abs
|
|
import kotlin.math.cos
|
|
import kotlin.math.sin
|
|
|
|
class FallingLeafParticle(
|
|
world: World, pos: BlockPos, leafKey: LeafKey
|
|
) : AbstractParticle(
|
|
world, pos.x.toDouble() + 0.5, pos.y.toDouble(), pos.z.toDouble() + 0.5
|
|
) {
|
|
|
|
companion object {
|
|
@JvmStatic val biomeBrightnessMultiplier = 0.5f
|
|
}
|
|
|
|
var rotationSpeed = randomF(min = PI2 / 80.0, max = PI2 / 50.0)
|
|
var rotPositive = true
|
|
val isMirrored = randomB()
|
|
var wasCollided = false
|
|
|
|
init {
|
|
angle = randomF(max = PI2)
|
|
maxAge = MathHelper.floor(randomD(0.6, 1.0) * BetterFoliage.config.fallingLeaves.lifetime * 20.0)
|
|
velocityY = -BetterFoliage.config.fallingLeaves.speed
|
|
|
|
scale = BetterFoliage.config.fallingLeaves.size.toFloat() * 0.1f
|
|
|
|
val state = world.getBlockState(pos)
|
|
val blockColor = MinecraftClient.getInstance().blockColorMap.getColorMultiplier(state, world, pos, 0)
|
|
sprite = LeafParticleRegistry[leafKey.leafType][randomI(max = 1024)]
|
|
setParticleColor(leafKey.overrideColor, blockColor)
|
|
}
|
|
|
|
override val isValid: Boolean get() = (sprite != null)
|
|
|
|
override fun update() {
|
|
if (randomF() > 0.95f) rotPositive = !rotPositive
|
|
// if (age > maxAge - 20) colorAlpha = 0.05f * (maxAge - age)
|
|
|
|
if (onGround || wasCollided) {
|
|
velocity.setTo(0.0, 0.0, 0.0)
|
|
if (!wasCollided) {
|
|
age = age.coerceAtLeast(maxAge - 20)
|
|
wasCollided = true
|
|
}
|
|
} else {
|
|
val cosRotation = cos(angle).toDouble(); val sinRotation = sin(angle).toDouble()
|
|
velocity.setTo(cosRotation, 0.0, sinRotation).mul(BetterFoliage.config.fallingLeaves.perturb)
|
|
.add(LeafWindTracker.current).add(0.0, -1.0, 0.0).mul(BetterFoliage.config.fallingLeaves.speed)
|
|
angle += if (rotPositive) rotationSpeed else -rotationSpeed
|
|
}
|
|
}
|
|
|
|
override fun render(worldRenderer: BufferBuilder, partialTickTime: Float) {
|
|
val tickAngle = angle + partialTickTime * (if (rotPositive) rotationSpeed else -rotationSpeed)
|
|
renderParticleQuad(worldRenderer, partialTickTime, rotation = tickAngle.toDouble(), isMirrored = isMirrored)
|
|
}
|
|
|
|
fun setParticleColor(overrideColor: Int?, blockColor: Int) {
|
|
val color = overrideColor ?: blockColor
|
|
setColor(color)
|
|
}
|
|
}
|
|
|
|
object LeafWindTracker : WorldTickCallback, ClientWorldLoadCallback {
|
|
val random = Random()
|
|
val target = Double3.zero
|
|
val current = Double3.zero
|
|
var nextChange: Long = 0
|
|
|
|
fun changeWindTarget(world: World) {
|
|
nextChange = world.time + 120 + random.nextInt(80)
|
|
val direction = PI2 * random.nextDouble()
|
|
val speed = abs(random.nextGaussian()) * BetterFoliage.config.fallingLeaves.windStrength +
|
|
(if (!world.isRaining) 0.0 else abs(random.nextGaussian()) * BetterFoliage.config.fallingLeaves.stormStrength)
|
|
target.setTo(cos(direction) * speed, 0.0, sin(direction) * speed)
|
|
}
|
|
|
|
override fun tick(world: World) {
|
|
if (world.isClient) {
|
|
// change target wind speed
|
|
if (world.time >= nextChange) changeWindTarget(world)
|
|
|
|
// change current wind speed
|
|
val changeRate = if (world.isRaining) 0.015 else 0.005
|
|
current.add(
|
|
(target.x - current.x).minmax(-changeRate, changeRate),
|
|
0.0,
|
|
(target.z - current.z).minmax(-changeRate, changeRate)
|
|
)
|
|
}
|
|
}
|
|
|
|
override fun loadWorld(world: ClientWorld) {
|
|
changeWindTarget(world)
|
|
}
|
|
}
|
|
|