Merge branch 'main' into Bee-Polite-Bee-Efficient

This commit is contained in:
JazzMcNade
2025-08-09 13:58:48 -05:00
14 changed files with 214 additions and 28 deletions
+3 -1
View File
@@ -40,7 +40,8 @@
- Ground type Pokémon are immune to lightning damage
- Added functionality to Everstone when held by a Pokémon; suppresses evolution notification and hides evolve button in summary interface.
- Added new optional property `attachment_options` for most EmitterShapes to be attached to the locator/entities scale, rotation, and/or position. Position is true by default.
- Galarica Nut bushes now generate on beaches
- Galarica Nut bushes now generate on beaches.
- Some Pokémon now pitch their bodies in the direction they're moving.
### Pokémon Added
@@ -398,6 +399,7 @@
- Added `q.has_argument(<argument_name>, [argument_value])` MoLang function to several battle-related action effect contexts.
- Added `q.has_argument_at(<index>, [argument_value])` MoLang function to several battle-related action effect contexts.
- Added `q.hit_count` MoLang function to move action effect contexts.
- Added `is_included`, `to_lower`, `to_upper`, and `string_length` as available Molang functions.
## [1.6.1 (January 26th, 2025)](#1-6-1)
@@ -168,6 +168,20 @@ object MoLangFunctions {
val replace = params.getString(2)
return@Function StringValue(text.replace(search, replace))
},
"is_included" to java.util.function.Function { params ->
val text = params.getString(0)
val search = params.getString(1)
return@Function DoubleValue(text.contains(search))
},
"to_lower" to java.util.function.Function { params ->
return@Function StringValue(params.getString(0).lowercase())
},
"to_upper" to java.util.function.Function { params ->
return@Function StringValue(params.getString(0).uppercase())
},
"string_length" to java.util.function.Function { params ->
return@Function DoubleValue(params.getString(0).length)
},
"is_blank" to java.util.function.Function { params ->
val arg = params.get<MoValue>(0)
return@Function DoubleValue((arg is StringValue && (arg.value.isBlank() || arg.value.toDoubleOrNull() == 0.0)) || (arg is DoubleValue && arg.value == 0.0))
@@ -693,6 +707,9 @@ object MoLangFunctions {
val owner = entity.owner
return@put owner?.asMostSpecificMoLangValue() ?: DoubleValue.ZERO
}
map.put("delta_movement") {
return@put listOf(entity.deltaMovement.x, entity.deltaMovement.y, entity.deltaMovement.z).asArrayValue(::DoubleValue)
}
if (entity is MoLangScriptingEntity) {
map.put("add_callback") { params ->
@@ -19,7 +19,15 @@ import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.text.text
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.animation.ActiveAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BimanualSwingAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.PitchTiltAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.PrimaryAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.PunchAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.QuadrupedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.SingleBoneLookAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.WingFlapIdleAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunction
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.sineFunction
@@ -117,6 +125,22 @@ object ClientMoLangFunctions {
ObjectValue(anim)
}
},
"pitch_tilt" to Function {
model -> Function { params ->
val bone = params.getStringOrNull(0) ?: "root"
val maxChangePerTick = params.getDoubleOrNull(1) ?: 1.5F
val minPitch = params.getDoubleOrNull(2) ?: -45F
val maxPitch = params.getDoubleOrNull(3) ?: 45F
ObjectValue(
PitchTiltAnimation(
bone = model.getPart(bone),
minPitch = minPitch.toFloat(),
maxPitch = maxPitch.toFloat(),
maxChangePerTick = maxChangePerTick.toFloat()
)
)
}
},
"look" to Function {
model -> Function { params ->
val boneName = params.getString(0)
@@ -607,6 +607,7 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
setDefault()
// Applies any of the state's queued actions.
state.preRender()
state.renderMarkers.clear()
// Performs a check that the current pose is correct and returns back which pose we should be applying. Even if
// a change of pose is necessary, if it's going to gradually transition there then we're still going to keep
// applying our current pose until that process is done.
@@ -758,6 +759,8 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
yRot = Mth.lerp(state.getPartialTicks(), entity.yBodyRotO, entity.yBodyRot)
yRot = 180f - Mth.wrapDegrees(yRot)
}
//For some reason locators are positioned upside-down so this fixes that
matrixStack.mulPose(Axis.ZP.rotationDegrees(180f))
} else if (entity is EmptyPokeBallEntity) {
scale = 0.7F
yRot = Mth.lerp(state.getPartialTicks(), entity.yRot, entity.yRotO)
@@ -773,9 +776,6 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
matrixStack.scale(scale, scale, scale)
matrixStack.mulPose(Axis.YP.rotationDegrees(yRot))
//For some reason locators are positioned upside-down so this fixes that
matrixStack.mulPose(Axis.ZP.rotationDegrees(180f))
locatorAccess.update(matrixStack, entity, scale, state.locatorStates, isRoot = true)
}
@@ -131,6 +131,14 @@ abstract class PosableState : Schedulable {
/** A list of items to be rendered on a PosableModel during an animation */
val animationItems = mutableMapOf<String, ItemStack>()
/** Just some numbers that might be getting arbitrarily set and referenced. */
val numbers = mutableMapOf<String, Float>()
/**
* Markers that have been added to the state this render, cleared when animation is about to start.
* This is used to hand basic state from one animation to another.
*/
val renderMarkers = mutableSetOf<String>()
/** All of the MoLang functions that can be expose current riding data. */
val ridingFunctions = QueryStruct(hashMapOf())
.addFunction("pitch") { params ->
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.animation
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.addRotation
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Bone
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.util.math.geometry.toDegrees
import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.util.Mth
/**
* Animation used to tilt the targeted bone of the entity by a pitch that is proportionate
* to the direction the entity is moving. This is used to make birds and fish tilt upwards
* or downwards based on their motion.
*
* @author Hiroku
* @since August 9th, 2025
*/
class PitchTiltAnimation(
val bone: Bone,
val maxChangePerTick: Float = 1F,
val minPitch: Float = -45F,
val maxPitch: Float = 45F,
) : PoseAnimation() {
companion object {
const val PREVIOUS_ANGLE = "previous_pitch_tilt_angle"
const val PITCHED_TILT = "has_pitched_tilt"
}
override fun setupAnim(
context: RenderContext,
model: PosableModel,
state: PosableState,
limbSwing: Float,
limbSwingAmount: Float,
ageInTicks: Float,
headYaw: Float,
headPitch: Float,
intensity: Float
) {
val entity = context.entity ?: return
if (entity.passengers.isNotEmpty()) {
return
}
val delta = entity.deltaMovement
// The angleOfMotion should be 0 in the case that horizontal movement is 1 and vertical movement is 0.
// It should be the angle in degrees that becomes higher as the entity's motion becomes more upwards, and negative as the entity's motion becomes more downwards
val vertical = delta.y
val horizontal = delta.horizontalDistance()
val angleOfMotion = if (horizontal == 0.0) {
when {
vertical > 0 -> maxPitch
vertical < 0 -> minPitch
else -> 0F
}
} else {
Mth.atan2(vertical, horizontal).toDegrees()
}.coerceIn(minPitch, maxPitch)
val maxChangePerTick = this.maxChangePerTick * intensity
val lastAngle = state.numbers[PREVIOUS_ANGLE] ?: 0F
val interpolatedAngle = if (angleOfMotion - lastAngle > maxChangePerTick) {
lastAngle + maxChangePerTick
} else if (angleOfMotion - lastAngle < -maxChangePerTick) {
lastAngle - maxChangePerTick
} else {
angleOfMotion
}
bone.addRotation(0, -interpolatedAngle.toRadians())
state.numbers[PREVIOUS_ANGLE] = interpolatedAngle
state.renderMarkers += PITCHED_TILT
}
}
@@ -11,6 +11,8 @@ package com.cobblemon.mod.common.client.render.models.blockbench.animation
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.addRotation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.PitchTiltAnimation.Companion.PITCHED_TILT
import com.cobblemon.mod.common.client.render.models.blockbench.animation.PitchTiltAnimation.Companion.PREVIOUS_ANGLE
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Bone
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation.Companion.X_AXIS
@@ -63,7 +65,10 @@ class SingleBoneLookAnimation(
val head = bone ?: return
val pitch = pitchMultiplier * headPitch.coerceIn(minPitch, maxPitch)
val yaw = yawMultiplier * headYaw.coerceIn(minYaw, maxYaw)
head.addRotation(X_AXIS, pitch.toRadians() * intensity)
// If PitchTiltAnimation was applied then we should counteract that tilt. It does kinda
// assume that the tilt was on the body bone, though.
val counterTiltDegrees = if (PITCHED_TILT in state.renderMarkers) { state.numbers[PREVIOUS_ANGLE] ?: 0 } else 0F
head.addRotation(X_AXIS, (pitch.toRadians() * intensity) + counterTiltDegrees.toRadians())
head.addRotation(Y_AXIS, yaw.toRadians() * intensity)
}
}
@@ -8,6 +8,7 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1
import com.cobblemon.mod.common.client.render.models.blockbench.animation.PitchTiltAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
@@ -86,6 +87,7 @@ class PidgeyModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
PitchTiltAnimation(bone = getPart("body"), maxChangePerTick = 1F),
singleBoneLook(),
bedrock("pidgey", "air_idle")
)
@@ -103,6 +105,7 @@ class PidgeyModel(root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
PitchTiltAnimation(bone = getPart("body"), maxChangePerTick = 1F),
singleBoneLook(),
bedrock("pidgey", "air_fly")
)
@@ -36,16 +36,26 @@ import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity.Companion.SPAWN_DIRECTION
import com.cobblemon.mod.common.pokeball.PokeBall
import com.cobblemon.mod.common.util.*
import com.cobblemon.mod.common.util.effectiveName
import com.cobblemon.mod.common.util.isLookingAt
import com.cobblemon.mod.common.util.lang
import com.cobblemon.mod.common.util.math.DoubleRange
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.PI
import kotlin.math.ceil
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.sqrt
import net.minecraft.ChatFormatting
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.Font.DisplayMode
import net.minecraft.client.renderer.*
import net.minecraft.client.renderer.LightTexture
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.entity.EntityRendererProvider
import net.minecraft.client.renderer.entity.ItemRenderer
import net.minecraft.client.renderer.entity.MobRenderer
@@ -57,8 +67,11 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.util.Mth
import net.minecraft.world.entity.Entity
import net.minecraft.world.phys.Vec3
import org.joml.*
import kotlin.math.*
import org.joml.Math
import org.joml.Matrix4f
import org.joml.Quaternionf
import org.joml.Vector3f
import org.joml.Vector4f
class PokemonRenderer(
context: EntityRendererProvider.Context
@@ -127,7 +140,7 @@ class PokemonRenderer(
clientDelegate
)
}
if(entity.platform != PlatformType.NONE) {
if (entity.platform != PlatformType.NONE) {
drawPlatform(
poseMatrix,
entity,
@@ -144,8 +157,7 @@ class PokemonRenderer(
if (entity.passengers.isNotEmpty()) {
renderRiding(entity, entityYaw, partialTicks, poseMatrix, buffer, packedLight)
}
else {
} else {
super.render(entity, entityYaw, partialTicks, poseMatrix, buffer, packedLight)
}
@@ -182,7 +194,7 @@ class PokemonRenderer(
val controller = rollable.orientationController
poseMatrix.pushPose()
if(!DISABLE_ROLLING_DEBUG && controller.active){
if (!DISABLE_ROLLING_DEBUG && controller.active) {
val matrix = poseMatrix.last().pose()
val yaw = Mth.rotLerp(partialTicks, entity.yBodyRotO, entity.yBodyRot)
val center = Vector3f(0f, entity.bbHeight/2, 0f)
@@ -34,7 +34,7 @@
"namedAnimations": {
"faint": "q.bedrock_primary('magikarp', 'water_faint', q.curve('one'))"
},
"animations": ["q.look('head')", "q.bedrock('magikarp', 'water_idle')"],
"animations": ["q.pitch_tilt('body', 0.22)", "q.look('head')", "q.bedrock('magikarp', 'water_idle')"],
"quirks": ["q.bedrock_quirk('magikarp', 'blink')"]
},
"swim": {
@@ -42,7 +42,7 @@
"namedAnimations": {
"faint": "q.bedrock_primary('magikarp', 'water_faint', q.curve('one'))"
},
"animations": ["q.look('head')", "q.bedrock('magikarp', 'water_swim')"],
"animations": ["q.pitch_tilt('body', 0.22)", "q.look('head')", "q.bedrock('magikarp', 'water_swim')"],
"quirks": ["q.bedrock_quirk('magikarp', 'blink')"]
},
"sleep": {
@@ -2,7 +2,7 @@
"type": "minecraft:chest",
"pools": [
{
"rolls": 1,
"rolls": 3,
"bonus_rolls": 0.0,
"entries": [
{
@@ -12,8 +12,8 @@
"add": false,
"count": {
"type": "minecraft:uniform",
"max": 3.0,
"min": 9.0
"max": 1.0,
"min": 3.0
},
"function": "minecraft:set_count"
}
@@ -29,12 +29,28 @@
"count": {
"type": "minecraft:uniform",
"max": 1.0,
"min": 3.0
"min": 1.0
},
"function": "minecraft:set_count"
}
],
"name": "cobblemon:rare_candy",
"name": "cobblemon:exp_candy_m",
"weight": 10
},
{
"type": "minecraft:item",
"functions": [
{
"add": false,
"count": {
"type": "minecraft:uniform",
"max": 1.0,
"min": 1.0
},
"function": "minecraft:set_count"
}
],
"name": "minecraft:golden_apple",
"weight": 10
}
]
@@ -2,7 +2,7 @@
"type": "minecraft:chest",
"pools": [
{
"rolls": 1,
"rolls": 6,
"bonus_rolls": 0.0,
"entries": [
{
@@ -12,8 +12,8 @@
"add": false,
"count": {
"type": "minecraft:uniform",
"max": 6.0,
"min": 18.0
"max": 1.0,
"min": 3.0
},
"function": "minecraft:set_count"
}
@@ -28,13 +28,29 @@
"add": false,
"count": {
"type": "minecraft:uniform",
"max": 3.0,
"min": 5.0
"max": 1.0,
"min": 2.0
},
"function": "minecraft:set_count"
}
],
"name": "cobblemon:rare_candy",
"name": "cobblemon:exp_candy_m",
"weight": 10
},
{
"type": "minecraft:item",
"functions": [
{
"add": false,
"count": {
"type": "minecraft:uniform",
"max": 1.0,
"min": 2.0
},
"function": "minecraft:set_count"
}
],
"name": "minecraft:golden_apple",
"weight": 10
}
]
@@ -2,7 +2,7 @@ t.wander_control = q.entity.get_wander_control_memory();
t.wander_control.reset();
t.wander_control.set_allow_land((q.entity.behaviour.moving.walk.can_walk && !q.entity.behaviour.moving.walk.avoids_land) || (!q.entity.behaviour.moving.walk.can_walk && q.entity.behaviour.moving.fly.can_fly));
t.wander_control.set_allow_water(q.entity.behaviour.moving.swim.can_swim && !q.entity.behaviour.moving.swim.avoids_water);
t.wander_control.set_allow_water(q.entity.behaviour.moving.swim.can_swim_in_water && !q.entity.behaviour.moving.swim.avoids_water);
t.wander_control.set_allow_air(q.entity.behaviour.moving.fly.can_fly && !q.entity.behaviour.moving.walk.can_walk);
t.wander_control.set_walk_speed(0.35);