mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 11:54:59 -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.TintColorCalculator
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.BlockLikeRenderer
|
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.input.camera.RaycastHit
|
||||||
|
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
||||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
open class Block(
|
open class Block(
|
||||||
final override val resourceLocation: ResourceLocation,
|
final override val resourceLocation: ResourceLocation,
|
||||||
mappings: Registries,
|
registries: Registries,
|
||||||
data: JsonObject,
|
data: JsonObject,
|
||||||
) : RegistryItem {
|
) : RegistryItem {
|
||||||
open val explosionResistance: Float = data["explosion_resistance"]?.asFloat ?: 0.0f
|
open val explosionResistance: Float = data["explosion_resistance"]?.asFloat ?: 0.0f
|
||||||
@ -96,6 +98,8 @@ open class Block(
|
|||||||
return this.defaultState.withProperties(properties)
|
return this.defaultState.withProperties(properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun randomTick(connection: PlayConnection, particleRenderer: ParticleRenderer?, blockState: BlockState, blockPosition: Vec3i, random: Random) {}
|
||||||
|
|
||||||
companion object : ResourceLocationDeserializer<Block> {
|
companion object : ResourceLocationDeserializer<Block> {
|
||||||
override fun deserialize(mappings: Registries?, resourceLocation: ResourceLocation, data: JsonObject): Block {
|
override fun deserialize(mappings: Registries?, resourceLocation: ResourceLocation, data: JsonObject): Block {
|
||||||
check(mappings != null) { "Registries is null!" }
|
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.ParticleRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.CampfireSmokeParticle
|
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.CampfireSmokeParticle
|
||||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
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.Vec3
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
import kotlin.random.Random
|
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) {
|
private fun extinguish(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i) {
|
||||||
val particleRenderer = connection.rendering?.renderWindow?.get(ParticleRenderer) ?: return
|
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 isSignal = blockState.properties[BlockProperties.CAMPFIRE_SIGNAL_FIRE] == true
|
||||||
|
|
||||||
val data = connection.registries.particleTypeRegistry[if (isSignal) {
|
val particleType = if (isSignal) {
|
||||||
CampfireSmokeParticle.SignalSmokeParticleFactory
|
signalSmokeParticle
|
||||||
} else {
|
} 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) {
|
if (extinguished) {
|
||||||
// ToDo: Spawn smoke particles
|
// 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 {
|
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) {
|
if (itemStack?.item !is ShovelItem || blockState.properties[BlockProperties.LIT] != true) {
|
||||||
return super.onUse(connection, blockState, blockPosition, raycastHit, hands, itemStack)
|
return super.onUse(connection, blockState, blockPosition, raycastHit, hands, itemStack)
|
||||||
@ -69,4 +85,8 @@ open class CampfireBlock(resourceLocation: ResourceLocation, mappings: Registrie
|
|||||||
extinguish(connection, blockState, blockPosition)
|
extinguish(connection, blockState, blockPosition)
|
||||||
return BlockUsages.SUCCESS
|
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.BiomeAccessor
|
||||||
import de.bixilon.minosoft.data.world.biome.accessor.NullBiomeAccessor
|
import de.bixilon.minosoft.data.world.biome.accessor.NullBiomeAccessor
|
||||||
import de.bixilon.minosoft.data.world.light.WorldLightAccessor
|
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.chunkPosition
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkPosition
|
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.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.gui.rendering.util.VecUtil.sectionHeight
|
||||||
import de.bixilon.minosoft.modding.event.EventInitiators
|
import de.bixilon.minosoft.modding.event.EventInitiators
|
||||||
import de.bixilon.minosoft.modding.event.events.BlockSetEvent
|
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 de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collection of chunks and more
|
* Collection of chunks and more
|
||||||
@ -51,6 +56,7 @@ class World(
|
|||||||
var biomeAccessor: BiomeAccessor = NullBiomeAccessor
|
var biomeAccessor: BiomeAccessor = NullBiomeAccessor
|
||||||
var time = 0L
|
var time = 0L
|
||||||
var age = 0L
|
var age = 0L
|
||||||
|
private val random = Random
|
||||||
|
|
||||||
operator fun get(blockPosition: Vec3i): BlockState? {
|
operator fun get(blockPosition: Vec3i): BlockState? {
|
||||||
return chunks[blockPosition.chunkPosition]?.get(blockPosition.inChunkPosition)
|
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> {
|
fun getBlocks(start: Vec3i, end: Vec3i): Map<Vec3i, BlockState> {
|
||||||
val blocks: MutableMap<Vec3i, BlockState> = mutableMapOf()
|
val blocks: MutableMap<Vec3i, BlockState> = mutableMapOf()
|
||||||
|
|
||||||
|
@ -104,6 +104,8 @@ class AudioPlayer(
|
|||||||
|
|
||||||
listener = SoundListener()
|
listener = SoundListener()
|
||||||
|
|
||||||
|
listener.masterVolume = Minosoft.config.config.game.sound.masterVolume
|
||||||
|
|
||||||
connection.registerEvent(CallbackEventInvoker.of<CameraPositionChangeEvent> {
|
connection.registerEvent(CallbackEventInvoker.of<CameraPositionChangeEvent> {
|
||||||
queue += {
|
queue += {
|
||||||
listener.position = it.newPosition
|
listener.position = it.newPosition
|
||||||
@ -176,13 +178,13 @@ class AudioPlayer(
|
|||||||
}
|
}
|
||||||
source.sound = sound
|
source.sound = sound
|
||||||
source.pitch = pitch * sound.pitch
|
source.pitch = pitch * sound.pitch
|
||||||
source.gain = volume * sound.volume * Minosoft.config.config.game.sound.masterVolume
|
source.gain = volume * sound.volume
|
||||||
source.play()
|
source.play()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startLoop() {
|
fun startLoop() {
|
||||||
while (connection.connectionState != ConnectionStates.DISCONNECTING) {
|
while (connection.connectionState != ConnectionStates.DISCONNECTING) { // ToDo: Also kill when disconnected
|
||||||
queue.work()
|
queue.work()
|
||||||
Thread.sleep(1L)
|
Thread.sleep(1L)
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ import glm_.vec3.Vec3
|
|||||||
import org.lwjgl.openal.AL10.*
|
import org.lwjgl.openal.AL10.*
|
||||||
|
|
||||||
class SoundListener(position: Vec3 = Vec3.EMPTY) {
|
class SoundListener(position: Vec3 = Vec3.EMPTY) {
|
||||||
|
|
||||||
var position: Vec3 = position
|
var position: Vec3 = position
|
||||||
set(value) {
|
set(value) {
|
||||||
alListener3f(AL_POSITION, value.x, value.y, value.z)
|
alListener3f(AL_POSITION, value.x, value.y, value.z)
|
||||||
@ -31,6 +30,10 @@ class SoundListener(position: Vec3 = Vec3.EMPTY) {
|
|||||||
field = value
|
field = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var masterVolume: Float
|
||||||
|
get() = alGetListenerf(AL_MAX_GAIN)
|
||||||
|
set(value) = alListenerf(AL_MAX_GAIN, value)
|
||||||
|
|
||||||
fun setOrientation(look: Vec3, up: Vec3) {
|
fun setOrientation(look: Vec3, up: Vec3) {
|
||||||
alListenerfv(AL_ORIENTATION, floatArrayOf(look.x, look.y, look.z, up.x, up.y, up.z))
|
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) {
|
infix operator fun Vec3.plusAssign(lambda: () -> Float) {
|
||||||
this assign this + lambda
|
this assign this + lambda
|
||||||
}
|
}
|
||||||
|
@ -78,9 +78,9 @@ class PlayConnection(
|
|||||||
lateinit var player: Player
|
lateinit var player: Player
|
||||||
private set
|
private set
|
||||||
|
|
||||||
lateinit var velocityHandlerTask: TimeWorkerTask
|
private lateinit var entityTickTask: TimeWorkerTask
|
||||||
private var velocityHandlerLastExecutionTime: Long = 0L
|
private lateinit var blockEntityTickTask: TimeWorkerTask
|
||||||
lateinit var worldTickTask: TimeWorkerTask
|
private lateinit var randomTickTask: TimeWorkerTask
|
||||||
val collisionDetector = CollisionDetector(this)
|
val collisionDetector = CollisionDetector(this)
|
||||||
|
|
||||||
override var connectionState: ConnectionStates = ConnectionStates.DISCONNECTED
|
override var connectionState: ConnectionStates = ConnectionStates.DISCONNECTED
|
||||||
@ -124,8 +124,8 @@ class PlayConnection(
|
|||||||
if (CLI.getCurrentConnection() == null) {
|
if (CLI.getCurrentConnection() == null) {
|
||||||
CLI.setCurrentConnection(this)
|
CLI.setCurrentConnection(this)
|
||||||
}
|
}
|
||||||
velocityHandlerLastExecutionTime = System.currentTimeMillis()
|
var velocityHandlerLastExecutionTime = System.currentTimeMillis()
|
||||||
velocityHandlerTask = TimeWorkerTask(ProtocolDefinition.TICK_TIME / 5) {
|
entityTickTask = TimeWorkerTask(ProtocolDefinition.TICK_TIME / 5) {
|
||||||
val currentTime = System.currentTimeMillis()
|
val currentTime = System.currentTimeMillis()
|
||||||
val deltaTime = currentTime - velocityHandlerLastExecutionTime
|
val deltaTime = currentTime - velocityHandlerLastExecutionTime
|
||||||
if (deltaTime > 0L) {
|
if (deltaTime > 0L) {
|
||||||
@ -136,12 +136,15 @@ class PlayConnection(
|
|||||||
}
|
}
|
||||||
velocityHandlerLastExecutionTime = currentTime
|
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()
|
world.realTick()
|
||||||
}
|
})
|
||||||
TimeWorker.addTask(worldTickTask)
|
|
||||||
|
TimeWorker.addTask(TimeWorkerTask(ProtocolDefinition.TICK_TIME, maxDelayTime = ProtocolDefinition.TICK_TIME / 2) {
|
||||||
|
world.randomTick()
|
||||||
|
})
|
||||||
|
|
||||||
registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
|
registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
|
||||||
val additionalPrefix = when (it.position) {
|
val additionalPrefix = when (it.position) {
|
||||||
@ -160,11 +163,14 @@ class PlayConnection(
|
|||||||
CLI.setCurrentConnection(null)
|
CLI.setCurrentConnection(null)
|
||||||
Command.print("Disconnected from current connection!")
|
Command.print("Disconnected from current connection!")
|
||||||
}
|
}
|
||||||
if (this::velocityHandlerTask.isInitialized) {
|
if (this::entityTickTask.isInitialized) {
|
||||||
TimeWorker.removeTask(velocityHandlerTask)
|
TimeWorker.removeTask(entityTickTask)
|
||||||
}
|
}
|
||||||
if (this::worldTickTask.isInitialized) {
|
if (this::blockEntityTickTask.isInitialized) {
|
||||||
TimeWorker.removeTask(worldTickTask)
|
TimeWorker.removeTask(blockEntityTickTask)
|
||||||
|
}
|
||||||
|
if (this::randomTickTask.isInitialized) {
|
||||||
|
TimeWorker.removeTask(randomTickTask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
@ -126,4 +126,8 @@ object KUtil {
|
|||||||
*/
|
*/
|
||||||
val Number.millis: Int
|
val Number.millis: Int
|
||||||
get() = this.toInt() * ProtocolDefinition.TICK_TIME
|
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