mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 19:35:00 -04:00
random ticks, campfire sounds
This commit is contained in:
parent
50168dfbe2
commit
a43741b4f5
@ -30,12 +30,14 @@ import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.TintColorCalculator
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.BlockLikeRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
|
||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import glm_.vec3.Vec3i
|
||||
import kotlin.random.Random
|
||||
|
||||
open class Block(
|
||||
final override val resourceLocation: ResourceLocation,
|
||||
mappings: Registries,
|
||||
registries: Registries,
|
||||
data: JsonObject,
|
||||
) : RegistryItem {
|
||||
open val explosionResistance: Float = data["explosion_resistance"]?.asFloat ?: 0.0f
|
||||
@ -96,6 +98,8 @@ open class Block(
|
||||
return this.defaultState.withProperties(properties)
|
||||
}
|
||||
|
||||
open fun randomTick(connection: PlayConnection, particleRenderer: ParticleRenderer?, blockState: BlockState, blockPosition: Vec3i, random: Random) {}
|
||||
|
||||
companion object : ResourceLocationDeserializer<Block> {
|
||||
override fun deserialize(mappings: Registries?, resourceLocation: ResourceLocation, data: JsonObject): Block {
|
||||
check(mappings != null) { "Registries is null!" }
|
||||
|
@ -26,11 +26,16 @@ import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
|
||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.CampfireSmokeParticle
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||
import de.bixilon.minosoft.util.KUtil.chance
|
||||
import glm_.vec3.Vec3
|
||||
import glm_.vec3.Vec3i
|
||||
import kotlin.random.Random
|
||||
|
||||
open class CampfireBlock(resourceLocation: ResourceLocation, mappings: Registries, data: JsonObject) : Block(resourceLocation, mappings, data) {
|
||||
open class CampfireBlock(resourceLocation: ResourceLocation, registries: Registries, data: JsonObject) : Block(resourceLocation, registries, data) {
|
||||
private val campfireCrackleSoundEvent = registries.soundEventRegistry[CAMPFIRE_CRACKLE_SOUND_RESOURCE_LOCATION]!!
|
||||
private val cosySmokeParticle = registries.particleTypeRegistry[CampfireSmokeParticle.CosySmokeParticleFactory]!!
|
||||
private val signalSmokeParticle = registries.particleTypeRegistry[CampfireSmokeParticle.SignalSmokeParticleFactory]!!
|
||||
|
||||
private fun extinguish(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i) {
|
||||
val particleRenderer = connection.rendering?.renderWindow?.get(ParticleRenderer) ?: return
|
||||
@ -48,19 +53,30 @@ open class CampfireBlock(resourceLocation: ResourceLocation, mappings: Registrie
|
||||
)
|
||||
val isSignal = blockState.properties[BlockProperties.CAMPFIRE_SIGNAL_FIRE] == true
|
||||
|
||||
val data = connection.registries.particleTypeRegistry[if (isSignal) {
|
||||
CampfireSmokeParticle.SignalSmokeParticleFactory
|
||||
val particleType = if (isSignal) {
|
||||
signalSmokeParticle
|
||||
} else {
|
||||
CampfireSmokeParticle.CosySmokeParticleFactory
|
||||
}]!!
|
||||
cosySmokeParticle
|
||||
}
|
||||
|
||||
particleRenderer.add(CampfireSmokeParticle(connection, particleRenderer, position, Vec3(0.0f, 0.07f, 0.0f), data.simple(), isSignal))
|
||||
particleRenderer.add(CampfireSmokeParticle(connection, particleRenderer, position, Vec3(0.0f, 0.07f, 0.0f), particleType.simple(), isSignal))
|
||||
|
||||
if (extinguished) {
|
||||
// ToDo: Spawn smoke particles
|
||||
}
|
||||
}
|
||||
|
||||
override fun randomTick(connection: PlayConnection, particleRenderer: ParticleRenderer?, blockState: BlockState, blockPosition: Vec3i, random: Random) {
|
||||
particleRenderer ?: return
|
||||
if (blockState.properties[BlockProperties.LIT] != true) {
|
||||
return
|
||||
}
|
||||
if (random.chance(10)) {
|
||||
connection.rendering?.audioPlayer?.playSoundEvent(campfireCrackleSoundEvent, blockPosition + Vec3(0.5f), 0.5f + random.nextFloat(), 0.6f + random.nextFloat() * 0.7f)
|
||||
}
|
||||
// ToDo: Spawn Lava particles
|
||||
}
|
||||
|
||||
override fun onUse(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
if (itemStack?.item !is ShovelItem || blockState.properties[BlockProperties.LIT] != true) {
|
||||
return super.onUse(connection, blockState, blockPosition, raycastHit, hands, itemStack)
|
||||
@ -69,4 +85,8 @@ open class CampfireBlock(resourceLocation: ResourceLocation, mappings: Registrie
|
||||
extinguish(connection, blockState, blockPosition)
|
||||
return BlockUsages.SUCCESS
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val CAMPFIRE_CRACKLE_SOUND_RESOURCE_LOCATION = "minecraft:block.campfire.crackle".asResourceLocation()
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,13 @@ import de.bixilon.minosoft.data.mappings.tweaker.VersionTweaker
|
||||
import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor
|
||||
import de.bixilon.minosoft.data.world.biome.accessor.NullBiomeAccessor
|
||||
import de.bixilon.minosoft.data.world.light.WorldLightAccessor
|
||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.blockPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkSectionPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.minus
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
||||
import de.bixilon.minosoft.modding.event.EventInitiators
|
||||
import de.bixilon.minosoft.modding.event.events.BlockSetEvent
|
||||
@ -33,6 +37,7 @@ import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
||||
import glm_.vec2.Vec2i
|
||||
import glm_.vec3.Vec3i
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* Collection of chunks and more
|
||||
@ -51,6 +56,7 @@ class World(
|
||||
var biomeAccessor: BiomeAccessor = NullBiomeAccessor
|
||||
var time = 0L
|
||||
var age = 0L
|
||||
private val random = Random
|
||||
|
||||
operator fun get(blockPosition: Vec3i): BlockState? {
|
||||
return chunks[blockPosition.chunkPosition]?.get(blockPosition.inChunkPosition)
|
||||
@ -162,6 +168,22 @@ class World(
|
||||
}
|
||||
}
|
||||
|
||||
fun randomTick() {
|
||||
val particleRenderer = connection.rendering?.renderWindow?.get(ParticleRenderer)
|
||||
for (i in 0 until 667) {
|
||||
randomTick(16, particleRenderer)
|
||||
randomTick(32, particleRenderer)
|
||||
}
|
||||
}
|
||||
|
||||
private fun randomTick(radius: Int, particleRenderer: ParticleRenderer?) {
|
||||
val blockPosition = connection.player.entity.position.blockPosition + { random.nextInt(radius) } - { random.nextInt(radius) }
|
||||
|
||||
val blockState = this[blockPosition] ?: return
|
||||
|
||||
blockState.block.randomTick(connection, particleRenderer, blockState, blockPosition, random)
|
||||
}
|
||||
|
||||
fun getBlocks(start: Vec3i, end: Vec3i): Map<Vec3i, BlockState> {
|
||||
val blocks: MutableMap<Vec3i, BlockState> = mutableMapOf()
|
||||
|
||||
|
@ -104,6 +104,8 @@ class AudioPlayer(
|
||||
|
||||
listener = SoundListener()
|
||||
|
||||
listener.masterVolume = Minosoft.config.config.game.sound.masterVolume
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<CameraPositionChangeEvent> {
|
||||
queue += {
|
||||
listener.position = it.newPosition
|
||||
@ -176,13 +178,13 @@ class AudioPlayer(
|
||||
}
|
||||
source.sound = sound
|
||||
source.pitch = pitch * sound.pitch
|
||||
source.gain = volume * sound.volume * Minosoft.config.config.game.sound.masterVolume
|
||||
source.gain = volume * sound.volume
|
||||
source.play()
|
||||
}
|
||||
}
|
||||
|
||||
fun startLoop() {
|
||||
while (connection.connectionState != ConnectionStates.DISCONNECTING) {
|
||||
while (connection.connectionState != ConnectionStates.DISCONNECTING) { // ToDo: Also kill when disconnected
|
||||
queue.work()
|
||||
Thread.sleep(1L)
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import glm_.vec3.Vec3
|
||||
import org.lwjgl.openal.AL10.*
|
||||
|
||||
class SoundListener(position: Vec3 = Vec3.EMPTY) {
|
||||
|
||||
var position: Vec3 = position
|
||||
set(value) {
|
||||
alListener3f(AL_POSITION, value.x, value.y, value.z)
|
||||
@ -31,6 +30,10 @@ class SoundListener(position: Vec3 = Vec3.EMPTY) {
|
||||
field = value
|
||||
}
|
||||
|
||||
var masterVolume: Float
|
||||
get() = alGetListenerf(AL_MAX_GAIN)
|
||||
set(value) = alListenerf(AL_MAX_GAIN, value)
|
||||
|
||||
fun setOrientation(look: Vec3, up: Vec3) {
|
||||
alListenerfv(AL_ORIENTATION, floatArrayOf(look.x, look.y, look.z, up.x, up.y, up.z))
|
||||
}
|
||||
|
@ -93,6 +93,22 @@ object VecUtil {
|
||||
)
|
||||
}
|
||||
|
||||
infix operator fun Vec3i.plus(lambda: () -> Int): Vec3i {
|
||||
return Vec3i(
|
||||
x = x + lambda(),
|
||||
y = y + lambda(),
|
||||
z = z + lambda(),
|
||||
)
|
||||
}
|
||||
|
||||
infix operator fun Vec3i.minus(lambda: () -> Int): Vec3i {
|
||||
return Vec3i(
|
||||
x = x - lambda(),
|
||||
y = y - lambda(),
|
||||
z = z - lambda(),
|
||||
)
|
||||
}
|
||||
|
||||
infix operator fun Vec3.plusAssign(lambda: () -> Float) {
|
||||
this assign this + lambda
|
||||
}
|
||||
|
@ -78,9 +78,9 @@ class PlayConnection(
|
||||
lateinit var player: Player
|
||||
private set
|
||||
|
||||
lateinit var velocityHandlerTask: TimeWorkerTask
|
||||
private var velocityHandlerLastExecutionTime: Long = 0L
|
||||
lateinit var worldTickTask: TimeWorkerTask
|
||||
private lateinit var entityTickTask: TimeWorkerTask
|
||||
private lateinit var blockEntityTickTask: TimeWorkerTask
|
||||
private lateinit var randomTickTask: TimeWorkerTask
|
||||
val collisionDetector = CollisionDetector(this)
|
||||
|
||||
override var connectionState: ConnectionStates = ConnectionStates.DISCONNECTED
|
||||
@ -124,8 +124,8 @@ class PlayConnection(
|
||||
if (CLI.getCurrentConnection() == null) {
|
||||
CLI.setCurrentConnection(this)
|
||||
}
|
||||
velocityHandlerLastExecutionTime = System.currentTimeMillis()
|
||||
velocityHandlerTask = TimeWorkerTask(ProtocolDefinition.TICK_TIME / 5) {
|
||||
var velocityHandlerLastExecutionTime = System.currentTimeMillis()
|
||||
entityTickTask = TimeWorkerTask(ProtocolDefinition.TICK_TIME / 5) {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
val deltaTime = currentTime - velocityHandlerLastExecutionTime
|
||||
if (deltaTime > 0L) {
|
||||
@ -136,12 +136,15 @@ class PlayConnection(
|
||||
}
|
||||
velocityHandlerLastExecutionTime = currentTime
|
||||
}
|
||||
TimeWorker.addTask(velocityHandlerTask)
|
||||
TimeWorker.addTask(entityTickTask)
|
||||
|
||||
worldTickTask = TimeWorkerTask(ProtocolDefinition.TICK_TIME, maxDelayTime = ProtocolDefinition.TICK_TIME / 2) {
|
||||
TimeWorker.addTask(TimeWorkerTask(ProtocolDefinition.TICK_TIME, maxDelayTime = ProtocolDefinition.TICK_TIME / 2) {
|
||||
world.realTick()
|
||||
}
|
||||
TimeWorker.addTask(worldTickTask)
|
||||
})
|
||||
|
||||
TimeWorker.addTask(TimeWorkerTask(ProtocolDefinition.TICK_TIME, maxDelayTime = ProtocolDefinition.TICK_TIME / 2) {
|
||||
world.randomTick()
|
||||
})
|
||||
|
||||
registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
|
||||
val additionalPrefix = when (it.position) {
|
||||
@ -160,11 +163,14 @@ class PlayConnection(
|
||||
CLI.setCurrentConnection(null)
|
||||
Command.print("Disconnected from current connection!")
|
||||
}
|
||||
if (this::velocityHandlerTask.isInitialized) {
|
||||
TimeWorker.removeTask(velocityHandlerTask)
|
||||
if (this::entityTickTask.isInitialized) {
|
||||
TimeWorker.removeTask(entityTickTask)
|
||||
}
|
||||
if (this::worldTickTask.isInitialized) {
|
||||
TimeWorker.removeTask(worldTickTask)
|
||||
if (this::blockEntityTickTask.isInitialized) {
|
||||
TimeWorker.removeTask(blockEntityTickTask)
|
||||
}
|
||||
if (this::randomTickTask.isInitialized) {
|
||||
TimeWorker.removeTask(randomTickTask)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
@ -126,4 +126,8 @@ object KUtil {
|
||||
*/
|
||||
val Number.millis: Int
|
||||
get() = this.toInt() * ProtocolDefinition.TICK_TIME
|
||||
|
||||
fun Random.chance(intPercent: Int): Boolean {
|
||||
return this.nextInt(100) < intPercent
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user