Compare commits

...
Author SHA1 Message Date
Plastered_Crab dd936ed8a6 Test stuff for Jet 2025-01-23 15:19:35 -08:00
4 changed files with 356 additions and 0 deletions
@@ -0,0 +1,149 @@
/*
* 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.pokemon.riding.controllers
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.api.riding.controller.RideController
import com.cobblemon.mod.common.api.riding.controller.posing.PoseOption
import com.cobblemon.mod.common.api.riding.controller.posing.PoseProvider
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readString
import com.cobblemon.mod.common.util.resolveFloat
import com.cobblemon.mod.common.util.withQueryValue
import com.cobblemon.mod.common.util.writeString
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
class JetAirController : RideController {
override val key = KEY
override val poseProvider = PoseProvider(PoseType.WALK)
.with(PoseOption(PoseType.FLY) { it.deltaMovement.horizontalDistance() > 0.1 })
override val condition: (PokemonEntity) -> Boolean = { true }
var jumpVector = listOf("0".asExpression(), "0.3".asExpression(), "0".asExpression())
private set
var gravity: Expression = "0".asExpression()
private set
var horizontalAcceleration: Expression = "0.1".asExpression()
private set
var verticalAcceleration: Expression = "0.1".asExpression()
private set
var speed: Expression = "1.0".asExpression()
private set
override fun speed(entity: PokemonEntity, driver: Player): Float {
return getRuntime(entity).resolveFloat(speed)
}
override fun rotation(entity: PokemonEntity, driver: LivingEntity): Vec2 {
return Vec2(driver.xRot * 0.5f, driver.yRot)
}
/*override fun velocity(entity: PokemonEntity, driver: Player, input: Vec3): Vec3 {
val f = driver.xxa * 0.2f
var g = driver.zza
if (g <= 0.0f) {
g *= 0.25f
}
var jumpVector = Vec3.ZERO
if (entity.jumpInputStrength > 0) {
val runtime = getRuntime(entity)
runtime.environment.query.addFunction("jump_strength") { DoubleValue(entity.jumpInputStrength.toDouble()) }
val jumpForces = this.jumpVector.map { runtime.resolveFloat(it) }
jumpVector = Vec3(jumpForces[0].toDouble(), jumpForces[1].toDouble(), jumpForces[2].toDouble())
entity.jumpInputStrength = 0
entity.addDeltaMovement(jumpVector)
}
val velocity = Vec3(f.toDouble(), 0.0, g.toDouble())
return velocity
}*/
override fun velocity(entity: PokemonEntity, driver: Player, input: Vec3): Vec3 {
val currentSpeed = getRuntime(entity).resolveFloat(speed)
val runtime = getRuntime(entity)
// Dynamically calculate acceleration based on current speed
val accelerationFactor = runtime.resolveFloat(horizontalAcceleration)
val newSpeed = Math.min(currentSpeed + accelerationFactor, 5.0f) // Cap at max speed (e.g., 5.0)
// Update the speed value in runtime
speed = "${newSpeed}".asExpression()
// Calculate forward velocity
val forwardMovement = driver.zza * newSpeed
val lateralMovement = driver.xxa * newSpeed * 0.5f
// Handle jump logic
var jumpVector = Vec3.ZERO
if (entity.jumpInputStrength > 0) {
runtime.environment.query.addFunction("jump_strength") { DoubleValue(entity.jumpInputStrength.toDouble()) }
val jumpForces = this.jumpVector.map { runtime.resolveFloat(it) }
jumpVector = Vec3(jumpForces[0].toDouble(), jumpForces[1].toDouble(), jumpForces[2].toDouble())
entity.jumpInputStrength = 0
entity.addDeltaMovement(jumpVector)
}
// Final velocity calculation
return Vec3(lateralMovement.toDouble(), 0.0, forwardMovement.toDouble())
}
override fun canJump(
entity: PokemonEntity,
driver: Player
): Boolean {
return true
}
override fun jumpForce(
entity: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return Vec3.ZERO
}
override fun gravity(entity: PokemonEntity, regularGravity: Double): Double? {
return getRuntime(entity)
.withQueryValue("gravity", DoubleValue(regularGravity))
.resolveFloat(gravity)
.toDouble()
}
override fun encode(buffer: RegistryFriendlyByteBuf) {
super.encode(buffer)
buffer.writeString(gravity.toString())
buffer.writeString(horizontalAcceleration.toString())
buffer.writeString(verticalAcceleration.toString())
buffer.writeString(speed.toString())
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
gravity = buffer.readString().asExpression()
horizontalAcceleration = buffer.readString().asExpression()
verticalAcceleration = buffer.readString().asExpression()
speed = buffer.readString().asExpression()
}
companion object {
val KEY = cobblemonResource("air/jet")
}
}
@@ -0,0 +1,141 @@
/*
* 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.pokemon.riding.controllers
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.riding.controller.RideController
import com.cobblemon.mod.common.api.riding.controller.posing.PoseOption
import com.cobblemon.mod.common.api.riding.controller.posing.PoseProvider
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.pokemon.riding.states.CompositeState
import com.cobblemon.mod.common.util.adapters.riding.RideControllerAdapter
import com.cobblemon.mod.common.util.asExpression
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.getString
import com.cobblemon.mod.common.util.readString
import com.cobblemon.mod.common.util.resolveInt
import com.cobblemon.mod.common.util.writeString
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
class RunUpToJetCompositeController : RideController {
override val key = KEY
override val poseProvider = PoseProvider(PoseType.STAND)
.with(PoseOption(PoseType.WALK) { it.entityData.get(PokemonEntity.MOVING) })
override val condition: (PokemonEntity) -> Boolean = { true }
var minimumSpeed: Expression = "0.5".asExpression()
private set
var minimumJump: Expression = "0.5".asExpression()
private set
var landController: RideController = GenericLandController()
private set
var flightController: RideController = JetAirController()
private set
override fun pose(entity: PokemonEntity): PoseType {
return getActiveController(entity).poseProvider.select(entity)
}
fun getActiveController(entity: PokemonEntity): RideController {
val state = getState(entity, ::CompositeState)
return state.activeController ?: let {
val controller = if (entity.getCurrentPoseType() in PoseType.FLYING_POSES) {
entity.setBehaviourFlag(PokemonBehaviourFlag.FLYING, true)
flightController
} else {
entity.setBehaviourFlag(PokemonBehaviourFlag.FLYING, false)
landController
}
state.activeController = controller
state.timeTransitioned = entity.level().gameTime
controller
}
}
override fun speed(
entity: PokemonEntity,
driver: Player
): Float {
val state = getState(entity, ::CompositeState)
if (state.activeController == flightController && entity.onGround() && state.timeTransitioned + 20 < entity.level().gameTime) {
getState(entity, ::CompositeState).activeController = landController
entity.setBehaviourFlag(PokemonBehaviourFlag.FLYING, false)
}
return getActiveController(entity).speed(entity, driver)
}
override fun rotation(entity: PokemonEntity, driver: LivingEntity): Vec2 {
return getActiveController(entity).rotation(entity, driver)
}
override fun velocity(
entity: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
return getActiveController(entity).velocity(entity, driver, input)
}
override fun canJump(entity: PokemonEntity, driver: Player) = true
override fun jumpForce(
entity: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
val controller = getActiveController(entity)
if (controller == landController && jumpStrength >= getRuntime(entity).resolveInt(minimumJump)) {
getState(entity, ::CompositeState).let {
it.activeController = flightController
entity.setBehaviourFlag(PokemonBehaviourFlag.FLYING, true)
it.timeTransitioned = entity.level().gameTime
}
}
return controller.jumpForce(entity, driver, jumpStrength)
}
override fun gravity(entity: PokemonEntity, regularGravity: Double): Double? {
return getActiveController(entity).gravity(entity, regularGravity)
}
override fun encode(buffer: RegistryFriendlyByteBuf) {
super.encode(buffer)
buffer.writeString(minimumSpeed.getString())
buffer.writeString(minimumJump.getString())
landController.encode(buffer)
flightController.encode(buffer)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
minimumSpeed = buffer.readString().asExpression()
minimumJump = buffer.readString().asExpression()
landController = buffer.readResourceLocation().let { key ->
val controller = RideControllerAdapter.types[key]?.getConstructor()?.newInstance() ?: error("Unknown controller key: $key")
controller.decode(buffer)
controller
}
flightController = buffer.readResourceLocation().let { key ->
val controller = RideControllerAdapter.types[key]?.getConstructor()?.newInstance() ?: error("Unknown controller key: $key")
controller.decode(buffer)
controller
}
}
companion object {
val KEY = cobblemonResource("composite/run_up_to_jet")
}
}
@@ -32,6 +32,8 @@ object RideControllerAdapter : JsonDeserializer<RideController> {
BirdAirController.KEY to BirdAirController::class.java,
HelicopterAirController.KEY to HelicopterAirController::class.java,
GliderAirController.KEY to GliderAirController::class.java,
JetAirController.KEY to JetAirController::class.java,
RunUpToJetCompositeController.KEY to RunUpToJetCompositeController::class.java,
)
override fun deserialize(element: JsonElement, type: Type, context: JsonDeserializationContext): RideController {
@@ -92,6 +92,70 @@
],
"baseExperienceYield": 300,
"experienceGroup": "slow",
"riding": {
"controller": {
"key": "cobblemon:composite/run_up_to_jet",
"minimumSpeed": "0.2",
"minimumJump": "80",
"landController": {
"key": "cobblemon:land/generic",
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.33, 0, 1)",
"jumpVector": [0, "0.3*q.jump_strength/50", "-1 * 0.5*q.jump_strength/50"]
},
"flightController": {
"key": "cobblemon:air/jet",
"gravity": "q.gravity * (0.05 + (q.passenger_count - 1) * 0.05)",
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.33, 0, 1)",
"jumpVector": [
"0.3 * q.jump_strength / 50 * q.camera.facing.x",
"0.3 * q.jump_strength / 50 * q.camera.facing.y",
"0.3 * q.jump_strength / 50 * q.camera.facing.z"
],
"accelerationRate": "Math.min(q.runtime.acceleration + 0.01, 0.05)"
}
},
"seats": [
{
"offset": {
"x": 0,
"y": 1.5,
"z": -0.5
},
"poseOffsets": [
{
"poseTypes": [
"FLY"
],
"offset": {
"x": 0,
"y": 0.2,
"z": 1
}
}
]
},
{
"offset": {
"x": 0,
"y": 1.5,
"z": -1.5
},
"poseOffsets": [
{
"poseTypes": [
"FLY"
],
"offset": {
"x": 0,
"y": 0.2,
"z": 0.2
}
}
]
}
]
},
"eggCycles": 40,
"eggGroups": [
"monster",