mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-21 06:36:25 -04:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89c2b5cef3 | ||
|
|
bd4a6fc48c | ||
|
|
c7bca0ba19 |
@@ -21,6 +21,8 @@
|
||||
|
||||
### Additions
|
||||
- Added `/cobblemonconfig reload` command to reload `main.json` configuration. **Note:** Some settings require a server restart to take effect; use this command cautiously.
|
||||
- Added the Model Appendages system, allowing for resolver-based bedrock model attachments to Pokémon models based on Locators.
|
||||
- View the `egg` examples in `assets/cobblemon/bedrock/appendage` for an example of how to use this system.
|
||||
|
||||
## [1.6.1 (January 26th, 2025)](#1-6-1)
|
||||
|
||||
|
||||
@@ -21,12 +21,10 @@ import com.cobblemon.mod.common.client.render.models.blockbench.ExcludedLabels
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.*
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.appendage.ModelAppendageModelRepository
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunction
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
|
||||
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
|
||||
import com.cobblemon.mod.common.util.getBooleanOrNull
|
||||
import com.cobblemon.mod.common.util.getDoubleOrNull
|
||||
import com.cobblemon.mod.common.util.getStringOrNull
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import java.util.function.Function
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
||||
@@ -53,7 +51,7 @@ object ClientMoLangFunctions {
|
||||
"say" to java.util.function.Function { params -> Minecraft.getInstance().player?.sendSystemMessage(params.getString(0).text()) ?: Unit },
|
||||
)
|
||||
|
||||
val animationFunctions = hashMapOf<String, Function<PosableModel, Function<MoParams, Any>>>(
|
||||
val posableModelFunctions = hashMapOf<String, Function<PosableModel, Function<MoParams, Any>>>(
|
||||
"exclude_labels" to Function { model -> Function { params ->
|
||||
val labels = params.params.map { it.asString() }
|
||||
ObjectValue(ExcludedLabels(labels))
|
||||
@@ -244,6 +242,18 @@ object ClientMoLangFunctions {
|
||||
)
|
||||
}
|
||||
},
|
||||
"appendage_model" to Function {
|
||||
model -> Function { params ->
|
||||
val name = params.getString(0)
|
||||
ObjectValue((ModelAppendageModelRepository to name.asResource()))
|
||||
}
|
||||
},
|
||||
"vanilla_model" to Function {
|
||||
model -> Function { params ->
|
||||
val id = params.getString(0).asResource()
|
||||
ObjectValue(id)
|
||||
}
|
||||
},
|
||||
"primary_animation" to Function { model ->
|
||||
Function { params ->
|
||||
val animation = params.get<ObjectValue<ActiveAnimation>>(0)?.obj ?: return@Function DoubleValue.ZERO
|
||||
@@ -344,7 +354,7 @@ object ClientMoLangFunctions {
|
||||
}
|
||||
)
|
||||
|
||||
fun PosableModel.animationFunctions(): HashMap<String, Function<MoParams, Any>> = animationFunctions.map { (k, v) -> k to v.apply(this) }.toHashMap()
|
||||
fun PosableModel.animationFunctions(): HashMap<String, Function<MoParams, Any>> = posableModelFunctions.map { (k, v) -> k to v.apply(this) }.toHashMap()
|
||||
|
||||
fun MoLangRuntime.setupClient(): MoLangRuntime {
|
||||
environment.query.addFunctions(clientFunctions)
|
||||
|
||||
@@ -47,6 +47,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.repository.MiscM
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.NPCModelRepository
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokeBallModelRepository
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokemonModelRepository
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.appendage.ModelAppendageModelRepository
|
||||
import com.cobblemon.mod.common.client.render.npc.NPCRenderer
|
||||
import com.cobblemon.mod.common.client.render.pokeball.PokeBallRenderer
|
||||
import com.cobblemon.mod.common.client.render.pokemon.PokemonRenderer
|
||||
@@ -100,7 +101,8 @@ object CobblemonClient {
|
||||
NPCModelRepository,
|
||||
FossilModelRepository,
|
||||
BlockEntityModelRepository,
|
||||
GenericBedrockEntityModelRepository
|
||||
GenericBedrockEntityModelRepository,
|
||||
ModelAppendageModelRepository
|
||||
)
|
||||
|
||||
val overlay: PartyOverlay by lazy { PartyOverlay() }
|
||||
|
||||
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.client.render
|
||||
|
||||
import com.cobblemon.mod.common.util.math.geometry.getOrigin
|
||||
import com.cobblemon.mod.common.util.math.geometry.transformPosition
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.fabricmc.loader.impl.lib.sat4j.core.Vec
|
||||
import org.joml.Matrix4f
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ import com.cobblemon.mod.common.api.mulch.MulchVariant
|
||||
import com.cobblemon.mod.common.block.BerryBlock
|
||||
import com.cobblemon.mod.common.block.entity.BerryBlockEntity
|
||||
import com.cobblemon.mod.common.client.CobblemonBakingOverrides
|
||||
import com.cobblemon.mod.common.client.render.layer.CobblemonRenderLayers
|
||||
import com.cobblemon.mod.common.client.render.layer.CobblemonRenderTypes
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.BerryModelRepository
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.setPosition
|
||||
import com.cobblemon.mod.common.util.math.geometry.Axis
|
||||
@@ -54,7 +54,7 @@ class BerryBlockRenderer(private val context: BlockEntityRendererProvider.Contex
|
||||
if (entity.renderState == null) {
|
||||
entity.renderState = BerryBlockEntityRenderState()
|
||||
}
|
||||
val bf = vertexConsumers.getBuffer(CobblemonRenderLayers.BERRY_LAYER)
|
||||
val bf = vertexConsumers.getBuffer(CobblemonRenderTypes.BERRY_LAYER)
|
||||
val renderState = entity.renderState as BerryBlockEntityRenderState
|
||||
// if (renderState.needsRebuild || renderState.vboLightLevel != light) {
|
||||
renderToBuffer(entity, matrices, light, overlay, renderState, bf)
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import net.minecraft.Util
|
||||
import net.minecraft.client.renderer.RenderStateShard
|
||||
import net.minecraft.client.renderer.RenderStateShard.*
|
||||
|
||||
object CobblemonRenderLayers {
|
||||
object CobblemonRenderTypes {
|
||||
val BERRY_LAYER = run {
|
||||
val multiPhaseParameters = RenderType.CompositeState.builder()
|
||||
.setLightmapState(LIGHTMAP)
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
package com.cobblemon.mod.common.client.render.layer
|
||||
|
||||
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokemonModelRepository
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.appendage.ModelAppendageModelRepository
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.math.Axis
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.MultiBufferSource
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.ItemDisplayContext
|
||||
import org.joml.Vector3f
|
||||
|
||||
object ModelAppendageRenderer {
|
||||
|
||||
fun <T> render(
|
||||
poseStack: PoseStack,
|
||||
bufferSource: MultiBufferSource,
|
||||
packedLight: Int,
|
||||
livingEntity: T,
|
||||
limbSwing: Float,
|
||||
limbSwingAmount: Float,
|
||||
ageInTicks: Float,
|
||||
netHeadYaw: Float,
|
||||
headPitch: Float,
|
||||
locator: String,
|
||||
context: RenderContext,
|
||||
parentModel: ResourceLocation
|
||||
) where T : PokemonEntity {
|
||||
val clientDelegate = livingEntity.delegate as PokemonClientDelegate
|
||||
val appendages = ModelAppendageModelRepository.getAppendagesForModelAndTarget(parentModel, locator) ?: return
|
||||
// avoid editing the original context
|
||||
val clonedContext = context.clone()
|
||||
appendages.forEach { appendage ->
|
||||
val modelObj = appendage.model.resolveObject(clientDelegate.runtime).obj
|
||||
if (modelObj is ResourceLocation) {
|
||||
poseStack.pushPose()
|
||||
clientDelegate.locatorStates[locator]?.let { bone ->
|
||||
val stack = if(modelObj.toString() == "cobblemon:held_item") livingEntity.pokemon.heldItemNoCopy() else BuiltInRegistries.ITEM.get(modelObj).defaultInstance
|
||||
val pos = bone.getOrigin().subtract(livingEntity.position())
|
||||
val scale = Vector3f()
|
||||
bone.matrix.getScale(scale)
|
||||
poseStack.scale(scale.x(), scale.y(), scale.z())
|
||||
poseStack.translate(pos.x, pos.y, pos.z)
|
||||
poseStack.mulPose(bone.clone().matrix.setTranslation(0.0f, 0.0f, 0.0f))
|
||||
poseStack.scale(
|
||||
appendage.scale.x().toFloat(), appendage.scale.y().toFloat(),
|
||||
appendage.scale.z().toFloat()
|
||||
)
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(appendage.rotation.x().toFloat()))
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(appendage.rotation.y().toFloat()))
|
||||
poseStack.mulPose(Axis.ZP.rotationDegrees(appendage.rotation.z().toFloat()))
|
||||
poseStack.translate(appendage.offset.x(), appendage.offset.y(), appendage.offset.z())
|
||||
Minecraft.getInstance().itemRenderer.renderStatic(stack, ItemDisplayContext.THIRD_PERSON_RIGHT_HAND, packedLight, OverlayTexture.NO_OVERLAY, poseStack, bufferSource, livingEntity.level(), 0)
|
||||
}
|
||||
poseStack.popPose()
|
||||
} else if (modelObj is Pair<*, *>) {
|
||||
val repo = modelObj.first as ModelAppendageModelRepository
|
||||
val resLoc = modelObj.second as ResourceLocation
|
||||
val model =
|
||||
repo.getPoserNullable(resLoc, clientDelegate) ?: return
|
||||
model.context = clonedContext
|
||||
model.setLayerContext(
|
||||
bufferSource,
|
||||
clientDelegate,
|
||||
ModelAppendageModelRepository.getLayers(resLoc, clientDelegate)
|
||||
)
|
||||
poseStack.pushPose()
|
||||
clientDelegate.locatorStates[locator]?.let { bone ->
|
||||
val pos = bone.getOrigin().subtract(livingEntity.position())
|
||||
val scale = Vector3f()
|
||||
bone.matrix.getScale(scale)
|
||||
poseStack.scale(scale.x(), scale.y(), scale.z())
|
||||
poseStack.translate(pos.x, pos.y, pos.z)
|
||||
poseStack.mulPose(bone.clone().matrix.setTranslation(0.0f, 0.0f, 0.0f))
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(180f))
|
||||
poseStack.translate(0.0, -1.75, 0.0)
|
||||
poseStack.scale(
|
||||
appendage.scale.x().toFloat(), appendage.scale.y().toFloat(),
|
||||
appendage.scale.z().toFloat()
|
||||
)
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(appendage.rotation.x().toFloat()))
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(appendage.rotation.y().toFloat()))
|
||||
poseStack.mulPose(Axis.ZP.rotationDegrees(appendage.rotation.z().toFloat()))
|
||||
poseStack.translate(appendage.offset.x(), appendage.offset.y(), appendage.offset.z())
|
||||
model.applyAnimations(
|
||||
livingEntity,
|
||||
clientDelegate,
|
||||
limbSwing,
|
||||
limbSwingAmount,
|
||||
ageInTicks,
|
||||
netHeadYaw,
|
||||
headPitch
|
||||
)
|
||||
val buffer = bufferSource.getBuffer(
|
||||
RenderType.entityCutout(
|
||||
ModelAppendageModelRepository.getTexture(
|
||||
resLoc,
|
||||
clientDelegate
|
||||
)
|
||||
)
|
||||
)
|
||||
model.withLayerContext(
|
||||
bufferSource,
|
||||
clientDelegate,
|
||||
ModelAppendageModelRepository.getLayers(resLoc, clientDelegate)
|
||||
) {
|
||||
model.render(clonedContext, poseStack, buffer, packedLight, OverlayTexture.NO_OVERLAY, -0x1)
|
||||
}
|
||||
|
||||
}
|
||||
model.green = 1F
|
||||
model.blue = 1F
|
||||
model.red = 1F
|
||||
|
||||
model.resetLayerContext()
|
||||
poseStack.popPose()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.cobblemon.mod.common.client.render.layer.appendage
|
||||
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
data class ModelAppendage(
|
||||
@SerializedName("target_model") val targetModel: ResourceLocation?,
|
||||
@SerializedName("model") val model: ExpressionLike,
|
||||
@SerializedName("target_locator") val targetLocator: String,
|
||||
@SerializedName("scale") val scale: Vec3 = Vec3(1.0, 1.0, 1.0),
|
||||
@SerializedName("rotation") val rotation: Vec3 = Vec3(0.0, 0.0, 0.0),
|
||||
@SerializedName("offset") val offset: Vec3 = Vec3(0.0, 0.0, 0.0)
|
||||
)
|
||||
+6
@@ -80,6 +80,12 @@ class RenderContext {
|
||||
this.context.remove(key)
|
||||
}
|
||||
|
||||
fun clone(): RenderContext {
|
||||
val newContext = RenderContext()
|
||||
newContext.context.putAll(this.context)
|
||||
return newContext
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a key used for accessing values in the context.
|
||||
*
|
||||
|
||||
+4
-2
@@ -23,6 +23,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.repository.Varyi
|
||||
import com.cobblemon.mod.common.client.util.exists
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.ExpressionLikeAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.IdentifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.Vec3dAdapter
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.endsWith
|
||||
@@ -72,6 +73,7 @@ abstract class VaryingModelRepository<T : PosableModel> {
|
||||
GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.disableHtmlEscaping()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(Vec3::class.java, Vec3dAdapter)
|
||||
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
@@ -213,7 +215,7 @@ abstract class VaryingModelRepository<T : PosableModel> {
|
||||
Cobblemon.LOGGER.info("Loaded $models $title models.")
|
||||
}
|
||||
|
||||
fun reload(resourceManager: ResourceManager) {
|
||||
open fun reload(resourceManager: ResourceManager) {
|
||||
Cobblemon.LOGGER.info("Loading $title assets...")
|
||||
this.variations.clear()
|
||||
this.posers.clear()
|
||||
@@ -222,7 +224,7 @@ abstract class VaryingModelRepository<T : PosableModel> {
|
||||
registerVariations(resourceManager)
|
||||
}
|
||||
|
||||
fun getPoser(name: ResourceLocation, state: PosableState): T {
|
||||
open fun getPoser(name: ResourceLocation, state: PosableState): T {
|
||||
try {
|
||||
val poser = this.variations[name]?.getPoser(state)
|
||||
if (poser != null) {
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package com.cobblemon.mod.common.client.render.models.blockbench.repository.appendage
|
||||
|
||||
import com.cobblemon.mod.common.client.render.layer.appendage.ModelAppendage
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.endsWith
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.packs.resources.ResourceManager
|
||||
import java.io.File
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
object ModelAppendageModelRepository : VaryingModelRepository<PosableModel>() {
|
||||
override val poserClass: Class<PosableModel>
|
||||
get() = PosableModel::class.java
|
||||
override val title: String
|
||||
get() = "Model Appendage"
|
||||
override val type: String
|
||||
get() = "appendage"
|
||||
override val variationDirectories: List<String>
|
||||
get() = listOf("bedrock/$type/variations")
|
||||
override val poserDirectories: List<String>
|
||||
get() = listOf("bedrock/$type/posers")
|
||||
override val modelDirectories: List<String>
|
||||
get() = listOf("bedrock/$type/models")
|
||||
override val animationDirectories: List<String>
|
||||
get() = listOf("bedrock/$type/animations")
|
||||
val appendageDirectories: List<String>
|
||||
get() = listOf("bedrock/$type/appendages")
|
||||
val appendages = mutableMapOf<ResourceLocation, ModelAppendage>()
|
||||
override val fallback: ResourceLocation = cobblemonResource("substitute")
|
||||
override val isForLivingEntityRenderer: Boolean
|
||||
get() = true
|
||||
|
||||
override fun registerInBuiltPosers() {}
|
||||
|
||||
override fun reload(resourceManager: ResourceManager) {
|
||||
super.reload(resourceManager)
|
||||
this.appendages.clear()
|
||||
registerJsonAppendages(resourceManager)
|
||||
}
|
||||
|
||||
private fun registerJsonAppendages(resourceManager: ResourceManager) {
|
||||
for (directory in appendageDirectories) {
|
||||
resourceManager
|
||||
.listResources(directory) { path -> path.endsWith(".json") }
|
||||
.forEach { (identifier, resource) ->
|
||||
resource.open().use { stream ->
|
||||
val json = String(stream.readAllBytes(), StandardCharsets.UTF_8)
|
||||
val resolvedIdentifier = ResourceLocation.fromNamespaceAndPath(identifier.namespace, File(identifier.path).nameWithoutExtension)
|
||||
appendages[resolvedIdentifier] = gson.fromJson(json, ModelAppendage::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getAppendagesForModelAndTarget(model: ResourceLocation, target: String): List<ModelAppendage> {
|
||||
return appendages.entries.filter { (it.value.targetModel == model || it.value.targetModel == null) && it.value.targetLocator == target }.map { it.value }
|
||||
}
|
||||
|
||||
fun getPoserNullable(name: ResourceLocation, state: PosableState): PosableModel? {
|
||||
try {
|
||||
val poser = this.variations[name]?.getPoser(state)
|
||||
if (poser != null) {
|
||||
return poser
|
||||
}
|
||||
} catch(e: IllegalStateException) {
|
||||
// e.printStackTrace()
|
||||
}
|
||||
return this.variations[fallback]?.getPoser(state)
|
||||
}
|
||||
}
|
||||
+118
-34
@@ -18,6 +18,7 @@ import com.cobblemon.mod.common.client.entity.PokemonClientDelegate.Companion.BE
|
||||
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate.Companion.BEAM_SHRINK_TIME
|
||||
import com.cobblemon.mod.common.client.keybind.boundKey
|
||||
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding
|
||||
import com.cobblemon.mod.common.client.render.layer.ModelAppendageRenderer
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PosablePokemonEntityModel
|
||||
@@ -41,7 +42,6 @@ import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import com.cobblemon.mod.common.util.math.remap
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.math.Axis
|
||||
import kotlin.math.*
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.Font.DisplayMode
|
||||
@@ -61,15 +61,17 @@ import org.joml.Math
|
||||
import org.joml.Quaternionf
|
||||
import org.joml.Vector3f
|
||||
import org.joml.Vector4f
|
||||
import kotlin.math.*
|
||||
|
||||
class PokemonRenderer(
|
||||
context: EntityRendererProvider.Context
|
||||
var context: EntityRendererProvider.Context
|
||||
) : MobRenderer<PokemonEntity, PosablePokemonEntityModel>(context, PosablePokemonEntityModel(), 0.5f) {
|
||||
companion object {
|
||||
val recallBeamColour = Vector4f(1F, 0.1F, 0.1F, 1F)
|
||||
fun ease(x: Double): Double {
|
||||
return 1 - (1 - x).pow(3)
|
||||
}
|
||||
|
||||
private val LEVEL_LABEL_STYLE = Style.EMPTY.withColor(ChatFormatting.WHITE)
|
||||
.withBold(false)
|
||||
.withItalic(false)
|
||||
@@ -88,7 +90,10 @@ class PokemonRenderer(
|
||||
}
|
||||
|
||||
override fun getTextureLocation(entity: PokemonEntity): ResourceLocation {
|
||||
return PokemonModelRepository.getTexture(entity.pokemon.species.resourceIdentifier, entity.delegate as PokemonClientDelegate)
|
||||
return PokemonModelRepository.getTexture(
|
||||
entity.pokemon.species.resourceIdentifier,
|
||||
entity.delegate as PokemonClientDelegate
|
||||
)
|
||||
}
|
||||
|
||||
override fun render(
|
||||
@@ -100,7 +105,10 @@ class PokemonRenderer(
|
||||
packedLight: Int
|
||||
) {
|
||||
val clientDelegate = entity.delegate as PokemonClientDelegate
|
||||
shadowRadius = min((entity.boundingBox.maxX - entity.boundingBox.minX), (entity.boundingBox.maxZ) - (entity.boundingBox.minZ)).toFloat() / 1.5F * (entity.delegate as PokemonClientDelegate).entityScaleModifier
|
||||
shadowRadius = min(
|
||||
(entity.boundingBox.maxX - entity.boundingBox.minX),
|
||||
(entity.boundingBox.maxZ) - (entity.boundingBox.minZ)
|
||||
).toFloat() / 1.5F * (entity.delegate as PokemonClientDelegate).entityScaleModifier
|
||||
model.posableModel = PokemonModelRepository.getPoser(entity.pokemon.species.resourceIdentifier, clientDelegate)
|
||||
model.posableModel.context = model.context
|
||||
model.setupEntityTypeContext(entity)
|
||||
@@ -126,7 +134,7 @@ class PokemonRenderer(
|
||||
clientDelegate
|
||||
)
|
||||
}
|
||||
if(entity.platform != PlatformType.NONE) {
|
||||
if (entity.platform != PlatformType.NONE) {
|
||||
drawPlatform(
|
||||
poseMatrix,
|
||||
entity,
|
||||
@@ -138,10 +146,34 @@ class PokemonRenderer(
|
||||
poseMatrix.translate(0.0, 0.25 * (entity.delegate as PokemonClientDelegate).entityScaleModifier, 0.0)
|
||||
}
|
||||
|
||||
modelNow.setLayerContext(buffer, clientDelegate, PokemonModelRepository.getLayers(entity.pokemon.species.resourceIdentifier, clientDelegate))
|
||||
modelNow.setLayerContext(
|
||||
buffer,
|
||||
clientDelegate,
|
||||
PokemonModelRepository.getLayers(entity.pokemon.species.resourceIdentifier, clientDelegate)
|
||||
)
|
||||
|
||||
|
||||
super.render(entity, entityYaw, partialTicks, poseMatrix, buffer, packedLight)
|
||||
PokemonModelRepository.variations[entity.pokemon.species.resourceIdentifier]?.getResolvedModel(clientDelegate).let { parentModel ->
|
||||
clientDelegate.locatorStates.keys.forEach { locatorKey ->
|
||||
if (parentModel != null) {
|
||||
ModelAppendageRenderer.render(
|
||||
poseMatrix,
|
||||
buffer,
|
||||
packedLight,
|
||||
entity,
|
||||
0f,
|
||||
0f,
|
||||
entity.age.toFloat() + partialTicks,
|
||||
entityYaw,
|
||||
entity.lookAngle.x.toFloat(),
|
||||
locatorKey,
|
||||
model.context,
|
||||
parentModel
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modelNow.green = 1F
|
||||
modelNow.blue = 1F
|
||||
@@ -165,7 +197,7 @@ class PokemonRenderer(
|
||||
val s = clientDelegate.secondsSinceBeamEffectStarted
|
||||
if (beamMode == 3) {
|
||||
if (s > BEAM_EXTEND_TIME) {
|
||||
val value = (s - BEAM_EXTEND_TIME) / BEAM_SHRINK_TIME
|
||||
val value = (s - BEAM_EXTEND_TIME) / BEAM_SHRINK_TIME
|
||||
val colourValue = 1F - min(0.6F, value)
|
||||
modelNow.green = colourValue
|
||||
modelNow.blue = colourValue
|
||||
@@ -181,7 +213,9 @@ class PokemonRenderer(
|
||||
val lookVec = phaseTarget.lookAngle.yRot((PI / 2).toFloat()).multiply(1.0, 0.0, 1.0).normalize()
|
||||
phaseTarget.getEyePosition(partialTicks).subtract(0.0, 0.4, 0.0).subtract(lookVec.scale(0.3))
|
||||
} else {
|
||||
val lookVec = phaseTarget.lookAngle.yRot((PI / 2 - (phaseTarget.visualRotationYInDegrees - phaseTarget.xRot).toRadians()).toFloat()).multiply(1.0, 0.0, 1.0).normalize()
|
||||
val lookVec =
|
||||
phaseTarget.lookAngle.yRot((PI / 2 - (phaseTarget.visualRotationYInDegrees - phaseTarget.xRot).toRadians()).toFloat())
|
||||
.multiply(1.0, 0.0, 1.0).normalize()
|
||||
phaseTarget.getEyePosition(partialTicks).subtract(0.0, 0.7, 0.0).subtract(lookVec.scale(0.4))
|
||||
}
|
||||
}
|
||||
@@ -192,7 +226,8 @@ class PokemonRenderer(
|
||||
clientDelegate.sendOutPosition = clientDelegate.sendOutPosition!!.add(0.0, 0.04, 0.0)
|
||||
beamSourcePosition = clientDelegate.sendOutPosition!!
|
||||
}
|
||||
val offsetDirection = beamSourcePosition.subtract(entity.position()).normalize().scale(-clientDelegate.ballOffset.toDouble())
|
||||
val offsetDirection =
|
||||
beamSourcePosition.subtract(entity.position()).normalize().scale(-clientDelegate.ballOffset.toDouble())
|
||||
val facingDir: Vec3
|
||||
with(beamSourcePosition.subtract(entity.position())) {
|
||||
var newOffset = offsetDirection.scale(2.0)
|
||||
@@ -200,16 +235,17 @@ class PokemonRenderer(
|
||||
newOffset = newOffset.scale((distance / 10.0) * 5)
|
||||
facingDir = newOffset.normalize()
|
||||
clientDelegate.sendOutOffset = newOffset
|
||||
poseMatrix.translate(x+newOffset.x, y+newOffset.y, z+newOffset.z)
|
||||
poseMatrix.translate(x + newOffset.x, y + newOffset.y, z + newOffset.z)
|
||||
}
|
||||
val dir = beamSourcePosition.subtract(entity.position()).normalize()
|
||||
val angle = Mth.atan2(dir.z, dir.x) - PI / 2
|
||||
poseMatrix.mulPose(Axis.YP.rotation(-angle.toFloat() + (180 * Math.PI / 180).toFloat()))
|
||||
|
||||
if (beamMode == 1 && !clientDelegate.ballDone){
|
||||
if(entity.pokemon.caughtBall.name.toString().contains("beast")){
|
||||
if (beamMode == 1 && !clientDelegate.ballDone) {
|
||||
if (entity.pokemon.caughtBall.name.toString().contains("beast")) {
|
||||
// get rotation angle on x-axis for facingDir
|
||||
val xAngleFacingDir = Mth.atan2(facingDir.y, sqrt(facingDir.x * facingDir.x + facingDir.z * facingDir.z))
|
||||
val xAngleFacingDir =
|
||||
Mth.atan2(facingDir.y, sqrt(facingDir.x * facingDir.x + facingDir.z * facingDir.z))
|
||||
poseMatrix.mulPose(Axis.XP.rotation(-xAngleFacingDir.toFloat()))
|
||||
}
|
||||
drawPokeBall(
|
||||
@@ -221,7 +257,7 @@ class PokemonRenderer(
|
||||
packedLight = packedLight,
|
||||
ball = CobblemonClient.storage.myParty.firstOrNull { it?.uuid == entity.pokemon.uuid }?.caughtBall
|
||||
?: clientDelegate.currentEntity.pokemon.caughtBall,
|
||||
distance = ceil(beamSourcePosition.distanceTo(entity.position())/4f).toInt()
|
||||
distance = ceil(beamSourcePosition.distanceTo(entity.position()) / 4f).toInt()
|
||||
)
|
||||
}
|
||||
poseMatrix.popPose()
|
||||
@@ -231,7 +267,8 @@ class PokemonRenderer(
|
||||
}
|
||||
|
||||
override fun scale(pEntity: PokemonEntity, pPoseStack: PoseStack, pPartialTickTime: Float) {
|
||||
val scale = pEntity.pokemon.form.baseScale * pEntity.pokemon.scaleModifier * (pEntity.delegate as PokemonClientDelegate).entityScaleModifier
|
||||
val scale =
|
||||
pEntity.pokemon.form.baseScale * pEntity.pokemon.scaleModifier * (pEntity.delegate as PokemonClientDelegate).entityScaleModifier
|
||||
pPoseStack.scale(scale, scale, scale)
|
||||
}
|
||||
|
||||
@@ -245,9 +282,17 @@ class PokemonRenderer(
|
||||
* @param colour The colour of the beam.
|
||||
* @param buffer The vertex consumer provider.
|
||||
*/
|
||||
fun renderBeam(matrixStack: PoseStack, partialTicks: Float, entity: PokemonEntity, beamTarget: Entity, buffer: MultiBufferSource, offset: Vec3) {
|
||||
fun renderBeam(
|
||||
matrixStack: PoseStack,
|
||||
partialTicks: Float,
|
||||
entity: PokemonEntity,
|
||||
beamTarget: Entity,
|
||||
buffer: MultiBufferSource,
|
||||
offset: Vec3
|
||||
) {
|
||||
val clientDelegate = entity.delegate as PokemonClientDelegate
|
||||
val pokemonPosition = entity.position().add(0.0, entity.bbHeight / 2.0 * clientDelegate.entityScaleModifier.toDouble(), 0.0)
|
||||
val pokemonPosition =
|
||||
entity.position().add(0.0, entity.bbHeight / 2.0 * clientDelegate.entityScaleModifier.toDouble(), 0.0)
|
||||
var beamSourcePosition = if (beamTarget is EmptyPokeBallEntity) {
|
||||
(beamTarget.delegate as PokeBallPosableState).locatorStates["beam"]?.getOrigin() ?: beamTarget.position()
|
||||
} else {
|
||||
@@ -257,7 +302,9 @@ class PokemonRenderer(
|
||||
} else if (beamTarget is NPCEntity) {
|
||||
(beamTarget.delegate as NPCClientDelegate).locatorStates["beam"]?.getOrigin() ?: beamTarget.position()
|
||||
} else {
|
||||
val lookVec = beamTarget.lookAngle.yRot((PI / 2 - (beamTarget.visualRotationYInDegrees - beamTarget.xRot).toRadians()).toFloat()).multiply(1.0, 0.0, 1.0).normalize()
|
||||
val lookVec =
|
||||
beamTarget.lookAngle.yRot((PI / 2 - (beamTarget.visualRotationYInDegrees - beamTarget.xRot).toRadians()).toFloat())
|
||||
.multiply(1.0, 0.0, 1.0).normalize()
|
||||
beamTarget.getEyePosition(partialTicks).subtract(0.0, 0.7, 0.0).subtract(lookVec.scale(0.4))
|
||||
}
|
||||
}
|
||||
@@ -272,8 +319,9 @@ class PokemonRenderer(
|
||||
// the further away the source position is, the smaller the newOffset should be. Max distance is 20 blocks
|
||||
val distance = beamSourcePosition.distanceTo(entity.position())
|
||||
newOffset = newOffset.scale((distance / 10.0) * 5)
|
||||
newOffset = newOffset.multiply(0.0, 1+ease(clientDelegate.ballOffset.toDouble()), 0.0)
|
||||
val direction = pokemonPosition.subtract(beamSourcePosition.add(newOffset)).let { Vector3f(it.x.toFloat(), it.y.toFloat(), it.z.toFloat()) }
|
||||
newOffset = newOffset.multiply(0.0, 1 + ease(clientDelegate.ballOffset.toDouble()), 0.0)
|
||||
val direction = pokemonPosition.subtract(beamSourcePosition.add(newOffset))
|
||||
.let { Vector3f(it.x.toFloat(), it.y.toFloat(), it.z.toFloat()) }
|
||||
|
||||
matrixStack.pushPose()
|
||||
with(beamSourcePosition.subtract(entity.position())) {
|
||||
@@ -349,10 +397,10 @@ class PokemonRenderer(
|
||||
}
|
||||
val player = Minecraft.getInstance().player ?: return
|
||||
val d = this.entityRenderDispatcher.distanceToSqr(entity)
|
||||
if (d <= 4096.0){
|
||||
if (d <= 4096.0) {
|
||||
val scale = min(1.5, max(0.65, d.remap(DoubleRange(-16.0, 96.0), DoubleRange(0.0, 1.0))))
|
||||
val sizeScale = Mth.lerp(scale.remap(DoubleRange(0.65, 1.5), DoubleRange(0.0,1.0)), 0.5, 1.0)
|
||||
val offsetScale = Mth.lerp(scale.remap(DoubleRange(0.65, 1.5), DoubleRange(0.0,1.0)), 0.0,1.0)
|
||||
val sizeScale = Mth.lerp(scale.remap(DoubleRange(0.65, 1.5), DoubleRange(0.0, 1.0)), 0.5, 1.0)
|
||||
val offsetScale = Mth.lerp(scale.remap(DoubleRange(0.65, 1.5), DoubleRange(0.0, 1.0)), 0.0, 1.0)
|
||||
val entityHeight = entity.boundingBox.ysize + 0.5f
|
||||
matrices.pushPose()
|
||||
matrices.translate(0.0, entityHeight, 0.0)
|
||||
@@ -374,15 +422,48 @@ class PokemonRenderer(
|
||||
var h = (-this.font.width(label) / 2).toFloat()
|
||||
val y = 0F
|
||||
val packedLight = LightTexture.pack(15, 15)
|
||||
this.font.drawInBatch(label, h, y, 0x20FFFFFF, false, matrix4f, vertexConsumers, DisplayMode.SEE_THROUGH, opacity, packedLight)
|
||||
this.font.drawInBatch(
|
||||
label,
|
||||
h,
|
||||
y,
|
||||
0x20FFFFFF,
|
||||
false,
|
||||
matrix4f,
|
||||
vertexConsumers,
|
||||
DisplayMode.SEE_THROUGH,
|
||||
opacity,
|
||||
packedLight
|
||||
)
|
||||
this.font.drawInBatch(label, h, y, -1, false, matrix4f, vertexConsumers, DisplayMode.NORMAL, 0, packedLight)
|
||||
|
||||
if (CobblemonClient.clientPlayerData.showChallengeLabel && entity.canBattle(player)) {
|
||||
val sendOutBinding = PartySendBinding.boundKey().displayName
|
||||
val battlePrompt = lang("challenge_label", sendOutBinding)
|
||||
h = (-this.font.width(battlePrompt) / 2).toFloat()
|
||||
this.font.drawInBatch(battlePrompt, h, y + 10, 0x20FFFFFF, false, matrix4f, vertexConsumers, DisplayMode.SEE_THROUGH, opacity, packedLight)
|
||||
this.font.drawInBatch(battlePrompt, h, y + 10, -1, false, matrix4f, vertexConsumers, DisplayMode.NORMAL, 0, packedLight)
|
||||
this.font.drawInBatch(
|
||||
battlePrompt,
|
||||
h,
|
||||
y + 10,
|
||||
0x20FFFFFF,
|
||||
false,
|
||||
matrix4f,
|
||||
vertexConsumers,
|
||||
DisplayMode.SEE_THROUGH,
|
||||
opacity,
|
||||
packedLight
|
||||
)
|
||||
this.font.drawInBatch(
|
||||
battlePrompt,
|
||||
h,
|
||||
y + 10,
|
||||
-1,
|
||||
false,
|
||||
matrix4f,
|
||||
vertexConsumers,
|
||||
DisplayMode.NORMAL,
|
||||
0,
|
||||
packedLight
|
||||
)
|
||||
}
|
||||
matrices.popPose()
|
||||
}
|
||||
@@ -391,7 +472,10 @@ class PokemonRenderer(
|
||||
private fun resolveBaseLabel(entity: PokemonEntity): MutableComponent {
|
||||
return when {
|
||||
!ServerSettings.displayEntityNameLabel -> Component.empty()
|
||||
Cobblemon.config.displayNameForUnknownPokemon || CobblemonClient.clientPokedexData.getKnowledgeForSpecies(entity.pokemon.species.resourceIdentifier) != PokedexEntryProgress.NONE -> entity.name.copy()
|
||||
Cobblemon.config.displayNameForUnknownPokemon || CobblemonClient.clientPokedexData.getKnowledgeForSpecies(
|
||||
entity.pokemon.species.resourceIdentifier
|
||||
) != PokedexEntryProgress.NONE -> entity.name.copy()
|
||||
|
||||
else -> Component.literal(HIDDEN_NAME)
|
||||
}
|
||||
}
|
||||
@@ -416,7 +500,7 @@ class PokemonRenderer(
|
||||
} else {
|
||||
matrixStack.translate(0.0, -0.2, 0.0)
|
||||
val rot = 360F * distance
|
||||
if(ball.name.toString().contains("beast")){
|
||||
if (ball.name.toString().contains("beast")) {
|
||||
matrixStack.mulPose(Axis.ZN.rotationDegrees(Math.lerp(0F, rot, scale)))
|
||||
} else {
|
||||
matrixStack.mulPose(Axis.XN.rotationDegrees(Math.lerp(0F, rot, scale)))
|
||||
@@ -440,12 +524,12 @@ class PokemonRenderer(
|
||||
}
|
||||
|
||||
private fun drawPlatform(
|
||||
matrixStack: PoseStack,
|
||||
entity: PokemonEntity,
|
||||
scale: Float = 1F,
|
||||
buff: MultiBufferSource,
|
||||
packedLight: Int,
|
||||
) {
|
||||
matrixStack: PoseStack,
|
||||
entity: PokemonEntity,
|
||||
scale: Float = 1F,
|
||||
buff: MultiBufferSource,
|
||||
packedLight: Int,
|
||||
) {
|
||||
val (modelResource, textureResource) = PlatformType.getModelWithTexture(entity.platform)
|
||||
val model = MiscModelRepository.modelOf(modelResource) ?: return
|
||||
matrixStack.pushPose()
|
||||
|
||||
+564
@@ -0,0 +1,564 @@
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"animations": {
|
||||
"animation.egg.idle": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"egg": {
|
||||
"rotation": [0, 0, 0],
|
||||
"position": [0, 0, 0]
|
||||
},
|
||||
"body": {
|
||||
"rotation": [0, 0, 0],
|
||||
"position": [0, 0, 0]
|
||||
},
|
||||
"egg_shell1": {
|
||||
"position": [0, "math.sin(q.anim_time*90+1)", 0]
|
||||
},
|
||||
"egg_shell2": {
|
||||
"position": [0, "math.sin(q.anim_time*90+2)", 0]
|
||||
},
|
||||
"egg_shell3": {
|
||||
"position": [0, "math.sin(q.anim_time*90+3)", 0]
|
||||
},
|
||||
"egg_shell4": {
|
||||
"position": [0, "math.sin(q.anim_time*90+4)", 0]
|
||||
},
|
||||
"egg_shell5": {
|
||||
"position": [0, "math.sin(q.anim_time*90+5)", 0]
|
||||
},
|
||||
"egg_shell6": {
|
||||
"position": [0, "math.sin(q.anim_time*90+6)", 0]
|
||||
},
|
||||
"egg_shell7": {
|
||||
"position": [0, "math.sin(q.anim_time*90+7)", 0]
|
||||
},
|
||||
"egg_shell8": {
|
||||
"position": [0, "math.sin(q.anim_time*90+8)", 0]
|
||||
},
|
||||
"egg_shell9": {
|
||||
"position": [0, "math.sin(q.anim_time*90+9)", 0]
|
||||
},
|
||||
"egg_shell10": {
|
||||
"position": [0, "math.sin(q.anim_time*90+10)", 0]
|
||||
},
|
||||
"egg_shell11": {
|
||||
"position": [0, "math.sin(q.anim_time*90+11)", 0]
|
||||
},
|
||||
"egg_shell12": {
|
||||
"position": [0, "math.sin(q.anim_time*90+12)", 0]
|
||||
},
|
||||
"egg_shell13": {
|
||||
"position": [0, "math.sin(q.anim_time*90+13)", 0]
|
||||
},
|
||||
"egg_shell14": {
|
||||
"position": [0, "math.sin(q.anim_time*90+14)", 0]
|
||||
},
|
||||
"egg_shell15": {
|
||||
"position": [0, "math.sin(q.anim_time*90+15)", 0]
|
||||
},
|
||||
"egg_shell16": {
|
||||
"position": [0, "math.sin(q.anim_time*90+16)", 0]
|
||||
},
|
||||
"egg_shell17": {
|
||||
"position": [0, "math.sin(q.anim_time*90+17)", 0]
|
||||
},
|
||||
"egg_shell18": {
|
||||
"position": [0, "math.sin(q.anim_time*90+18)", 0]
|
||||
},
|
||||
"egg_shell19": {
|
||||
"position": [0, "math.sin(q.anim_time*90+19)", 0]
|
||||
},
|
||||
"egg_shell20": {
|
||||
"position": [0, "math.sin(q.anim_time*90+20)", 0]
|
||||
},
|
||||
"egg_shell21": {
|
||||
"position": [0, "math.sin(q.anim_time*90+21)", 0]
|
||||
},
|
||||
"egg_shell22": {
|
||||
"position": [0, "math.sin(q.anim_time*90+22)", 0]
|
||||
},
|
||||
"egg_shell23": {
|
||||
"position": [0, "math.sin(q.anim_time*90+23)", 0]
|
||||
},
|
||||
"egg_shell24": {
|
||||
"position": [0, "math.sin(q.anim_time*90+24)", 0]
|
||||
},
|
||||
"egg_shell25": {
|
||||
"position": [0, "math.sin(q.anim_time*90+25)", 0]
|
||||
},
|
||||
"egg_shell26": {
|
||||
"position": [0, "math.sin(q.anim_time*90+26)", 0]
|
||||
},
|
||||
"egg_shell27": {
|
||||
"position": [0, "math.sin(q.anim_time*90+27)", 0]
|
||||
},
|
||||
"egg_shell28": {
|
||||
"position": [0, "math.sin(q.anim_time*90+28)", 0]
|
||||
},
|
||||
"egg_shell29": {
|
||||
"position": [0, "math.sin(q.anim_time*90+29)", 0]
|
||||
},
|
||||
"egg_shell30": {
|
||||
"position": [0, "math.sin(q.anim_time*90+30)", 0]
|
||||
},
|
||||
"egg_shell31": {
|
||||
"position": [0, "math.sin(q.anim_time*90+31)", 0]
|
||||
},
|
||||
"egg_shell32": {
|
||||
"position": [0, "math.sin(q.anim_time*90+32)", 0]
|
||||
},
|
||||
"egg_shell33": {
|
||||
"position": [0, "math.sin(q.anim_time*90+33)", 0]
|
||||
},
|
||||
"egg_shell34": {
|
||||
"position": [0, "math.sin(q.anim_time*90+34)", 0]
|
||||
},
|
||||
"egg_shell35": {
|
||||
"position": [0, "math.sin(q.anim_time*90+35)", 0]
|
||||
},
|
||||
"egg_shell36": {
|
||||
"position": [0, "math.sin(q.anim_time*90+36)", 0]
|
||||
},
|
||||
"egg_shell37": {
|
||||
"position": [0, "math.sin(q.anim_time*90+37)", 0]
|
||||
},
|
||||
"egg_shell38": {
|
||||
"position": [0, "math.sin(q.anim_time*90+38)", 0]
|
||||
},
|
||||
"egg_shell39": {
|
||||
"position": [0, "math.sin(q.anim_time*90+39)", 0]
|
||||
},
|
||||
"egg_shell40": {
|
||||
"position": [0, "math.sin(q.anim_time*90+40)", 0]
|
||||
},
|
||||
"egg_shell41": {
|
||||
"position": [0, "math.sin(q.anim_time*90+41)", 0]
|
||||
},
|
||||
"egg_shell42": {
|
||||
"position": [0, "math.sin(q.anim_time*90+42)", 0]
|
||||
},
|
||||
"egg_shell43": {
|
||||
"position": [0, "math.sin(q.anim_time*90+43)", 0]
|
||||
},
|
||||
"egg_shell44": {
|
||||
"position": [0, "math.sin(q.anim_time*90+44)", 0]
|
||||
},
|
||||
"egg_shell45": {
|
||||
"position": [0, "math.sin(q.anim_time*90+45)", 0]
|
||||
},
|
||||
"egg_shell46": {
|
||||
"position": [0, "math.sin(q.anim_time*90+46)", 0]
|
||||
},
|
||||
"egg_shell47": {
|
||||
"position": [0, "math.sin(q.anim_time*90+47)", 0]
|
||||
},
|
||||
"egg_shell48": {
|
||||
"position": [0, "math.sin(q.anim_time*90+48)", 0]
|
||||
},
|
||||
"egg_shell49": {
|
||||
"position": [0, "math.sin(q.anim_time*90+49)", 0]
|
||||
},
|
||||
"egg_shell50": {
|
||||
"position": [0, "math.sin(q.anim_time*90+50)", 0]
|
||||
},
|
||||
"egg_shell51": {
|
||||
"position": [0, "math.sin(q.anim_time*90+51)", 0]
|
||||
},
|
||||
"egg_shell52": {
|
||||
"position": [0, "math.sin(q.anim_time*90+52)", 0]
|
||||
},
|
||||
"egg_shell53": {
|
||||
"position": [0, "math.sin(q.anim_time*90+53)", 0]
|
||||
},
|
||||
"egg_shell54": {
|
||||
"position": [0, "math.sin(q.anim_time*90+54)", 0]
|
||||
},
|
||||
"egg_shell55": {
|
||||
"position": [0, "math.sin(q.anim_time*90+55)", 0]
|
||||
},
|
||||
"egg_shell56": {
|
||||
"position": [0, "math.sin(q.anim_time*90+56)", 0]
|
||||
},
|
||||
"egg_shell57": {
|
||||
"position": [0, "math.sin(q.anim_time*90+57)", 0]
|
||||
},
|
||||
"egg_shell58": {
|
||||
"position": [0, "math.sin(q.anim_time*90+58)", 0]
|
||||
},
|
||||
"egg_shell59": {
|
||||
"position": [0, "math.sin(q.anim_time*90+59)", 0]
|
||||
},
|
||||
"egg_shell60": {
|
||||
"position": [0, "math.sin(q.anim_time*90+60)", 0]
|
||||
},
|
||||
"egg_shell61": {
|
||||
"position": [0, "math.sin(q.anim_time*90+61)", 0]
|
||||
},
|
||||
"egg_shell62": {
|
||||
"position": [0, "math.sin(q.anim_time*90+62)", 0]
|
||||
},
|
||||
"egg_shell63": {
|
||||
"position": [0, "math.sin(q.anim_time*90+63)", 0]
|
||||
},
|
||||
"egg_shell64": {
|
||||
"position": [0, "math.sin(q.anim_time*90+64)", 0]
|
||||
},
|
||||
"egg_shell65": {
|
||||
"position": [0, "math.sin(q.anim_time*90+65)", 0]
|
||||
},
|
||||
"egg_shell66": {
|
||||
"position": [0, "math.sin(q.anim_time*90+66)", 0]
|
||||
},
|
||||
"egg_shell67": {
|
||||
"position": [0, "math.sin(q.anim_time*90+67)", 0]
|
||||
},
|
||||
"egg_shell68": {
|
||||
"position": [0, "math.sin(q.anim_time*90+68)", 0]
|
||||
},
|
||||
"egg_shell69": {
|
||||
"position": [0, "math.sin(q.anim_time*90+69)", 0]
|
||||
},
|
||||
"egg_shell70": {
|
||||
"position": [0, "math.sin(q.anim_time*90+70)", 0]
|
||||
},
|
||||
"egg_shell71": {
|
||||
"position": [0, "math.sin(q.anim_time*90+71)", 0]
|
||||
},
|
||||
"egg_shell72": {
|
||||
"position": [0, "math.sin(q.anim_time*90+72)", 0]
|
||||
},
|
||||
"egg_shell73": {
|
||||
"position": [0, "math.sin(q.anim_time*90+73)", 0]
|
||||
},
|
||||
"egg_shell74": {
|
||||
"position": [0, "math.sin(q.anim_time*90+74)", 0]
|
||||
},
|
||||
"egg_shell75": {
|
||||
"position": [0, "math.sin(q.anim_time*90+75)", 0]
|
||||
},
|
||||
"egg_shell76": {
|
||||
"position": [0, "math.sin(q.anim_time*90+76)", 0]
|
||||
},
|
||||
"egg_shell77": {
|
||||
"position": [0, "math.sin(q.anim_time*90+77)", 0]
|
||||
},
|
||||
"egg_shell78": {
|
||||
"position": [0, "math.sin(q.anim_time*90+78)", 0]
|
||||
},
|
||||
"egg_shell79": {
|
||||
"position": [0, "math.sin(q.anim_time*90+79)", 0]
|
||||
},
|
||||
"egg_shell80": {
|
||||
"position": [0, "math.sin(q.anim_time*90+80)", 0]
|
||||
},
|
||||
"egg_shell81": {
|
||||
"position": [0, "math.sin(q.anim_time*90+81)", 0]
|
||||
},
|
||||
"egg_shell82": {
|
||||
"position": [0, "math.sin(q.anim_time*90+82)", 0]
|
||||
},
|
||||
"egg_shell83": {
|
||||
"position": [0, "math.sin(q.anim_time*90+83)", 0]
|
||||
},
|
||||
"egg_shell84": {
|
||||
"position": [0, "math.sin(q.anim_time*90+84)", 0]
|
||||
},
|
||||
"egg_shell85": {
|
||||
"position": [0, "math.sin(q.anim_time*90+85)", 0]
|
||||
},
|
||||
"egg_shell86": {
|
||||
"position": [0, "math.sin(q.anim_time*90+86)", 0]
|
||||
},
|
||||
"egg_shell87": {
|
||||
"position": [0, "math.sin(q.anim_time*90+87)", 0]
|
||||
},
|
||||
"egg_shell88": {
|
||||
"position": [0, "math.sin(q.anim_time*90+88)", 0]
|
||||
},
|
||||
"egg_shell89": {
|
||||
"position": [0, "math.sin(q.anim_time*90+89)", 0]
|
||||
},
|
||||
"egg_shell90": {
|
||||
"position": [0, "math.sin(q.anim_time*90+90)", 0]
|
||||
},
|
||||
"egg_shell91": {
|
||||
"position": [0, "math.sin(q.anim_time*90+91)", 0]
|
||||
},
|
||||
"egg_shell92": {
|
||||
"position": [0, "math.sin(q.anim_time*90+92)", 0]
|
||||
},
|
||||
"egg_shell93": {
|
||||
"position": [0, "math.sin(q.anim_time*90+93)", 0]
|
||||
},
|
||||
"egg_shell94": {
|
||||
"position": [0, "math.sin(q.anim_time*90+94)", 0]
|
||||
},
|
||||
"egg_shell95": {
|
||||
"position": [0, "math.sin(q.anim_time*90+95)", 0]
|
||||
},
|
||||
"egg_shell96": {
|
||||
"position": [0, "math.sin(q.anim_time*90+96)", 0]
|
||||
},
|
||||
"egg_shell97": {
|
||||
"position": [0, "math.sin(q.anim_time*90+97)", 0]
|
||||
},
|
||||
"egg_shell98": {
|
||||
"position": [0, "math.sin(q.anim_time*90+98)", 0]
|
||||
},
|
||||
"egg_shell99": {
|
||||
"position": [0, "math.sin(q.anim_time*90+99)", 0]
|
||||
},
|
||||
"egg_shell100": {
|
||||
"position": [0, "math.sin(q.anim_time*90+100)", 0]
|
||||
},
|
||||
"egg_shell105": {
|
||||
"position": [0, "math.sin(q.anim_time*90+105+1)", 0]
|
||||
},
|
||||
"egg_shell106": {
|
||||
"position": [0, "math.sin(q.anim_time*90+106+1)", 0]
|
||||
},
|
||||
"egg_shell107": {
|
||||
"position": [0, "math.sin(q.anim_time*90+107+1)", 0]
|
||||
},
|
||||
"egg_shell108": {
|
||||
"position": [0, "math.sin(q.anim_time*90+108+1)", 0]
|
||||
},
|
||||
"egg_shell109": {
|
||||
"position": [0, "math.sin(q.anim_time*90+109+1)", 0]
|
||||
},
|
||||
"egg_shell110": {
|
||||
"position": [0, "math.sin(q.anim_time*90+110+1)", 0]
|
||||
},
|
||||
"egg_shell111": {
|
||||
"position": [0, "math.sin(q.anim_time*90+111+1)", 0]
|
||||
},
|
||||
"egg_shell112": {
|
||||
"position": [0, "math.sin(q.anim_time*90+112+1)", 0]
|
||||
},
|
||||
"egg_shell113": {
|
||||
"position": [0, "math.sin(q.anim_time*90+113+1)", 0]
|
||||
},
|
||||
"egg_shell114": {
|
||||
"position": [0, "math.sin(q.anim_time*90+114+1)", 0]
|
||||
},
|
||||
"egg_shell115": {
|
||||
"position": [0, "math.sin(q.anim_time*90+115+1)", 0]
|
||||
},
|
||||
"egg_shell116": {
|
||||
"position": [0, "math.sin(q.anim_time*90+116+1)", 0]
|
||||
},
|
||||
"egg_shell117": {
|
||||
"position": [0, "math.sin(q.anim_time*90+117+1)", 0]
|
||||
},
|
||||
"egg_shell118": {
|
||||
"position": [0, "math.sin(q.anim_time*90+118+1)", 0]
|
||||
},
|
||||
"egg_shell119": {
|
||||
"position": [0, "math.sin(q.anim_time*90+119+1)", 0]
|
||||
},
|
||||
"egg_shell120": {
|
||||
"position": [0, "math.sin(q.anim_time*90+120+1)", 0]
|
||||
},
|
||||
"egg_shell121": {
|
||||
"position": [0, "math.sin(q.anim_time*90+121+1)", 0]
|
||||
},
|
||||
"egg_shell123": {
|
||||
"position": [0, "math.sin(q.anim_time*90+123+1)", 0]
|
||||
},
|
||||
"egg_shell124": {
|
||||
"position": [0, "math.sin(q.anim_time*90+124+1)", 0]
|
||||
},
|
||||
"egg_shell125": {
|
||||
"position": [0, "math.sin(q.anim_time*90+125+1)", 0]
|
||||
},
|
||||
"egg_shell126": {
|
||||
"position": [0, "math.sin(q.anim_time*90+126+1)", 0]
|
||||
},
|
||||
"egg_shell127": {
|
||||
"position": [0, "math.sin(q.anim_time*90+127+1)", 0]
|
||||
},
|
||||
"egg_shell128": {
|
||||
"position": [0, "math.sin(q.anim_time*90+128+1)", 0]
|
||||
},
|
||||
"egg_shell129": {
|
||||
"position": [0, "math.sin(q.anim_time*90+129+1)", 0]
|
||||
},
|
||||
"egg_shell130": {
|
||||
"position": [0, "math.sin(q.anim_time*90+130+1)", 0]
|
||||
},
|
||||
"egg_shell131": {
|
||||
"position": [0, "math.sin(q.anim_time*90+131+1)", 0]
|
||||
},
|
||||
"egg_shell132": {
|
||||
"position": [0, "math.sin(q.anim_time*90+132+1)", 0]
|
||||
},
|
||||
"egg_shell133": {
|
||||
"position": [0, "math.sin(q.anim_time*90+133+1)", 0]
|
||||
},
|
||||
"egg_shell134": {
|
||||
"position": [0, "math.sin(q.anim_time*90+134+1)", 0]
|
||||
},
|
||||
"egg_shell135": {
|
||||
"position": [0, "math.sin(q.anim_time*90+135+1)", 0]
|
||||
},
|
||||
"egg_shell136": {
|
||||
"position": [0, "math.sin(q.anim_time*90+136+1)", 0]
|
||||
},
|
||||
"egg_shell137": {
|
||||
"position": [0, "math.sin(q.anim_time*90+137+1)", 0]
|
||||
},
|
||||
"egg_shell138": {
|
||||
"position": [0, "math.sin(q.anim_time*90+138+1)", 0]
|
||||
},
|
||||
"egg_shell139": {
|
||||
"position": [0, "math.sin(q.anim_time*90+139+1)", 0]
|
||||
},
|
||||
"egg_shell140": {
|
||||
"position": [0, "math.sin(q.anim_time*90+140+1)", 0]
|
||||
},
|
||||
"egg_shell141": {
|
||||
"position": [0, "math.sin(q.anim_time*90+141+1)", 0]
|
||||
},
|
||||
"egg_shell142": {
|
||||
"position": [0, "math.sin(q.anim_time*90+142+1)", 0]
|
||||
},
|
||||
"egg_shell143": {
|
||||
"position": [0, "math.sin(q.anim_time*90+143+1)", 0]
|
||||
},
|
||||
"egg_shell144": {
|
||||
"position": [0, "math.sin(q.anim_time*90+144+1)", 0]
|
||||
},
|
||||
"egg_shell145": {
|
||||
"position": [0, "math.sin(q.anim_time*90+145+1)", 0]
|
||||
},
|
||||
"egg_shell146": {
|
||||
"position": [0, "math.sin(q.anim_time*90+146+1)", 0]
|
||||
},
|
||||
"egg_shell147": {
|
||||
"position": [0, "math.sin(q.anim_time*90+147+1)", 0]
|
||||
},
|
||||
"egg_shell148": {
|
||||
"position": [0, "math.sin(q.anim_time*90+148+1)", 0]
|
||||
},
|
||||
"egg_shell149": {
|
||||
"position": [0, "math.sin(q.anim_time*90+149+1)", 0]
|
||||
},
|
||||
"egg_shell150": {
|
||||
"position": [0, "math.sin(q.anim_time*90+150+1)", 0]
|
||||
},
|
||||
"egg_shell151": {
|
||||
"position": [0, "math.sin(q.anim_time*90+151+1)", 0]
|
||||
},
|
||||
"egg_shell152": {
|
||||
"position": [0, "math.sin(q.anim_time*90+152+1)", 0]
|
||||
},
|
||||
"egg_shell153": {
|
||||
"position": [0, "math.sin(q.anim_time*90+153+1)", 0]
|
||||
},
|
||||
"egg_shell154": {
|
||||
"position": [0, "math.sin(q.anim_time*90+154+1)", 0]
|
||||
},
|
||||
"egg_shell155": {
|
||||
"position": [0, "math.sin(q.anim_time*90+155+1)", 0]
|
||||
},
|
||||
"egg_shell156": {
|
||||
"position": [0, "math.sin(q.anim_time*90+156+1)", 0]
|
||||
},
|
||||
"egg_shell157": {
|
||||
"position": [0, "math.sin(q.anim_time*90+157+1)", 0]
|
||||
},
|
||||
"egg_shell158": {
|
||||
"position": [0, "math.sin(q.anim_time*90+158+1)", 0]
|
||||
},
|
||||
"egg_shell159": {
|
||||
"position": [0, "math.sin(q.anim_time*90+159+1)", 0]
|
||||
},
|
||||
"egg_shell160": {
|
||||
"position": [0, "math.sin(q.anim_time*90+160+1)", 0]
|
||||
},
|
||||
"egg_shell161": {
|
||||
"position": [0, "math.sin(q.anim_time*90+161+1)", 0]
|
||||
},
|
||||
"egg_shell162": {
|
||||
"position": [0, "math.sin(q.anim_time*90+162+1)", 0]
|
||||
},
|
||||
"egg_shell163": {
|
||||
"position": [0, "math.sin(q.anim_time*90+163+1)", 0]
|
||||
},
|
||||
"egg_shell164": {
|
||||
"position": [0, "math.sin(q.anim_time*90+164+1)", 0]
|
||||
},
|
||||
"egg_shell165": {
|
||||
"position": [0, "math.sin(q.anim_time*90+165+1)", 0]
|
||||
},
|
||||
"egg_shell166": {
|
||||
"position": [0, "math.sin(q.anim_time*90+166+1)", 0]
|
||||
},
|
||||
"egg_shell167": {
|
||||
"position": [0, "math.sin(q.anim_time*90+167+1)", 0]
|
||||
},
|
||||
"egg_shell168": {
|
||||
"position": [0, "math.sin(q.anim_time*90+168+1)", 0]
|
||||
},
|
||||
"egg_shell169": {
|
||||
"position": [0, "math.sin(q.anim_time*90+169+1)", 0]
|
||||
},
|
||||
"egg_shell170": {
|
||||
"position": [0, "math.sin(q.anim_time*90+170+1)", 0]
|
||||
},
|
||||
"egg_shell171": {
|
||||
"position": [0, "math.sin(q.anim_time*90+171+1)", 0]
|
||||
},
|
||||
"egg_shell172": {
|
||||
"position": [0, "math.sin(q.anim_time*90+172+1)", 0]
|
||||
},
|
||||
"egg_shell173": {
|
||||
"position": [0, "math.sin(q.anim_time*90+173+1)", 0]
|
||||
},
|
||||
"egg_shell174": {
|
||||
"position": [0, "math.sin(q.anim_time*90+174+1)", 0]
|
||||
},
|
||||
"egg_shell175": {
|
||||
"position": [0, "math.sin(q.anim_time*90+175+1)", 0]
|
||||
},
|
||||
"egg_shell176": {
|
||||
"position": [0, "math.sin(q.anim_time*90+176+1)", 0]
|
||||
},
|
||||
"egg_shell177": {
|
||||
"position": [0, "math.sin(q.anim_time*90+177+1)", 0]
|
||||
},
|
||||
"egg_shell178": {
|
||||
"position": [0, "math.sin(q.anim_time*90+178+1)", 0]
|
||||
},
|
||||
"egg_shell179": {
|
||||
"position": [0, "math.sin(q.anim_time*90+179+1)", 0]
|
||||
},
|
||||
"egg_shell180": {
|
||||
"position": [0, "math.sin(q.anim_time*90+180+1)", 0]
|
||||
},
|
||||
"egg_shell181": {
|
||||
"position": [0, "math.sin(q.anim_time*90+181+1)", 0]
|
||||
},
|
||||
"egg_shell182": {
|
||||
"position": [0, "math.sin(q.anim_time*90+182+1)", 0]
|
||||
},
|
||||
"egg_shell183": {
|
||||
"position": [0, "math.sin(q.anim_time*90+183+1)", 0]
|
||||
},
|
||||
"egg_shell184": {
|
||||
"position": [0, "math.sin(q.anim_time*90+184+1)", 0]
|
||||
},
|
||||
"egg_shell185": {
|
||||
"position": [0, "math.sin(q.anim_time*90+185+1)", 0]
|
||||
},
|
||||
"egg_body": {
|
||||
"position": [0, 0, 0]
|
||||
},
|
||||
"egg_body185": {
|
||||
"position": [0, 0, 5]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"model": "q.appendage_model('cobblemon:egg');",
|
||||
"target_locator": "head",
|
||||
"scale": [1.0, 1.0, 1.0],
|
||||
"offset": [0.0, 0, 0.0],
|
||||
"rotation": [0.0, 45.0, 0.0]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"poses": {
|
||||
"standing": {
|
||||
"poseName": "standing",
|
||||
"transformTicks": 0,
|
||||
"poseTypes": ["STAND", "WALK", "SLEEP", "HOVER", "FLY", "FLOAT", "SWIM", "PORTRAIT", "PROFILE"],
|
||||
"animations": [
|
||||
"q.bedrock('egg', 'idle')"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "cobblemon:egg",
|
||||
"order": 0,
|
||||
"variations": [
|
||||
{
|
||||
"aspects": [
|
||||
"shiny"
|
||||
],
|
||||
"poser": "cobblemon:egg",
|
||||
"model": "cobblemon:egg.geo",
|
||||
"texture": "cobblemon:textures/appendage/egg.png",
|
||||
"layers": []
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 395 B |
Reference in New Issue
Block a user