Skip to content
This repository has been archived by the owner on May 27, 2024. It is now read-only.

Commit

Permalink
Fix: Ensure ModelEngine models are loaded on chunk loads
Browse files Browse the repository at this point in the history
  • Loading branch information
0ffz committed Mar 14, 2024
1 parent 262fece commit d63636f
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 57 deletions.
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[versions]
gearyPaper = "0.29.12-dev.2"
gearyPaper = "0.29.12-dev.3"

[libraries]
geary-papermc = { module = "com.mineinabyss:geary-papermc", version.ref = "gearyPaper" }
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.mineinabyss.mobzy.mobzy
import com.mineinabyss.mobzy.modelengine.animation.AnimationController
import com.mineinabyss.mobzy.modelengine.animation.ModelEngineAnimationController
import com.mineinabyss.mobzy.modelengine.animation.ModelInteractionListener
import com.mineinabyss.mobzy.modelengine.intializers.ModelEngineWorldListener
import com.mineinabyss.mobzy.modelengine.intializers.createModelEngineListener
import com.mineinabyss.mobzy.modelengine.nametag.ModelEngineNameTagListener
import com.mineinabyss.mobzy.modelengine.riding.ModelEngineRidingListener
Expand All @@ -33,6 +34,7 @@ interface ModelEngineSupport {
ModelInteractionListener(),
ModelEngineNameTagListener(),
ModelEngineRidingListener(),
ModelEngineWorldListener(),
)
service<AnimationController>(ModelEngineAnimationController())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.mineinabyss.mobzy.modelengine.intializers

import com.mineinabyss.geary.helpers.with
import com.mineinabyss.geary.papermc.tracking.entities.toGearyOrNull
import com.mineinabyss.idofront.typealiases.BukkitEntity
import com.mineinabyss.idofront.util.randomOrMin
import com.ticxo.modelengine.api.ModelEngineAPI
import com.ticxo.modelengine.api.utils.data.io.SavedData
import org.bukkit.Color
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.world.EntitiesLoadEvent

class ModelEngineWorldListener : Listener {
@EventHandler
fun EntitiesLoadEvent.onLoad() {
entities.forEach { entity ->
entity.toGearyOrNull()?.with { model: SetModelEngineModel ->
ensureModelLoaded(entity, model)
}
}
}

companion object {
/** Idempotent function that makes sure the correct model is loaded on an entity. */
fun ensureModelLoaded(bukkit: BukkitEntity, model: SetModelEngineModel) {
if (bukkit.isDead) return

// MEG persists models by default, this ensures any geary entities are handling models on their own
if (bukkit.persistentDataContainer.has(SavedData.DATA_KEY))
bukkit.persistentDataContainer.remove(SavedData.DATA_KEY)
val modelEntity = ModelEngineAPI.getOrCreateModeledEntity(bukkit)
val blueprint = ModelEngineAPI.getBlueprint(model.modelId)
?: error("No blueprint registered for ${model.modelId}")

// Clear any old models
val existingMatchedModel = modelEntity.models.toList()
.onEach { (key, value) ->
if (value.blueprint == blueprint) return@onEach
modelEntity.removeModel(key)
value.destroy()
}
.find { (_, value) -> value.blueprint == blueprint }

val activeModel = (existingMatchedModel?.second ?: ModelEngineAPI.createActiveModel(blueprint)).apply {
if (model.damageTint) damageTint = Color.RED
//TODO keep a fixed random value!
val scale = model.scale.randomOrMin()
setScale(scale)
setHitboxScale(scale)
}

modelEntity.apply {
setSaved(false)
if (existingMatchedModel == null) addModel(activeModel, true).ifPresent { it.destroy() }
this.base.maxStepHeight = model.stepHeight
isBaseEntityVisible = !model.invisible
base.bodyRotationController.rotationDuration = 20
base.data?.let { data ->
model.verticalCull?.let {
data.verticalCull = true
data.verticalCullType = it.type
data.verticalCullDistance = it.distance
}
model.backCull?.let {
data.backCull = true
data.backCullAngle = it.angle
data.backCullType = it.type
data.backCullIgnoreRadius = it.ignoreRadius
}
model.blockedCull?.let {
data.blockedCull = true
data.blockedCullType = it.type
data.blockedCullIgnoreRadius = it.ignoreRadius
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
package com.mineinabyss.mobzy.modelengine.intializers

import com.github.shynixn.mccoroutine.bukkit.launch
import com.mineinabyss.geary.modules.GearyModule
import com.mineinabyss.geary.systems.builders.listener
import com.mineinabyss.geary.systems.query.ListenerQuery
import com.mineinabyss.idofront.typealiases.BukkitEntity
import com.mineinabyss.idofront.util.randomOrMin
import com.mineinabyss.mobzy.mobzy
import com.ticxo.modelengine.api.ModelEngineAPI
import kotlinx.coroutines.yield
import org.bukkit.Color
import com.ticxo.modelengine.api.utils.data.io.SavedData as ModelEngineSaveData
import com.mineinabyss.mobzy.modelengine.intializers.ModelEngineWorldListener.Companion.ensureModelLoaded
import org.bukkit.Bukkit

fun GearyModule.createModelEngineListener() = listener(
object : ListenerQuery() {
Expand All @@ -21,54 +17,7 @@ fun GearyModule.createModelEngineListener() = listener(
).exec {
val bukkit = bukkit
val model = model
mobzy.plugin.launch {
yield() // Wait till next tick so some entity stuff gets initialized
if (bukkit.isDead) return@launch

// MEG persists models by default, this ensures any geary entities are handling models on their own
if (bukkit.persistentDataContainer.has(ModelEngineSaveData.DATA_KEY))
bukkit.persistentDataContainer.remove(ModelEngineSaveData.DATA_KEY)
val modelEntity = ModelEngineAPI.getOrCreateModeledEntity(bukkit)
val blueprint =
ModelEngineAPI.getBlueprint(model.modelId) ?: error("No blueprint registered for ${model.modelId}")

// Clear any old models
modelEntity.models.toList().forEach { (key, value) ->
modelEntity.removeModel(key)
value.destroy()
}

val createdModel = ModelEngineAPI.createActiveModel(blueprint).apply {
if (model.damageTint) damageTint = Color.RED
val scale = model.scale.randomOrMin()
setScale(scale)
setHitboxScale(scale)
}

modelEntity.apply {
setSaved(false)
addModel(createdModel, true).ifPresent { it.destroy() }
this.base.maxStepHeight = model.stepHeight
isBaseEntityVisible = !model.invisible
base.bodyRotationController.rotationDuration = 20
base.data?.let { data ->
model.verticalCull?.let {
data.verticalCull = true
data.verticalCullType = it.type
data.verticalCullDistance = it.distance
}
model.backCull?.let {
data.backCull = true
data.backCullAngle = it.angle
data.backCullType = it.type
data.backCullIgnoreRadius = it.ignoreRadius
}
model.blockedCull?.let {
data.blockedCull = true
data.blockedCullType = it.type
data.blockedCullIgnoreRadius = it.ignoreRadius
}
}
}
}
Bukkit.getScheduler().scheduleSyncDelayedTask(mobzy.plugin, {
ensureModelLoaded(bukkit, model)
}, 1L)
}

0 comments on commit d63636f

Please sign in to comment.