Compare commits

..
96 changed files with 21229 additions and 3178 deletions

No files matched your search

+2 -3
View File
@@ -1,9 +1,8 @@
import utilities.isSnapshot
import utilities.version
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import utilities.isSnapshot
import utilities.version
/*
*
@@ -20,7 +20,6 @@ import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.phys.Vec3;
import org.joml.Matrix3f;
import org.joml.Quaternionf;
@@ -35,49 +34,31 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Camera.class)
public abstract class CameraMixin {
@Shadow
private Entity entity;
@Shadow
@Final
private Quaternionf rotation;
@Shadow
@Final
private Vector3f forwards;
@Shadow
@Final
private Vector3f up;
@Shadow
@Final
private Vector3f left;
@Shadow
private float xRot;
@Shadow
private float yRot;
@Shadow private Entity entity;
@Shadow @Final private Quaternionf rotation;
@Shadow @Final private Vector3f forwards;
@Shadow @Final private Vector3f up;
@Shadow @Final private Vector3f left;
@Shadow private float xRot;
@Shadow private float yRot;
@Shadow
private float eyeHeight;
@Shadow
private float eyeHeightOld;
@Shadow private float eyeHeight;
@Shadow private float eyeHeightOld;
@Shadow
protected abstract void setPosition(Vec3 pos);
@Shadow protected abstract void setPosition(Vec3 pos);
@Unique
private float returnTimer = 0;
@Unique
private float rollAngleStart = 0;
@Unique
Minecraft minecraft = Minecraft.getInstance();
@Unique private float returnTimer = 0;
@Unique private float rollAngleStart = 0;
@Unique Minecraft minecraft = Minecraft.getInstance();
@Unique
boolean disableRollableCameraDebug = false;
@Unique boolean disableRollableCameraDebug = false;
@Inject(method = "setRotation", at = @At("HEAD"), cancellable = true)
public void cobblemon$setRotation(float f, float g, CallbackInfo ci) {
if (!(this.entity instanceof OrientationControllable controllable) || disableRollableCameraDebug) return;
var controller = controllable.getOrientationController();
if (!controller.isActive() && controller.getOrientation() != null) {
if (this.returnTimer < 1) {
if(this.returnTimer < 1) {
//Rotation is taken from entity since we no longer handle mouse ourselves
//Stops a period of time when you can't input anything.
controller.getOrientation().set(
@@ -85,17 +66,16 @@ public abstract class CameraMixin {
.rotateY((float) Math.toRadians(180 - this.entity.getYRot()))
.rotateX((float) Math.toRadians(-this.entity.getXRot()))
);
if (rollAngleStart == 0) {
if(rollAngleStart == 0){
this.returnTimer = 1;
controller.reset();
return;
}
controller.getOrientation().rotateZ((float) Math.toRadians(-rollAngleStart * (1 - returnTimer)));
controller.getOrientation().rotateZ((float) Math.toRadians(-rollAngleStart*(1-returnTimer)));
cobblemon$applyRotation();
this.returnTimer += .05F;
ci.cancel();
}
else {
} else {
this.returnTimer = 1;
controller.reset();
}
@@ -109,16 +89,26 @@ public abstract class CameraMixin {
ci.cancel();
}
@Inject(method = "setup", at = @At("HEAD"))
private void cobblemon$tickAnimationPreRenders(BlockGetter level, Entity entity, boolean detached, boolean thirdPersonReverse, float partialTick, CallbackInfo ci) {
MountedPokemonAnimationRenderController.INSTANCE.reset();
}
@WrapOperation(method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;setPosition(DDD)V"))
public void cobblemon$positionCamera(Camera instance, double x, double y, double z, Operation<Void> original, @Local(ordinal = 1, argsOnly = true) boolean thirdPersonReverse) {
if (cobblemon$isRidingPokemon(entity)) {
Vec3 position = MountedCameraRenderer.INSTANCE.getCameraPosition(instance, entity, entity.getVehicle(), thirdPersonReverse, eyeHeightOld, eyeHeight);
if (position != null) {
Entity entity = instance.getEntity();
Entity vehicle = entity.getVehicle();
MountedPokemonAnimationRenderController.INSTANCE.reset();
if(vehicle instanceof Rideable){
Vec3 position = MountedCameraRenderer.INSTANCE.getCameraPosition(
instance,
entity,
vehicle,
x,
y,
z,
thirdPersonReverse,
eyeHeightOld,
eyeHeight
);
if(position != null){
setPosition(position);
return;
}
@@ -128,18 +118,12 @@ public abstract class CameraMixin {
}
@Unique
private boolean cobblemon$isRidingPokemon(Entity entity) {
return entity.getVehicle() instanceof PokemonEntity;
}
@Unique
private void cobblemon$applyRotation() {
if (!(this.entity instanceof OrientationControllable controllable) || controllable.getOrientationController().getOrientation() == null)
return;
private void cobblemon$applyRotation(){
if (!(this.entity instanceof OrientationControllable controllable) || controllable.getOrientationController().getOrientation() == null) return;
var controller = controllable.getOrientationController();
var newRotation = controller.getOrientation().normal(new Matrix3f()).getNormalizedRotation(new Quaternionf());
if (this.minecraft.options.getCameraType().isMirrored()) {
newRotation.rotateY((float) Math.toRadians(180));
newRotation.rotateY((float)Math.toRadians(180));
}
this.rotation.set(newRotation);
this.xRot = controller.getPitch();
@@ -154,7 +138,7 @@ public abstract class CameraMixin {
Entity entity = instance.getEntity();
Entity vehicle = entity.getVehicle();
if (!(vehicle instanceof PokemonEntity) || Cobblemon.config.getViewBobTranslation()) {
if (!(vehicle instanceof PokemonEntity) || Cobblemon.config.getThirdPersonViewBobbing()) {
original.call(instance, zoom, dy, dx);
}
}
@@ -525,14 +525,13 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
}
})*/
// todo we might need to wait on these for later?
/*@JvmField
@JvmField
val CHOICE_DUMPLING = noSettingsItem("choice_dumpling") // todo make a ChoiceDumpingItem class for breeding purposes
@JvmField
val SWAP_SNACK = noSettingsItem("swap_snack") // todo make a SwapSnackItem class for breeding purposes
@JvmField
val TWICE_SPICED_BEETROOT = noSettingsItem("twice_spiced_beetroot") // todo make a TwiceSpiceBeetrootItem class for breeding purposes
*/
@JvmField
val POTATO_MOCHI = create("potato_mochi", object : Item(Properties().stacksTo(16)
.food(FoodProperties.Builder()
@@ -599,8 +598,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
}
})
// todo etc?
//@JvmField
@@ -831,7 +831,6 @@ object MoLangFunctions {
map.put("in_battle") { DoubleValue(pokemonEntity.isBattling) }
map.put("is_moving") { DoubleValue((pokemonEntity.moveControl as? PokemonMoveControl)?.hasWanted() == true) }
map.put("is_flying") { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
map.put("is_flying") { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
map.put("get_alt_pose") { StringValue(pokemonEntity.getAltPose()) }
map.put("is_gliding") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("gliding"))) }
map.put("is_sprinting") { DoubleValue(pokemonEntity.isUsingAltPose(cobblemonResource("sprinting"))) }
@@ -385,7 +385,7 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
driver: Player
): ResourceLocation {
when {
state.inAir.get() -> cobblemonResource("in_air")
state.inAir.get() -> return cobblemonResource("in_air")
state.sprinting.get() -> return cobblemonResource("sprinting")
}
return cobblemonResource("no_pose")
@@ -344,8 +344,6 @@ object CobblemonClient {
private fun registerItemColors() {
implementation.registerItemColors(AprijuiceItemColorProvider, *CobblemonItems.aprijuices.toTypedArray())
implementation.registerItemColors(PokeBaitItemColorProvider, CobblemonItems.POKE_BAIT)
implementation.registerItemColors(PokeBaitItemColorProvider, CobblemonItems.LURE_CAKE)
implementation.registerItemColors(PokeBaitItemColorProvider, CobblemonItems.POKE_CAKE)
}
fun reloadCodedAssets(resourceManager: ResourceManager) {
@@ -1,308 +0,0 @@
package com.cobblemon.mod.common.client.render.camera
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.Seat
import com.cobblemon.mod.common.client.MountedPokemonAnimationRenderController
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository.getPoser
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.mixin.accessor.CameraAccessor
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.toVec3d
import net.minecraft.client.Camera
import net.minecraft.client.Minecraft
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.Mth
import net.minecraft.world.entity.Entity
import net.minecraft.world.level.ClipContext
import net.minecraft.world.phys.HitResult
import net.minecraft.world.phys.Vec3
import org.joml.Matrix3f
import org.joml.Quaternionf
import org.joml.Vector3f
object CameraTransformationController {
private val transformers = mutableMapOf<Int, MutableList<CameraTransformer>>(
1 to mutableListOf(RidingCameraTransformer()),
)
fun register(priority: Int, transformer: CameraTransformer) {
if (transformers[priority] == null) {
transformers[priority] = mutableListOf()
}
transformers[priority]!!.add(transformer)
}
fun tick(current: CameraTransformation, delta: Float, context: CameraContext): CameraTransformation {
val transformers = transformers.toSortedMap().reversed().values.flatten()
transformers.forEach {
if (it.condition(context)) {
return it.tick(current, delta, context)
}
}
return current
}
}
interface CameraTransformer {
val key: ResourceLocation
val condition: (CameraContext) -> Boolean
fun tick(current: CameraTransformation, delta: Float, context: CameraContext): CameraTransformation
fun onStart() {}
fun onStop() {}
}
data class CameraTransformation(val position: Vec3, val rotation: Quaternionf, val fov: Int)
data class CameraContext(
val camera: Camera,
val entity: Entity,
val eyeHeight: Float,
val eyeHeightO: Float,
val perspective: CameraPerspective
)
enum class CameraPerspective {
FIRST_PERSON,
THIRD_PERSON_BACK,
THIRD_PERSON_FRONT
}
class RidingCameraTransformer : CameraTransformer {
override val key = cobblemonResource("camera/riding")
override val condition: (CameraContext) -> Boolean = { it.entity.vehicle is PokemonEntity }
val positionTransformer = RidingCameraPositionTransformer()
val viewBobPositionTransformer = RidingCameraViewBobPositionTransformer()
val rotationTransformer = OrientationControllerRotationTransformer()
val viewBobRotationTransformer = RidingCameraViewBobRotationTransformer()
override fun tick(current: CameraTransformation, delta: Float, context: CameraContext): CameraTransformation {
val vehicle = context.entity.vehicle as? PokemonEntity ?: return current
MountedPokemonAnimationRenderController.setup(vehicle, delta)
val position = getPosition(delta, context, vehicle)
val rotation = getRotation(current, context)
val fov = Minecraft.getInstance().options.fov().get()
return CameraTransformation(position, rotation, fov)
}
private fun getPosition(delta: Float, context: CameraContext, vehicle: PokemonEntity): Vec3 {
if (context.perspective == CameraPerspective.FIRST_PERSON || Cobblemon.config.viewBobTranslation) {
return viewBobPositionTransformer.getPosition(delta, context, vehicle)
} else {
return positionTransformer.getPosition(delta, context, vehicle)
}
}
private fun getRotation(current: CameraTransformation, context: CameraContext): Quaternionf {
if (Cobblemon.config.viewBobRotation) {
return viewBobRotationTransformer.getRotation()
}
else {
return rotationTransformer.getRotation(current.rotation, context)
}
}
}
class RidingCameraPositionTransformer {
fun getPosition(delta: Float, context: CameraContext, vehicle: PokemonEntity): Vec3 {
val position = Vec3(
Mth.lerp(delta.toDouble(), vehicle.xOld, vehicle.x),
Mth.lerp(delta.toDouble(), vehicle.yOld, vehicle.y),
Mth.lerp(delta.toDouble(), vehicle.zOld, vehicle.z)
)
val orientation = getOrientation(context.entity)
var offset = Vec3.ZERO
offset = applyThirdPersonToOffset(offset, context, vehicle)
offset = applyRollingToOffset(offset, orientation)
offset = applyZoomToOffset(offset, position, context)
val pivotOffset = applyPivotToOffset(vehicle, context.entity, orientation)
return position.add(pivotOffset).add(offset)
}
fun applyPivotToOffset(vehicle: PokemonEntity, passenger: Entity, orientation: Matrix3f): Vec3 {
val seatIndex: Int = vehicle.passengers.indexOf(passenger)
if (seatIndex < 0) return Vec3.ZERO
val seat: Seat = vehicle.seats[seatIndex]
val model = getPoser(vehicle.pokemon.species.resourceIdentifier, FloatingState())
val center = Vec3(0.0, passenger.bbHeight / 2.0, 0.0)
val pivotOffsets = model.thirdPersonPivotOffset
if (!pivotOffsets.containsKey(seat.locator)) return Vec3.ZERO
val pivotOffset = pivotOffsets[seat.locator]!!
val rotatedOffset = orientation.transform(pivotOffset.subtract(center).toVector3f())
return rotatedOffset.toVec3d().add(center)
}
fun applyThirdPersonToOffset(offset: Vec3, context: CameraContext, vehicle: PokemonEntity): Vec3 {
if (context.perspective == CameraPerspective.FIRST_PERSON) return offset
val model = getPoser(vehicle.pokemon.species.resourceIdentifier, FloatingState())
val cameraOffsets = model.thirdPersonCameraOffset
val seatIndex: Int = vehicle.passengers.indexOf(context.entity)
if (seatIndex < 0) return offset
val seat: Seat = vehicle.seats[seatIndex]
val thirdPartyOffset = getThirdPartyOffset(seat, cameraOffsets, context)
return offset.add(thirdPartyOffset)
}
private fun getThirdPartyOffset(seat: Seat, offsets: MutableMap<String, Vec3>, context: CameraContext): Vec3 {
val locatorName = when (context.perspective) {
CameraPerspective.FIRST_PERSON -> seat.locator
CameraPerspective.THIRD_PERSON_FRONT -> seat.locator
CameraPerspective.THIRD_PERSON_BACK -> "${seat.locator}_reverse"
}
if (!offsets.containsKey(locatorName)) return Vec3.ZERO
val offset = offsets[locatorName]!!
return when (context.perspective) {
CameraPerspective.FIRST_PERSON -> Vec3.ZERO
CameraPerspective.THIRD_PERSON_FRONT -> offset
CameraPerspective.THIRD_PERSON_BACK -> offset.multiply(1.0, 1.0, -1.0)
}
}
fun applyRollingToOffset(offset: Vec3, orientation: Matrix3f): Vec3 {
return orientation.transform(offset.toVector3f()).toVec3d()
}
fun applyZoomToOffset(offset: Vec3, pivot: Vec3, context: CameraContext): Vec3 {
val offsetDistance = offset.length()
val offsetDirection = offset.multiply(1 / offsetDistance, 1 / offsetDistance, 1 / offsetDistance)
val maxZoom = getMaxZoom(offsetDistance.toFloat(), offsetDirection.toVector3f(), pivot.toVector3f(), context.camera).toDouble()
return offset.multiply(maxZoom, maxZoom, maxZoom)
}
private fun getMaxZoom(maxZoom: Float, directionVector: Vector3f, positionVector: Vector3f, instance: Camera): Float {
var maxZoom = maxZoom
val pos = Vec3(positionVector)
for (i in 0 .. 7) {
val g = ((i and 1) * 2 - 1).toFloat()
val h = ((i shr 1 and 1) * 2 - 1).toFloat()
val j = ((i shr 2 and 1) * 2 - 1).toFloat()
val vec3 = pos.add((g * 0.1f).toDouble(), (h * 0.1f).toDouble(), (j * 0.1f).toDouble())
val vec32 = vec3.add(Vec3(directionVector).scale(maxZoom.toDouble()))
val level = (instance as CameraAccessor).level
val hitResult: HitResult =
level.clip(ClipContext(vec3, vec32, ClipContext.Block.VISUAL, ClipContext.Fluid.NONE, instance.entity))
if (hitResult.type != HitResult.Type.MISS) {
val k = hitResult.getLocation().distanceToSqr(pos).toFloat()
if (k < Mth.square(maxZoom)) {
maxZoom = Mth.sqrt(k)
}
}
}
return maxZoom
}
fun getOrientation(passenger: Entity): Matrix3f {
val xRot = (-1 * Math.toRadians(passenger.xRot.toDouble())).toFloat()
val controller = (passenger as? OrientationControllable)?.getOrientationController()
if (controller == null || !controller.isActive() || controller.orientation == null) {
return Matrix3f()
.rotateY(Math.toRadians((180f - passenger.yRot).toDouble()).toFloat())
.rotateX(xRot)
}
return controller.orientation!!
}
}
class RidingCameraViewBobPositionTransformer {
fun getPosition(delta: Float, context: CameraContext, vehicle: PokemonEntity): Vec3 {
val position = Vec3(
Mth.lerp(delta.toDouble(), vehicle.xOld, vehicle.x),
Mth.lerp(delta.toDouble(), vehicle.yOld, vehicle.y),
Mth.lerp(delta.toDouble(), vehicle.zOld, vehicle.z)
)
var offset = Vec3.ZERO
// Add eye level
offset = applyAABBToOffset(context, delta, offset, context.entity)
// Add first person offset from poser if found
offset = applyFirstPersonToOffset(context, offset, vehicle, context.entity)
// Transform the offset based on the entity's orientation
offset = applyRollingToOffset(offset, delta, context.entity)
// Add the offset from the locator
offset = applyLocatorToOffset(offset, vehicle, context.entity)
return position.add(offset)
}
private fun applyLocatorToOffset(offset: Vec3, vehicle: PokemonEntity, passenger: Entity): Vec3 {
val seatIndex: Int = vehicle.passengers.indexOf(passenger)
if (seatIndex < 0) return offset
val seat: Seat = vehicle.seats[seatIndex]
val delegate = vehicle.delegate as PokemonClientDelegate
val locator = delegate.locatorStates[seat.locator] ?: return offset
return offset.add(Vec3(locator.matrix.getTranslation(Vector3f())))
}
private fun applyAABBToOffset(context: CameraContext, delta: Float, offset: Vec3, passenger: Entity): Vec3 {
val currEyeHeight: Double =
Mth.lerp(delta.toDouble(), context.eyeHeight.toDouble(), context.eyeHeightO.toDouble())
return offset.add(0.0, currEyeHeight - (passenger.bbHeight / 2), 0.0)
}
private fun applyRollingToOffset(offset: Vec3, delta: Float, passenger: Entity): Vec3 {
val rollable = passenger as? OrientationControllable ?: return offset
val controller = rollable.getOrientationController()
if (!controller.isActive()) return offset
return controller.getRenderOrientation(delta).transform(offset.toVector3f()).toVec3d()
}
private fun applyFirstPersonToOffset(
context: CameraContext,
offset: Vec3,
vehicle: PokemonEntity,
passenger: Entity
): Vec3 {
if (context.perspective != CameraPerspective.FIRST_PERSON) return offset
val model = getPoser(vehicle.pokemon.species.resourceIdentifier, FloatingState())
val seatIndex: Int = vehicle.passengers.indexOf(passenger)
val seat: Seat = vehicle.seats[seatIndex]
val cameraOffsets = model.firstPersonCameraOffset
return when (cameraOffsets.containsKey(seat.locator)) {
true -> cameraOffsets[seat.locator]!!
false -> Vec3.ZERO
}
}
}
class RidingCameraViewBobRotationTransformer {
fun getRotation(): Quaternionf {
TODO()
}
}
class OrientationControllerRotationTransformer {
fun getRotation(current: Quaternionf, context: CameraContext): Quaternionf {
val entity = context.entity
val controllable = entity as? OrientationControllable ?: return current
val controller = controllable.getOrientationController()
val orientation = controller.orientation ?: return current
return orientation.normal(Matrix3f()).getNormalizedRotation(Quaternionf())
}
}
@@ -33,6 +33,9 @@ object MountedCameraRenderer
instance: Camera,
entity: Entity,
vehicle: Entity,
x: Double,
y: Double,
z: Double,
thirdPersonReverse: Boolean,
eyeHeightOld: Double,
eyeHeight: Double
@@ -56,7 +59,7 @@ object MountedCameraRenderer
// First person and view bobbing are handled the same way.
if (!instance.isDetached || Cobblemon.config.viewBobTranslation) {
if (!instance.isDetached || Cobblemon.config.thirdPersonViewBobbing) {
val delegate = vehicle.delegate as PokemonClientDelegate
val locator = delegate.locatorStates[seat.locator]
@@ -173,4 +176,4 @@ object MountedCameraRenderer
return maxZoom
}
}
}
@@ -1,125 +0,0 @@
/*
* 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.pokemon.gen8
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BiWingedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class CorviknightModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BiWingedFrame {
override val rootPart = root.registerChildWithAllChildren("corviknight")
override val leftWing = getPart("wing_left")
override val rightWing = getPart("wing_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override val head = getPart("head")
val openWingLeft = getPart("wing_open_left")
val openWingRight = getPart("wing_open_right")
val closedWingLeft = getPart("wing_closed_left")
val closedWingRight = getPart("wing_closed_right")
override var portraitScale = 1.0F
override var portraitTranslation = Vec3(-0.45, 3.0, 0.0)
override var profileScale = 0.36F
override var profileTranslation = Vec3(0.0, 1.2, 0.0)
lateinit var stand: Pose
lateinit var walk: Pose
lateinit var hover: Pose
lateinit var fly: Pose
lateinit var sleep: Pose
override val cryAnimation = CryProvider { bedrockStateful("corviknight", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("corviknight", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("corviknight", "sleep"))
)
stand = registerPose(
poseName = "standing",
poseTypes = PoseType.UI_POSES + PoseType.STATIONARY_POSES - PoseType.HOVER,
transformTicks = 10,
transformedParts = arrayOf(
openWingLeft.createTransformation().withVisibility(visibility = false),
openWingRight.createTransformation().withVisibility(visibility = false),
closedWingLeft.createTransformation().withVisibility(visibility = true),
closedWingRight.createTransformation().withVisibility(visibility = true)
),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("corviknight", "ground_idle")
)
)
hover = registerPose(
poseName = "hover",
poseType = PoseType.HOVER,
transformTicks = 10,
transformedParts = arrayOf(
openWingLeft.createTransformation().withVisibility(visibility = true),
openWingRight.createTransformation().withVisibility(visibility = true),
closedWingLeft.createTransformation().withVisibility(visibility = false),
closedWingRight.createTransformation().withVisibility(visibility = false)
),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("corviknight", "air_idle")
)
)
fly = registerPose(
poseName = "fly",
poseType = PoseType.FLY,
transformTicks = 10,
transformedParts = arrayOf(
openWingLeft.createTransformation().withVisibility(visibility = true),
openWingRight.createTransformation().withVisibility(visibility = true),
closedWingLeft.createTransformation().withVisibility(visibility = false),
closedWingRight.createTransformation().withVisibility(visibility = false)
),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("corviknight", "air_fly")
)
)
walk = registerPose(
poseName = "walking",
poseTypes = PoseType.MOVING_POSES - PoseType.FLY,
transformTicks = 10,
transformedParts = arrayOf(
openWingLeft.createTransformation().withVisibility(visibility = false),
openWingRight.createTransformation().withVisibility(visibility = false),
closedWingLeft.createTransformation().withVisibility(visibility = true),
closedWingRight.createTransformation().withVisibility(visibility = true)
),
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("corviknight", "ground_walk")
)
)
}
}
@@ -523,7 +523,6 @@ object VaryingModelRepository {
inbuilt("sirfetchd", ::SirfetchdModel)
inbuilt("rookidee", ::RookideeModel)
inbuilt("corvisquire", ::CorvisquireModel)
inbuilt("corviknight", ::CorviknightModel)
inbuilt("duskull", ::DuskullModel)
inbuilt("dusclops", ::DusclopsModel)
inbuilt("dusknoir", ::DusknoirModel)
@@ -262,11 +262,8 @@ class CobblemonConfig {
@CobblemonConfigField(Category.Interface, lang = "party_portrait_animations")
var partyPortraitAnimations = PortraitStyle.NEVER_ANIMATE
@CobblemonConfigField(Category.Riding, lang = "view_bob_translation")
var viewBobTranslation = false
@CobblemonConfigField(Category.Riding, lang = "view_bob_rotation")
var viewBobRotation = false
@CobblemonConfigField(Category.Riding, lang = "third_person_view_bobbing")
var thirdPersonViewBobbing = false
@CobblemonConfigField(Category.Riding, lang = "invert_roll")
var invertRoll = false
@@ -10,8 +10,6 @@ package com.cobblemon.mod.common.entity.npc
import com.bedrockk.molang.runtime.MoLangRuntime
import com.bedrockk.molang.runtime.struct.VariableStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.*
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
import com.cobblemon.mod.common.api.entity.PokemonSender
@@ -322,22 +320,6 @@ class NPCEntity(world: Level) : AgeableMob(CobblemonEntities.NPC, world), Npc, P
DebugPackets.sendPathFindingPacket(level(), this, this.navigation.path, this.navigation.path?.distToTarget ?: 0F)
}
override fun broadcastToPlayer(player: ServerPlayer): Boolean {
if(handleHideNPC(player, this)) {
return false
}
return super.broadcastToPlayer(player)
}
private fun handleHideNPC(player: Player, npc: NPCEntity): Boolean {
val value = Cobblemon.molangData.load(player.uuid).map[npc.stringUUID]
if (value is VariableStruct) {
val hide = value.map["hide"] as? DoubleValue
return hide?.asDouble() == 1.0
}
return false
}
override fun saveWithoutId(nbt: CompoundTag): CompoundTag {
super.saveWithoutId(nbt)
nbt.put(DataKeys.NPC_DATA, MoLangFunctions.writeMoValueToNBT(data))
@@ -20,13 +20,13 @@ import net.minecraft.network.RegistryFriendlyByteBuf
* @author Hiroku
* @since November 28th, 2021
*/
abstract class PokemonUpdatePacket<T>(val pokemon: () -> Pokemon?) : NetworkPacket<T> where T : NetworkPacket<T> {
abstract class PokemonUpdatePacket<T>(val pokemon: () -> Pokemon) : NetworkPacket<T> where T : NetworkPacket<T> {
final override fun encode(buffer: RegistryFriendlyByteBuf) {
val pokemon = pokemon()
// This won't ever happen in instances where packets get sent out, but they protect us from NPEs on fields that require synchronization on load/save
buffer.writeUUID(pokemon?.storeCoordinates?.get()?.store?.uuid ?: UUID.randomUUID())
buffer.writeUUID(pokemon?.uuid ?: UUID.randomUUID())
buffer.writeUUID(pokemon.storeCoordinates.get()?.store?.uuid ?: UUID.randomUUID())
buffer.writeUUID(pokemon.uuid)
encodeDetails(buffer)
}
@@ -41,12 +41,12 @@ abstract class PokemonUpdatePacket<T>(val pokemon: () -> Pokemon?) : NetworkPack
* Reads the current Pokémon from the given [buffer].
*
* @param buffer The [ByteBuf] being decoded.
* @return The [Pokemon] found. Can be null in flashback replays
* @return The [Pokemon] found.
*/
fun decodePokemon(buffer: RegistryFriendlyByteBuf) : () -> Pokemon? {
fun decodePokemon(buffer: RegistryFriendlyByteBuf) : () -> Pokemon {
val storeId = buffer.readUUID()
val pokemonId = buffer.readUUID()
return { CobblemonClient.storage.locatePokemon(storeId, pokemonId) }
return { CobblemonClient.storage.locatePokemon(storeId, pokemonId)!! }
}
}
}
@@ -22,7 +22,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
* @author Hiroku
* @since November 1st, 2022
*/
class AbilityUpdatePacket(pokemon: () -> Pokemon?, ability: AbilityTemplate) : SingleUpdatePacket<AbilityTemplate, AbilityUpdatePacket>(pokemon, ability) {
class AbilityUpdatePacket(pokemon: () -> Pokemon, ability: AbilityTemplate) : SingleUpdatePacket<AbilityTemplate, AbilityUpdatePacket>(pokemon, ability) {
override val id = ID
@@ -11,12 +11,10 @@ package com.cobblemon.mod.common.net.messages.client.pokemon.update
import com.cobblemon.mod.common.api.mark.Mark
import com.cobblemon.mod.common.api.mark.Marks
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.writeIdentifier
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
class ActiveMarkUpdatePacket(pokemon: () -> Pokemon?, value: Mark?): SingleUpdatePacket<Mark?, ActiveMarkUpdatePacket>(pokemon, value) {
class ActiveMarkUpdatePacket(pokemon: () -> Pokemon, value: Mark?): SingleUpdatePacket<Mark?, ActiveMarkUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeNullable(this.value) { _, v -> buffer.writeIdentifier(v.identifier) }
@@ -15,7 +15,7 @@ import com.cobblemon.mod.common.util.writeString
import io.netty.buffer.ByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
class AspectsUpdatePacket(pokemon: () -> Pokemon?, value: Set<String>): SingleUpdatePacket<Set<String>, AspectsUpdatePacket>(pokemon, value) {
class AspectsUpdatePacket(pokemon: () -> Pokemon, value: Set<String>): SingleUpdatePacket<Set<String>, AspectsUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeCollection(this.value) { pb, value -> pb.writeString(value) }
@@ -13,7 +13,7 @@ import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.RegistryFriendlyByteBuf
class BenchedMovesUpdatePacket(pokemon: () -> Pokemon?, value: BenchedMoves): SingleUpdatePacket<BenchedMoves, BenchedMovesUpdatePacket>(pokemon, value) {
class BenchedMovesUpdatePacket(pokemon: () -> Pokemon, value: BenchedMoves): SingleUpdatePacket<BenchedMoves, BenchedMovesUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
this.value.saveToBuffer(buffer)
@@ -18,7 +18,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
* @author Deltric
* @since January 13th, 2022
*/
abstract class BooleanUpdatePacket<T : NetworkPacket<T>>(pokemon: () -> Pokemon?, value: Boolean) : SingleUpdatePacket<Boolean, T>(pokemon, value) {
abstract class BooleanUpdatePacket<T : NetworkPacket<T>>(pokemon: () -> Pokemon, value: Boolean) : SingleUpdatePacket<Boolean, T>(pokemon, value) {
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeBoolean(this.value)
}
@@ -16,7 +16,7 @@ import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.writeIdentifier
import net.minecraft.network.RegistryFriendlyByteBuf
class CaughtBallUpdatePacket(pokemon: () -> Pokemon?, value: PokeBall): SingleUpdatePacket<PokeBall, CaughtBallUpdatePacket>(pokemon, value) {
class CaughtBallUpdatePacket(pokemon: () -> Pokemon, value: PokeBall): SingleUpdatePacket<PokeBall, CaughtBallUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeIdentifier(this.value.name)
@@ -15,7 +15,7 @@ import com.cobblemon.mod.common.util.writeItemStack
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.world.item.ItemStack
class CosmeticItemUpdatePacket(pokemon: () -> Pokemon?, value: ItemStack) : SingleUpdatePacket<ItemStack, CosmeticItemUpdatePacket>(pokemon, value) {
class CosmeticItemUpdatePacket(pokemon: () -> Pokemon, value: ItemStack) : SingleUpdatePacket<ItemStack, CosmeticItemUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
@@ -20,7 +20,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
* @author Segfault Guy
* @since July 27, 2023
*/
class DmaxLevelUpdatePacket(pokemon: () -> Pokemon?, value: Int) : IntUpdatePacket<DmaxLevelUpdatePacket>(pokemon, value) {
class DmaxLevelUpdatePacket(pokemon: () -> Pokemon, value: Int) : IntUpdatePacket<DmaxLevelUpdatePacket>(pokemon, value) {
override val id = ID
override fun getSize() = IntSize.U_BYTE
@@ -14,7 +14,7 @@ import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readSizedInt
import net.minecraft.network.RegistryFriendlyByteBuf
class ExperienceUpdatePacket(pokemon: () -> Pokemon?, value: Int) : IntUpdatePacket<ExperienceUpdatePacket>(pokemon, value) {
class ExperienceUpdatePacket(pokemon: () -> Pokemon, value: Int) : IntUpdatePacket<ExperienceUpdatePacket>(pokemon, value) {
override val id = ID
override fun getSize() = IntSize.INT
override fun set(pokemon: Pokemon, value: Int) = pokemon.setExperienceAndUpdateLevel(value)
@@ -14,7 +14,7 @@ import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
class FormUpdatePacket(pokemon: () -> Pokemon?, form: FormData) : SingleUpdatePacket<FormData, FormUpdatePacket>(pokemon, form) {
class FormUpdatePacket(pokemon: () -> Pokemon, form: FormData) : SingleUpdatePacket<FormData, FormUpdatePacket>(pokemon, form) {
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
this.value.encode(buffer)
}
@@ -30,7 +30,7 @@ class FormUpdatePacket(pokemon: () -> Pokemon?, form: FormData) : SingleUpdatePa
fun decode(buffer: RegistryFriendlyByteBuf): FormUpdatePacket {
val pokemon = decodePokemon(buffer)
val form = FormData()
form.species = pokemon()!!.species
form.species = pokemon().species
form.decode(buffer)
return FormUpdatePacket(pokemon, form)
}
@@ -14,7 +14,7 @@ import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readSizedInt
import net.minecraft.network.RegistryFriendlyByteBuf
class FriendshipUpdatePacket(pokemon: () -> Pokemon?, value: Int) : IntUpdatePacket<FriendshipUpdatePacket>(pokemon, value) {
class FriendshipUpdatePacket(pokemon: () -> Pokemon, value: Int) : IntUpdatePacket<FriendshipUpdatePacket>(pokemon, value) {
override val id = ID
override fun getSize() = IntSize.U_BYTE
override fun set(pokemon: Pokemon, value: Int) {
@@ -15,7 +15,7 @@ import com.cobblemon.mod.common.util.readEnumConstant
import com.cobblemon.mod.common.util.writeEnumConstant
import net.minecraft.network.RegistryFriendlyByteBuf
class GenderUpdatePacket(pokemon: () -> Pokemon?, value: Gender): SingleUpdatePacket<Gender, GenderUpdatePacket>(pokemon, value) {
class GenderUpdatePacket(pokemon: () -> Pokemon, value: Gender): SingleUpdatePacket<Gender, GenderUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeEnumConstant(this.value)
@@ -18,7 +18,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
* @author Segfault Guy
* @since July 27, 2023
*/
class GmaxFactorUpdatePacket(pokemon: () -> Pokemon?, value: Boolean) : BooleanUpdatePacket<GmaxFactorUpdatePacket>(pokemon, value) {
class GmaxFactorUpdatePacket(pokemon: () -> Pokemon, value: Boolean) : BooleanUpdatePacket<GmaxFactorUpdatePacket>(pokemon, value) {
override val id = ID
override fun set(pokemon: Pokemon, value: Boolean) {
@@ -20,7 +20,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
* @author Hiroku
* @since February 12, 2022
*/
class HealthUpdatePacket(pokemon: () -> Pokemon?, value: Int) : IntUpdatePacket<HealthUpdatePacket>(pokemon, value) {
class HealthUpdatePacket(pokemon: () -> Pokemon, value: Int) : IntUpdatePacket<HealthUpdatePacket>(pokemon, value) {
override val id = ID
override fun getSize() = IntSize.U_SHORT
override fun set(pokemon: Pokemon, value: Int) {
@@ -15,7 +15,7 @@ import com.cobblemon.mod.common.util.writeItemStack
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.world.item.ItemStack
class HeldItemUpdatePacket(pokemon: () -> Pokemon?, value: ItemStack): SingleUpdatePacket<ItemStack, HeldItemUpdatePacket>(pokemon, value) {
class HeldItemUpdatePacket(pokemon: () -> Pokemon, value: ItemStack): SingleUpdatePacket<ItemStack, HeldItemUpdatePacket>(pokemon, value) {
override val id = ID
@@ -22,7 +22,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
* @author Hiroku
* @since November 28th, 2021
*/
abstract class IntUpdatePacket<T : NetworkPacket<T>>(pokemon: () -> Pokemon?, value: Int) : SingleUpdatePacket<Int, T>(pokemon, value) {
abstract class IntUpdatePacket<T : NetworkPacket<T>>(pokemon: () -> Pokemon, value: Int) : SingleUpdatePacket<Int, T>(pokemon, value) {
abstract fun getSize(): IntSize
@@ -11,12 +11,10 @@ package com.cobblemon.mod.common.net.messages.client.pokemon.update
import com.cobblemon.mod.common.api.mark.Mark
import com.cobblemon.mod.common.api.mark.Marks
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.writeIdentifier
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
class MarkAddUpdatePacket(pokemon: () -> Pokemon?, value: Mark?): SingleUpdatePacket<Mark?, MarkAddUpdatePacket>(pokemon, value) {
class MarkAddUpdatePacket(pokemon: () -> Pokemon, value: Mark?): SingleUpdatePacket<Mark?, MarkAddUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeNullable(this.value) { _, v -> buffer.writeIdentifier(v.identifier) }
@@ -11,12 +11,10 @@ package com.cobblemon.mod.common.net.messages.client.pokemon.update
import com.cobblemon.mod.common.api.mark.Mark
import com.cobblemon.mod.common.api.mark.Marks
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.writeIdentifier
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
class MarkPotentialAddUpdatePacket(pokemon: () -> Pokemon?, value: Mark?): SingleUpdatePacket<Mark?, MarkPotentialAddUpdatePacket>(pokemon, value) {
class MarkPotentialAddUpdatePacket(pokemon: () -> Pokemon, value: Mark?): SingleUpdatePacket<Mark?, MarkPotentialAddUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeNullable(this.value) { _, v -> buffer.writeIdentifier(v.identifier) }
@@ -11,12 +11,10 @@ package com.cobblemon.mod.common.net.messages.client.pokemon.update
import com.cobblemon.mod.common.api.mark.Mark
import com.cobblemon.mod.common.api.mark.Marks
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.writeIdentifier
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
class MarkRemoveUpdatePacket(pokemon: () -> Pokemon?, value: Mark?): SingleUpdatePacket<Mark?, MarkRemoveUpdatePacket>(pokemon, value) {
class MarkRemoveUpdatePacket(pokemon: () -> Pokemon, value: Mark?): SingleUpdatePacket<Mark?, MarkRemoveUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeNullable(this.value) { _, v -> buffer.writeIdentifier(v.identifier) }
@@ -13,7 +13,7 @@ import com.cobblemon.mod.common.util.cobblemonResource
import io.netty.buffer.ByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
class MarkingsUpdatePacket(pokemon: () -> Pokemon?, value: List<Int>): SingleUpdatePacket<List<Int>, MarkingsUpdatePacket>(pokemon, value) {
class MarkingsUpdatePacket(pokemon: () -> Pokemon, value: List<Int>): SingleUpdatePacket<List<Int>, MarkingsUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeCollection(this.value) { pb, value -> pb.writeInt(value) }
@@ -11,13 +11,11 @@ package com.cobblemon.mod.common.net.messages.client.pokemon.update
import com.cobblemon.mod.common.api.mark.Mark
import com.cobblemon.mod.common.api.mark.Marks
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.writeIdentifier
import com.cobblemon.mod.common.util.*
import io.netty.buffer.ByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
class MarksPotentialUpdatePacket(pokemon: () -> Pokemon?, value: MutableSet<Mark>): SingleUpdatePacket<MutableSet<Mark>, MarksPotentialUpdatePacket>(pokemon, value) {
class MarksPotentialUpdatePacket(pokemon: () -> Pokemon, value: MutableSet<Mark>): SingleUpdatePacket<MutableSet<Mark>, MarksPotentialUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeCollection(this.value) { pb, value -> pb.writeIdentifier(value.identifier) }
@@ -11,13 +11,11 @@ package com.cobblemon.mod.common.net.messages.client.pokemon.update
import com.cobblemon.mod.common.api.mark.Mark
import com.cobblemon.mod.common.api.mark.Marks
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.writeIdentifier
import com.cobblemon.mod.common.util.*
import io.netty.buffer.ByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
class MarksUpdatePacket(pokemon: () -> Pokemon?, value: MutableSet<Mark>): SingleUpdatePacket<MutableSet<Mark>, MarksUpdatePacket>(pokemon, value) {
class MarksUpdatePacket(pokemon: () -> Pokemon, value: MutableSet<Mark>): SingleUpdatePacket<MutableSet<Mark>, MarksUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeCollection(this.value) { pb, value -> pb.writeIdentifier(value.identifier) }
@@ -13,7 +13,7 @@ import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.RegistryFriendlyByteBuf
class MoveSetUpdatePacket(pokemon: () -> Pokemon?, value: MoveSet) : SingleUpdatePacket<MoveSet, MoveSetUpdatePacket>(pokemon, value) {
class MoveSetUpdatePacket(pokemon: () -> Pokemon, value: MoveSet) : SingleUpdatePacket<MoveSet, MoveSetUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
this.value.saveToBuffer(buffer)
@@ -19,7 +19,7 @@ import com.cobblemon.mod.common.util.writeIdentifier
import com.cobblemon.mod.common.util.writeNullable
import net.minecraft.network.RegistryFriendlyByteBuf
class NatureUpdatePacket(pokemon: () -> Pokemon?, val nature: Nature?, val minted: Boolean) : PokemonUpdatePacket<NatureUpdatePacket>(pokemon) {
class NatureUpdatePacket(pokemon: () -> Pokemon, val nature: Nature?, val minted: Boolean) : PokemonUpdatePacket<NatureUpdatePacket>(pokemon) {
override val id = ID
@@ -31,7 +31,7 @@ class NatureUpdatePacket(pokemon: () -> Pokemon?, val nature: Nature?, val minte
override fun applyToPokemon() {
// Check for removing mint
if (minted && nature == null) {
pokemon()!!.mintedNature = null
pokemon().mintedNature = null
return
} else {
// Validate the nature locally
@@ -42,9 +42,9 @@ class NatureUpdatePacket(pokemon: () -> Pokemon?, val nature: Nature?, val minte
// Check which nature to modify
if (!minted) {
pokemon()!!.nature = nature
pokemon().nature = nature
} else {
pokemon()!!.mintedNature = nature
pokemon().mintedNature = nature
}
}
}
@@ -15,7 +15,7 @@ import com.cobblemon.mod.common.util.writeText
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.network.chat.MutableComponent
class NicknameUpdatePacket(pokemon: () -> Pokemon?, value: MutableComponent?): SingleUpdatePacket<MutableComponent?, NicknameUpdatePacket>(pokemon, value) {
class NicknameUpdatePacket(pokemon: () -> Pokemon, value: MutableComponent?): SingleUpdatePacket<MutableComponent?, NicknameUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
@@ -14,7 +14,7 @@ import com.cobblemon.mod.common.util.readString
import com.cobblemon.mod.common.util.writeString
import net.minecraft.network.RegistryFriendlyByteBuf
class OriginalTrainerUpdatePacket(pokemon: () -> Pokemon?, username: String?) : SingleUpdatePacket<String?, OriginalTrainerUpdatePacket>(pokemon, username) {
class OriginalTrainerUpdatePacket(pokemon: () -> Pokemon, username: String?) : SingleUpdatePacket<String?, OriginalTrainerUpdatePacket>(pokemon, username) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
@@ -13,7 +13,7 @@ import com.cobblemon.mod.common.pokemon.activestate.PokemonState
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.RegistryFriendlyByteBuf
class PokemonStateUpdatePacket(pokemon: () -> Pokemon?, value: PokemonState): SingleUpdatePacket<PokemonState, PokemonStateUpdatePacket>(pokemon, value) {
class PokemonStateUpdatePacket(pokemon: () -> Pokemon, value: PokemonState): SingleUpdatePacket<PokemonState, PokemonStateUpdatePacket>(pokemon, value) {
override val id = ID
@@ -15,7 +15,7 @@ import com.cobblemon.mod.common.util.readEnumConstant
import com.cobblemon.mod.common.util.writeEnumConstant
import net.minecraft.network.RegistryFriendlyByteBuf
class RideBoostsUpdatePacket(pokemon: () -> Pokemon?, rideBoosts: Map<RidingStat, Float>) : SingleUpdatePacket<Map<RidingStat, Float>, RideBoostsUpdatePacket>(pokemon, rideBoosts) {
class RideBoostsUpdatePacket(pokemon: () -> Pokemon, rideBoosts: Map<RidingStat, Float>) : SingleUpdatePacket<Map<RidingStat, Float>, RideBoostsUpdatePacket>(pokemon, rideBoosts) {
companion object {
val ID = cobblemonResource("ride_boosts_update")
fun decode(buffer: RegistryFriendlyByteBuf): RideBoostsUpdatePacket {
@@ -37,4 +37,4 @@ class RideBoostsUpdatePacket(pokemon: () -> Pokemon?, rideBoosts: Map<RidingStat
override fun set(pokemon: Pokemon, value: Map<RidingStat, Float>) {
pokemon.setRideBoosts(value)
}
}
}
@@ -12,7 +12,7 @@ import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.RegistryFriendlyByteBuf
class ShinyUpdatePacket(pokemon: () -> Pokemon?, value: Boolean) : BooleanUpdatePacket<ShinyUpdatePacket>(pokemon, value) {
class ShinyUpdatePacket(pokemon: () -> Pokemon, value: Boolean) : BooleanUpdatePacket<ShinyUpdatePacket>(pokemon, value) {
override val id = ID
override fun set(pokemon: Pokemon, value: Boolean) { pokemon.shiny = value }
companion object {
@@ -21,15 +21,14 @@ import net.minecraft.network.RegistryFriendlyByteBuf
* @author Hiroku
* @since November 28th, 2021
*/
abstract class SingleUpdatePacket<T, N : NetworkPacket<N>>(pokemon: () -> Pokemon?, val value: T) : PokemonUpdatePacket<N>(pokemon) {
abstract class SingleUpdatePacket<T, N : NetworkPacket<N>>(pokemon: () -> Pokemon, val value: T) : PokemonUpdatePacket<N>(pokemon) {
override fun encodeDetails(buffer: RegistryFriendlyByteBuf) {
this.encodeValue(buffer)
}
override fun applyToPokemon() {
val pokemon = pokemon() ?: return
set(pokemon, this.value)
set(this.pokemon(), this.value)
}
abstract fun encodeValue(buffer: RegistryFriendlyByteBuf)
@@ -27,7 +27,7 @@ import net.minecraft.resources.ResourceLocation
* @author Hiroku
* @since November 13th, 2023
*/
class SpeciesFeatureUpdatePacket(pokemon: () -> Pokemon?, val species: ResourceLocation, speciesFeature: SynchronizedSpeciesFeature) : SingleUpdatePacket<SynchronizedSpeciesFeature, SpeciesFeatureUpdatePacket>(pokemon, speciesFeature) {
class SpeciesFeatureUpdatePacket(pokemon: () -> Pokemon, val species: ResourceLocation, speciesFeature: SynchronizedSpeciesFeature) : SingleUpdatePacket<SynchronizedSpeciesFeature, SpeciesFeatureUpdatePacket>(pokemon, speciesFeature) {
companion object {
val ID = cobblemonResource("species_feature_update")
fun decode(buffer: RegistryFriendlyByteBuf): SpeciesFeatureUpdatePacket {
@@ -16,7 +16,7 @@ import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.writeIdentifier
import net.minecraft.network.RegistryFriendlyByteBuf
class SpeciesUpdatePacket(pokemon: () -> Pokemon?, value: Species) : SingleUpdatePacket<Species, SpeciesUpdatePacket>(pokemon, value) {
class SpeciesUpdatePacket(pokemon: () -> Pokemon, value: Species) : SingleUpdatePacket<Species, SpeciesUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeIdentifier(this.value.resourceIdentifier)
@@ -20,7 +20,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
* @author Hiroku
* @since November 23rd, 2022
*/
class EVsUpdatePacket(pokemon: () -> Pokemon?, eVs: EVs) : SingleUpdatePacket<EVs, EVsUpdatePacket>(pokemon, eVs) {
class EVsUpdatePacket(pokemon: () -> Pokemon, eVs: EVs) : SingleUpdatePacket<EVs, EVsUpdatePacket>(pokemon, eVs) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
this.value.saveToBuffer(buffer)
@@ -42,7 +42,7 @@ class EVsUpdatePacket(pokemon: () -> Pokemon?, eVs: EVs) : SingleUpdatePacket<EV
* @author Hiroku
* @since November 23rd, 2022
*/
class IVsUpdatePacket(pokemon: () -> Pokemon?, iVs: IVs) : SingleUpdatePacket<IVs, IVsUpdatePacket>(pokemon, iVs) {
class IVsUpdatePacket(pokemon: () -> Pokemon, iVs: IVs) : SingleUpdatePacket<IVs, IVsUpdatePacket>(pokemon, iVs) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
this.value.saveToBuffer(buffer)
@@ -13,11 +13,13 @@ import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.status.PersistentStatus
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readIdentifier
import com.cobblemon.mod.common.util.readNullable
import com.cobblemon.mod.common.util.writeIdentifier
import com.cobblemon.mod.common.util.writeNullable
import io.netty.buffer.ByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
class StatusUpdatePacket(pokemon: () -> Pokemon?, value: PersistentStatus?): SingleUpdatePacket<PersistentStatus?, StatusUpdatePacket>(pokemon, value) {
class StatusUpdatePacket(pokemon: () -> Pokemon, value: PersistentStatus?): SingleUpdatePacket<PersistentStatus?, StatusUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeNullable(this.value) { pb, value -> pb.writeIdentifier(value.name) }
@@ -22,7 +22,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
* @author Segfault Guy
* @since July 19, 2023
*/
class TeraTypeUpdatePacket(pokemon: () -> Pokemon?, value: TeraType) : SingleUpdatePacket<TeraType, TeraTypeUpdatePacket>(pokemon, value) {
class TeraTypeUpdatePacket(pokemon: () -> Pokemon, value: TeraType) : SingleUpdatePacket<TeraType, TeraTypeUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
@@ -10,6 +10,10 @@ package com.cobblemon.mod.common.net.messages.client.pokemon.update
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readNullable
import com.cobblemon.mod.common.util.readUUID
import com.cobblemon.mod.common.util.writeNullable
import com.cobblemon.mod.common.util.writeUUID
import net.minecraft.network.RegistryFriendlyByteBuf
import java.util.UUID
@@ -19,7 +23,7 @@ import java.util.UUID
* @author Hiroku
* @since April 4th, 2023
*/
class TetheringUpdatePacket(pokemon: () -> Pokemon?, tetheringId: UUID?) : SingleUpdatePacket<UUID?, TetheringUpdatePacket>(pokemon, tetheringId) {
class TetheringUpdatePacket(pokemon: () -> Pokemon, tetheringId: UUID?) : SingleUpdatePacket<UUID?, TetheringUpdatePacket>(pokemon, tetheringId) {
override val id = ID
@@ -18,7 +18,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
* @author Hiroku
* @since October 7th, 2023
*/
class TradeableUpdatePacket(pokemon: () -> Pokemon?, value: Boolean) : SingleUpdatePacket<Boolean, TradeableUpdatePacket>(pokemon, value) {
class TradeableUpdatePacket(pokemon: () -> Pokemon, value: Boolean) : SingleUpdatePacket<Boolean, TradeableUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
buffer.writeBoolean(value)
@@ -21,7 +21,7 @@ import io.netty.buffer.ByteBuf
import net.minecraft.core.RegistryAccess
import net.minecraft.network.RegistryFriendlyByteBuf
class AddEvolutionPacket(pokemon: () -> Pokemon?, value: EvolutionDisplay) : SingleUpdatePacket<EvolutionDisplay, AddEvolutionPacket>(pokemon, value) {
class AddEvolutionPacket(pokemon: () -> Pokemon, value: EvolutionDisplay) : SingleUpdatePacket<EvolutionDisplay, AddEvolutionPacket>(pokemon, value) {
override val id = ID
@@ -13,14 +13,14 @@ import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.RegistryFriendlyByteBuf
class ClearEvolutionsPacket(pokemon: () -> Pokemon?) : PokemonUpdatePacket<ClearEvolutionsPacket>(pokemon) {
class ClearEvolutionsPacket(pokemon: () -> Pokemon) : PokemonUpdatePacket<ClearEvolutionsPacket>(pokemon) {
override val id = ID
override fun encodeDetails(buffer: RegistryFriendlyByteBuf) {}
override fun applyToPokemon() {
this.pokemon()?.evolutionProxy?.client()?.clear()
this.pokemon().evolutionProxy.client().clear()
}
companion object {
@@ -19,7 +19,7 @@ import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.core.RegistryAccess
import net.minecraft.network.RegistryFriendlyByteBuf
class RemoveEvolutionPacket(pokemon: () -> Pokemon?, value: EvolutionDisplay) : SingleUpdatePacket<EvolutionDisplay, RemoveEvolutionPacket>(pokemon, value) {
class RemoveEvolutionPacket(pokemon: () -> Pokemon, value: EvolutionDisplay) : SingleUpdatePacket<EvolutionDisplay, RemoveEvolutionPacket>(pokemon, value) {
override val id = ID
@@ -6,11 +6,18 @@
"identifier": "geometry.tinkaton",
"texture_width": 128,
"texture_height": 128,
"visible_bounds_width": 5,
"visible_bounds_width": 8,
"visible_bounds_height": 4.5,
"visible_bounds_offset": [0, 1.75, 0]
},
"bones": [
{
"name": "bb_main",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [-2, 0, 0], "size": [2, 2, 2], "uv": [0, 0]}
]
},
{
"name": "tinkaton",
"pivot": [0, 0, 0]
@@ -26,8 +33,13 @@
"pivot": [0, 4, 0]
},
{
"name": "arm_hammer_right",
"name": "arms_hammer",
"parent": "torso_hammer",
"pivot": [0, 7, 0]
},
{
"name": "arm_hammer_right",
"parent": "arms_hammer",
"pivot": [-1.5, 6.5, 0]
},
{
@@ -98,6 +110,17 @@
{"origin": [-8, 17.75, -43.25], "size": [5, 5, 1], "uv": [24, 56]}
]
},
{
"name": "locator_hammer",
"parent": "hammer_front",
"pivot": [-8, 23, -28.75],
"rotation": [90, 0, 0],
"locators": {
"hammer": [-8, 23, -28.75],
"physical": [-8, 23, -28.75],
"special2": [-8, 23, -28.75]
}
},
{
"name": "hammer_back",
"parent": "hammer_middle",
@@ -107,6 +130,15 @@
{"origin": [-12.5, -7.75, -33.5], "size": [9, 4, 9], "uv": [37, 49]}
]
},
{
"name": "seat_1_locator",
"parent": "hammer_middle",
"pivot": [-8, 15, -35],
"rotation": [90, 0, 0],
"locators": {
"seat_1": [-8, 15, -35]
}
},
{
"name": "body",
"parent": "tinkaton",
@@ -221,6 +253,14 @@
{"origin": [2, 10.25, -3.425], "size": [1, 2, 1], "inflate": 0.01, "uv": [76, 19]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [-2.5, 11.25, -3.5],
"locators": {
"eye1": [-2.5, 11.25, -3.5]
}
},
{
"name": "eye_right",
"parent": "head",
@@ -237,6 +277,14 @@
{"origin": [-3, 10.25, -3.425], "size": [1, 2, 1], "inflate": 0.01, "uv": [20, 72]}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [2.5, 11.25, -3.5],
"locators": {
"eye2": [2.5, 11.25, -3.5]
}
},
{
"name": "mouths",
"parent": "head",
@@ -250,6 +298,14 @@
{"origin": [-2.5, 8.25, -3.41], "size": [5, 2, 0], "uv": [77, 0]}
]
},
{
"name": "locator_mouth",
"parent": "mouth_open",
"pivot": [0, 9.25, -3.5],
"locators": {
"mouth": [0, 9.25, -3.5]
}
},
{
"name": "mouth_closed",
"parent": "mouths",
@@ -307,8 +363,53 @@
]
},
{
"name": "arm_left",
"name": "locator_head",
"parent": "head",
"pivot": [0, 15.25, -2.5],
"locators": {
"head": [0, 15.25, -2.5]
}
},
{
"name": "locator_item_hat",
"parent": "head",
"pivot": [0, 16.25, 0],
"locators": {
"item_hat": [0, 16.25, 0]
}
},
{
"name": "locator_tera_hat",
"parent": "head",
"pivot": [0, 15.25, 0],
"locators": {
"tera_hat": [0, 15.25, 0]
}
},
{
"name": "locator_face",
"parent": "head",
"pivot": [0, 10.25, -3.5],
"locators": {
"face": [0, 10.25, -3.5]
}
},
{
"name": "locator_item_face",
"parent": "head",
"pivot": [0, 11.5, -3.5],
"locators": {
"item_face": [0, 11.5, -3.5]
}
},
{
"name": "arms",
"parent": "torso",
"pivot": [0, 7, 0]
},
{
"name": "arm_left",
"parent": "arms",
"pivot": [1.5, 6.5, 0],
"cubes": [
{"origin": [1.5, 5.5, -1.5], "size": [3, 2, 3], "uv": [94, 16]}
@@ -369,7 +470,7 @@
},
{
"name": "arm_right",
"parent": "torso",
"parent": "arms",
"pivot": [-1.5, 6.5, 0],
"cubes": [
{"origin": [-4.5, 5.5, -1.5], "size": [3, 2, 3], "uv": [58, 93]}
@@ -459,6 +560,46 @@
"cubes": [
{"origin": [0.25, 0, -1], "size": [2, 2, 2], "inflate": 0.2, "uv": [38, 54]}
]
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 7, 0],
"locators": {
"middle": [0, 7, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 7, -6],
"locators": {
"target": [0, 7, -6]
}
},
{
"name": "locator_root",
"parent": "tinkaton",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_special",
"parent": "tinkaton",
"pivot": [0, 7, -8],
"locators": {
"special": [0, 7, -8]
}
},
{
"name": "locator_top",
"parent": "tinkaton",
"pivot": [0, 23, 0],
"locators": {
"top": [0, 23, 0]
}
}
]
}
@@ -33,9 +33,9 @@
"parent": "top_body",
"pivot": [0, 4.5, -0.25],
"cubes": [
{"origin": [-4, 0.5, -10.25], "size": [8, 8, 10], "inflate": 0.11, "uv": [0, 21]},
{"origin": [-3.75, 2.5, -8.25], "size": [0, 4, 6], "uv": [70, -2], "mirror": true},
{"origin": [3.75, 2.5, -8.25], "size": [0, 4, 6], "uv": [70, -6]},
{"origin": [-3.75, 2.5, -8.25], "size": [0, 4, 6], "uv": [70, -2], "mirror": true}
{"origin": [-4, 0.5, -10.25], "size": [8, 8, 10], "inflate": 0.11, "uv": [0, 21]}
]
},
{
@@ -87,6 +87,25 @@
{"origin": [8.5, 2.5, -21.25], "size": [3, 3, 3], "uv": [0, 57]}
]
},
{
"name": "locator_hand_primary1",
"parent": "arm_front_left3",
"pivot": [10, 4, -19.75],
"rotation": [0, -90, 0],
"locators": {
"physical": [10, 4, -19.75],
"hand_primary1": [10, 4, -19.75]
}
},
{
"name": "locator_item",
"parent": "arm_front_left3",
"pivot": [10, 4, -19.75],
"rotation": [0, -90, 0],
"locators": {
"item": [10, 4, -19.75]
}
},
{
"name": "arm_middle_left",
"parent": "arms",
@@ -111,6 +130,15 @@
{"origin": [8.5, 2.5, -17.5], "size": [3, 3, 3], "uv": [24, 57]}
]
},
{
"name": "locator_hand_secondary1",
"parent": "arm_middle_left3",
"pivot": [10, 4, -16],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary1": [10, 4, -16]
}
},
{
"name": "arm_back_left",
"parent": "arms",
@@ -135,6 +163,15 @@
{"origin": [8.5, 2.5, -14.5], "size": [3, 3, 3], "uv": [65, 58]}
]
},
{
"name": "locator_hand_secondary3",
"parent": "arm_back_left3",
"pivot": [10, 4, -13],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary3": [10, 4, -13]
}
},
{
"name": "arm_front_right",
"parent": "arms",
@@ -159,6 +196,15 @@
{"origin": [-11.5, 2.5, -21.25], "size": [3, 3, 3], "uv": [12, 57], "mirror": true}
]
},
{
"name": "locator_hand_primary2",
"parent": "arm_front_right3",
"pivot": [-10, 4, -19.75],
"rotation": [0, 90, 0],
"locators": {
"hand_primary2": [-10, 4, -19.75]
}
},
{
"name": "arm_middle_right",
"parent": "arms",
@@ -183,6 +229,15 @@
{"origin": [-11.5, 2.5, -17.5], "size": [3, 3, 3], "uv": [53, 58], "mirror": true}
]
},
{
"name": "locator_hand_secondary2",
"parent": "arm_middle_right3",
"pivot": [-10, 4, -16],
"rotation": [0, 90, 0],
"locators": {
"hand_secondary2": [-10, 4, -16]
}
},
{
"name": "arm_back_right",
"parent": "arms",
@@ -207,6 +262,15 @@
{"origin": [-11.5, 2.5, -14.5], "size": [3, 3, 3], "uv": [77, 58], "mirror": true}
]
},
{
"name": "locator_hand_secondary4",
"parent": "arm_back_right3",
"pivot": [-10, 4, -13],
"rotation": [0, 90, 0],
"locators": {
"hand_secondary4": [-10, 4, -13]
}
},
{
"name": "head",
"parent": "chest",
@@ -246,6 +310,14 @@
{"origin": [1, 5.5, -32.03], "size": [1, 1, 0], "uv": [4, 0]}
]
},
{
"name": "locator_eye_left",
"parent": "pupil_left",
"pivot": [1.5, 6, -32],
"locators": {
"eye_left": [1.5, 6, -32]
}
},
{
"name": "eyelid_left",
"parent": "eye_left",
@@ -285,6 +357,14 @@
{"origin": [-2, 5.5, -32.03], "size": [1, 1, 0], "uv": [4, 0], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "pupil_right",
"pivot": [-1.5, 6, -32],
"locators": {
"eye_right": [-1.5, 6, -32]
}
},
{
"name": "eyelid_right",
"parent": "eye_right",
@@ -311,6 +391,71 @@
{"origin": [-4, 1, -32.25], "size": [8, 3, 4], "uv": [0, 14]}
]
},
{
"name": "locator_jaw_lower",
"parent": "jaw",
"pivot": [0, 4, -32.5],
"locators": {
"jaw2": [0, 4, -32.5]
}
},
{
"name": "head_locator",
"parent": "head",
"pivot": [0, 9, -29],
"locators": {
"head": [0, 9, -29]
}
},
{
"name": "item_hat_locator",
"parent": "head",
"pivot": [0, 9, -27.25],
"locators": {
"item_hat": [0, 9, -27.25]
}
},
{
"name": "face_locator",
"parent": "head",
"pivot": [0, 5, -32.5],
"locators": {
"face": [0, 5, -32.5]
}
},
{
"name": "item_face_locator",
"parent": "head",
"pivot": [0, 6, -32.5],
"locators": {
"item_face": [0, 6, -32.5]
}
},
{
"name": "mouth_locator",
"parent": "head",
"pivot": [0, 4, -28.5],
"locators": {
"mouth": [0, 4, -28.5],
"special": [0, 4, -28.5]
}
},
{
"name": "locator_jaw_upper",
"parent": "head",
"pivot": [0, 4, -32.5],
"locators": {
"jaw1": [0, 4, -32.5]
}
},
{
"name": "seat_1_locator",
"parent": "chest",
"pivot": [0, 10, -16],
"locators": {
"seat_1": [0, 10, -16]
}
},
{
"name": "segment1",
"parent": "body",
@@ -354,6 +499,56 @@
"cubes": [
{"origin": [-4, 0.5, 22.75], "size": [8, 8, 9], "inflate": 0.1, "uv": [56, 41]}
]
},
{
"name": "locator_tail",
"parent": "segment5",
"pivot": [0, 4.5, 27.5],
"rotation": [0, 180, 0],
"locators": {
"tail": [0, 4.5, 27.5]
}
},
{
"name": "locator_tail_tip",
"parent": "segment5",
"pivot": [0, 4.5, 32],
"rotation": [0, 180, 0],
"locators": {
"tail_tip": [0, 4.5, 32]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 4.5, 0],
"locators": {
"middle": [0, 4.5, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 4.5, -36],
"locators": {
"target": [0, 4.5, -36]
}
},
{
"name": "locator_root",
"parent": "orthworm",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "orthworm",
"pivot": [0, 11, 0],
"locators": {
"top": [0, 11, 0]
}
}
]
}
@@ -0,0 +1,102 @@
{
"portraitScale": 1,
"portraitTranslation": [-0.45, 3, 0],
"profileScale": 0.36,
"profileTranslation": [0, 1.2, 0],
"rootBone": "corviknight",
"firstPersonCameraOffset": {
"seat_1": [0, 0.25, 0]
},
"thirdPersonCameraOffset": {
"seat_1": [0, 4, 10],
"seat_1_reverse": [0, 3, 8]
},
"animations": {
"cry": "q.bedrock_stateful('corviknight', 'cry')"
},
"poses": {
"standing": {
"poseName": "standing",
"poseTypes": [
"STAND",
"NONE",
"PORTRAIT",
"PROFILE"
],
"animations": [
"q.look('head')",
"q.bedrock('corviknight', 'ground_idle')",
"q.bedrock('corviknight', 'folded_wangs')"
],
"transformTicks": 10,
"quirks": [
"q.bedrock_quirk('corviknight', 'blink')"
]
},
"walking": {
"poseName": "walking",
"poseTypes": [
"WALK"
],
"animations": [
"q.look('head')",
"q.bedrock('corviknight', 'ground_walk')",
"q.bedrock('corviknight', 'folded_wangs')"
],
"transformTicks": 10,
"quirks": [
"q.bedrock_quirk('corviknight', 'blink')"
]
},
"hover": {
"poseName": "hover",
"poseTypes": [
"HOVER",
"FLOAT"
],
"animations": [
"q.look('head')",
"q.bedrock('corviknight', 'air_idle')",
"q.bedrock('corviknight', 'wangs')"
],
"transformTicks": 10,
"quirks": [
"q.bedrock_quirk('corviknight', 'blink')"
]
},
"fly": {
"poseName": "fly",
"poseTypes": [
"FLY",
"SWIM"
],
"condition": "!q.is_gliding",
"animations": [
"q.look('head')",
"q.bedrock('corviknight', 'air_fly')",
"q.bedrock('corviknight', 'wangs')"
],
"transformTicks": 10,
"quirks": [
"q.bedrock_quirk('corviknight', 'blink')"
]
},
"glide": {
"poseName": "fly",
"poseTypes": [
"FLY",
"SWIM"
],
"condition": "q.is_gliding",
"animations": [
"q.look('head')",
"q.bedrock('corviknight', 'air_glide_TEST')",
"q.bedrock('corviknight', 'wangs')"
],
"transformTicks": 10,
"quirks": [
"q.bedrock_quirk('corviknight', 'blink')"
]
}
}
}
@@ -8,7 +8,7 @@
"poses": {
"in_air": {
"poseName": "in_air",
"poseTypes": ["WALK","STAND", "FLOAT", "NONE", "PORTRAIT"],
"poseTypes": ["STAND","WALK", "FLOAT"],
"isBattle": false,
"condition": "q.in_air",
"animations": [
@@ -4,11 +4,34 @@
"profileScale": 1,
"profileTranslation": [0.0, 0.3, 0.0],
"rootBone": "tinkaton",
"firstPersonCameraOffset": {
"seat_1": [0, 0.25, 0]
},
"thirdPersonCameraOffset": {
"seat_1": [0, 3, 6],
"seat_1_reverse": [0, 3, 6]
},
"animations": {
"faint": "q.bedrock_primary('tinkaton', 'faint', q.curve('one'))",
"cry": "q.bedrock_stateful('tinkaton', 'cry')"
},
"poses": {
"in-air": {
"poseName": "in-air",
"poseTypes": ["STAND","WALK", "FLOAT"],
"condition": "q.in_air",
"animations": [
"q.look('head')",
"q.bedrock('tinkaton', 'ride_jump')",
{
"condition": "q.is_ridden",
"animation": "q.bedrock('tinkaton', 'ride_mount_run')"
}
],
"quirks": ["q.bedrock_quirk('tinkaton', 'blink')"],
"transformTicks": 2,
"transformToTicks": 2
},
"battle-standing": {
"poseName": "battle-standing",
"poseTypes": ["STAND"],
@@ -26,15 +49,68 @@
"sleeping": "q.bedrock_primary('tinkaton', 'sleep_transition')"
}
},
"mount-standing": {
"poseName": "mount-standing",
"poseTypes": ["STAND"],
"isBattle": false,
"condition": "q.is_ridden",
"animations": ["q.look('head')", "q.bedrock('tinkaton', 'mount_idle')", "q.bedrock('tinkaton', 'ride_mount_run')"],
"quirks": ["q.bedrock_quirk('tinkaton', 'blink')"],
"transitions": {
"sleeping": "q.bedrock_primary('tinkaton', 'sleep_transition')"
}
},
"walking": {
"poseName": "walking",
"poseTypes": ["WALK"],
"condition": "!q.is_ridden && !q.is_sprinting",
"animations": ["q.look('head')", "q.bedrock('tinkaton', 'ground_walk')"],
"quirks": ["q.bedrock_quirk('tinkaton', 'blink')"],
"transitions": {
"sleeping": "q.bedrock_primary('tinkaton', 'sleep_transition')"
}
},
"mount-walking": {
"poseName": "mount-walking",
"poseTypes": ["WALK"],
"condition": "q.is_ridden && !q.is_sprinting",
"animations": [
"q.look('head')",
"q.bedrock('tinkaton', 'mount_walk')",
"q.bedrock('tinkaton', 'ride_mount_run')"
],
"quirks": ["q.bedrock_quirk('tinkaton', 'blink')"],
"transitions": {
"sleeping": "q.bedrock_primary('tinkaton', 'sleep_transition')"
}
},
"run": {
"poseName": "run",
"poseTypes": ["WALK"],
"condition": "!q.is_ridden && q.is_sprinting",
"animations": [
"q.look('head')",
"q.bedrock('tinkaton', 'ground_run')"
],
"quirks": ["q.bedrock_quirk('tinkaton', 'blink')"],
"transitions": {
"sleeping": "q.bedrock_primary('tinkaton', 'sleep_transition')"
}
},
"mount-run": {
"poseName": "mount-run",
"poseTypes": ["WALK"],
"condition": "q.is_ridden && q.is_sprinting",
"animations": [
"q.look('head')",
"q.bedrock('tinkaton', 'mount_run')",
"q.bedrock('tinkaton', 'ride_mount_run')"
],
"quirks": ["q.bedrock_quirk('tinkaton', 'blink')"],
"transitions": {
"sleeping": "q.bedrock_primary('tinkaton', 'sleep_transition')"
}
},
"sleeping": {
"poseName": "sleeping",
"poseTypes": ["SLEEP"],
@@ -4,7 +4,30 @@
"profileScale": 0.59,
"profileTranslation": [0.11, 1.09, 0],
"rootBone": "orthworm",
"firstPersonCameraOffset": {
"seat_1": [0, 0.25, 0]
},
"thirdPersonCameraOffset": {
"seat_1": [0, 1.5, 5],
"seat_1_reverse": [0, 1.5, 5]
},
"poses": {
"in-air": {
"poseName": "in-air",
"poseTypes": ["STAND", "WALK", "FLOAT", "NONE"],
"condition": "q.in_air",
"animations": [
"q.look('head')",
"q.bedrock('orthworm', 'ride_jump')",
{
"condition": "q.is_ridden",
"animation": "q.bedrock('orthworm', 'ride_ground_walk')"
}
],
"quirks": ["q.bedrock_quirk('orthworm', 'blink')"],
"transformTicks": 2,
"transformToTicks": 2
},
"portrait": {
"poseTypes": ["PORTRAIT", "PROFILE"],
"animations": [
@@ -22,16 +45,38 @@
},
"standing": {
"poseTypes": ["STAND", "NONE"],
"condition": "q.in_battle() == false",
"condition": "q.in_battle() == false && !q.in_air",
"animations": [
"q.bedrock('orthworm', 'ground_idle')"
"q.bedrock('orthworm', 'ground_idle')",
{
"condition": "q.is_ridden",
"animation": "q.bedrock('orthworm', 'ride_ground_walk')"
}
],
"quirks": ["q.bedrock_quirk('orthworm', 'blink')"]
},
"walking": {
"poseTypes": ["WALK"],
"condition": "!q.in_air && !q.is_sprinting",
"animations": [
"q.bedrock('orthworm', 'ground_idle')"
"q.bedrock('orthworm', 'ground_walk')",
{
"condition": "q.is_ridden",
"animation": "q.bedrock('orthworm', 'ride_ground_walk')"
}
],
"quirks": ["q.bedrock_quirk('orthworm', 'blink')"]
},
"run": {
"poseName": "run",
"poseTypes": ["WALK"],
"condition": "q.is_sprinting && !q.in_air",
"animations": [
"q.bedrock('orthworm', 'ground_run')",
{
"condition": "q.is_ridden",
"animation": "q.bedrock('orthworm', 'ride_ground_run')"
}
],
"quirks": ["q.bedrock_quirk('orthworm', 'blink')"]
}
@@ -2431,10 +2431,8 @@
"cobblemon.config.ui.party_portrait_animations.animate_selected.tooltip": "Selected Pokémon animates unless fainted",
"cobblemon.config.ui.party_portrait_animations.always_animate": "Always animate",
"cobblemon.config.ui.party_portrait_animations.always_animate.tooltip": "Entire party animates unless fainted",
"cobblemon.config.ui.view_bob_translation": "View Bob Translation",
"cobblemon.config.ui.view_bob_translation.tooltip": "If true then use default Minecraft behavior to follow directly behind the player's head. If false then follow a fixed offset from the pokemon.",
"cobblemon.config.ui.view_bob_rotation": "View Bob Rotation",
"cobblemon.config.ui.view_bob_rotation.tooltip": "If true then will rotate the camera based on the Pokemon's movements. If false then no rotation will occur.",
"cobblemon.config.ui.third_person_view_bobbing": "Third Person View Bobbing",
"cobblemon.config.ui.third_person_view_bobbing.tooltip": "If true then use default Minecraft behavior to follow directly behind the player's head. If false then follow a fixed offset from the pokemon.",
"cobblemon.config.ui.invert_pitch": "Invert Pitch",
"cobblemon.config.ui.invert_pitch.tooltip": "Invert the direction for pitch (left and right).",
"cobblemon.config.ui.invert_yaw": "Invert Yaw",
@@ -8901,4 +8899,4 @@
"cobblemon.ability.teraformzero.desc": "When Terapagos changes into its Stellar Form, it uses its hidden powers to eliminate all effects of weather and terrain, reducing them to zero.",
"cobblemon.ability.poisonpuppeteer": "Poison Puppeteer",
"cobblemon.ability.poisonpuppeteer.desc": "Pokémon poisoned by Pecharunt's moves will also become confused."
}
}
@@ -1,6 +0,0 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "cobblemon:item/candied_berry"
}
}
@@ -1,6 +0,0 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "cobblemon:item/jelly_doughnut"
}
}
@@ -1,8 +0,0 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "cobblemon:item/lure_cake",
"layer1": "cobblemon:item/lure_cake_overlay1",
"layer2": "cobblemon:item/lure_cake_overlay2"
}
}
@@ -1,8 +0,0 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "cobblemon:item/lure_cake",
"layer1": "cobblemon:item/lure_cake_overlay1",
"layer2": "cobblemon:item/lure_cake_overlay2"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 33 KiB

@@ -1,23 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "foods",
"ingredients": [
{
"item": "minecraft:apple"
},
{
"item": "minecraft:stick"
},
{
"item": "minecraft:sugar"
},
{
"item": "minecraft:honey_bottle"
}
],
"result": {
"id": "cobblemon:candied_apple",
"count": 1
},
"seasoningProcessors": []
}
@@ -1,29 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "foods",
"ingredients": [
{
"tag": "cobblemon:berries"
},
{
"tag": "cobblemon:berries"
},
{
"tag": "cobblemon:berries"
},
{
"item": "minecraft:stick"
},
{
"item": "minecraft:sugar"
},
{
"item": "minecraft:honey_bottle"
}
],
"result": {
"id": "cobblemon:candied_berry",
"count": 1
},
"seasoningProcessors": []
}
@@ -1,23 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "misc",
"ingredients": [
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:qualot_berry"
}
],
"result": {
"id": "cobblemon:clever_mochi",
"count": 3
},
"seasoningProcessors": []
}
@@ -1,23 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "misc",
"ingredients": [
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:enigma_berry"
}
],
"result": {
"id": "cobblemon:fresh_start_mochi",
"count": 3
},
"seasoningProcessors": []
}
@@ -1,23 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "misc",
"ingredients": [
{
"item": "minecraft:bowl"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
}
],
"result": {
"id": "cobblemon:fried_rice",
"count": 1
},
"seasoningProcessors": []
}
@@ -1,23 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "misc",
"ingredients": [
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hondew_berry"
}
],
"result": {
"id": "cobblemon:genius_mochi",
"count": 3
},
"seasoningProcessors": []
}
@@ -1,23 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "misc",
"ingredients": [
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:pomeg_berry"
}
],
"result": {
"id": "cobblemon:health_mochi",
"count": 3
},
"seasoningProcessors": []
}
@@ -1,20 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "foods",
"ingredients": [
{
"item": "cobblemon:hearty_grains"
},
{
"tag": "cobblemon:berries"
},
{
"item": "minecraft:dried_kelp"
}
],
"result": {
"id": "cobblemon:jelly_doughnut",
"count": 1
},
"seasoningProcessors": []
}
@@ -1,23 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "misc",
"ingredients": [
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:kelpsy_berry"
}
],
"result": {
"id": "cobblemon:muscle_mochi",
"count": 3
},
"seasoningProcessors": []
}
@@ -1,23 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "foods",
"ingredients": [
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "minecraft:potato"
}
],
"result": {
"id": "cobblemon:potato_mochi",
"count": 3
},
"seasoningProcessors": []
}
@@ -1,23 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "misc",
"ingredients": [
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:qualot_berry"
}
],
"result": {
"id": "cobblemon:resist_mochi",
"count": 3
},
"seasoningProcessors": []
}
@@ -1,23 +0,0 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "misc",
"ingredients": [
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:hearty_grains"
},
{
"item": "cobblemon:tamato_berry"
}
],
"result": {
"id": "cobblemon:swift_mochi",
"count": 3
},
"seasoningProcessors": []
}
@@ -3,7 +3,7 @@
"effects": [
{
"type": "cobblemon:ev",
"subcategory": "spd",
"subcategory": "def",
"chance": 1.0,
"value": 100.0
}
@@ -3,7 +3,7 @@
"effects": [
{
"type": "cobblemon:ev",
"subcategory": "spa",
"subcategory": "spd",
"chance": 1.0,
"value": 100.0
}
@@ -3,7 +3,7 @@
"effects": [
{
"type": "cobblemon:ev",
"subcategory": "atk",
"subcategory": "spa",
"chance": 1.0,
"value": 100.0
}
@@ -3,7 +3,7 @@
"effects": [
{
"type": "cobblemon:ev",
"subcategory": "def",
"subcategory": "spe",
"chance": 1.0,
"value": 100.0
}
@@ -3,7 +3,7 @@
"effects": [
{
"type": "cobblemon:ev",
"subcategory": "spe",
"subcategory": "atk",
"chance": 1.0,
"value": 100.0
}
@@ -49,10 +49,67 @@
"height": 4.4,
"fixed": false
},
"riding": {
"stats": {
"SPEED": {
"ranges": {
"LAND": "5-15",
"AIR": "35-65"
}
},
"ACCELERATION": {
"ranges": {
"LAND": "10-100",
"AIR": "20-50"
}
},
"SKILL": {
"ranges": {
"LAND": "40-85",
"AIR": "25-50"
}
},
"JUMP": {
"ranges": {
"LAND": "20-55",
"AIR": "30-60"
}
},
"STAMINA": {
"ranges": {
"LAND": "55-85",
"AIR": "55-85"
}
}
},
"behaviour": {
"key": "cobblemon:composite",
"transitionStrategy": "cobblemon:strategy/jump",
"defaultBehaviour": {
"key": "cobblemon:land/generic"
},
"alternateBehaviour": {
"key": "cobblemon:air/bird"
}
},
"seats": [
{
"offset": {
"x": 0,
"y": 0,
"z": 0
}
}
]
},
"behaviour": {
"moving": {
"walk": {
"walkSpeed": 0.147
},
"fly": {
"canFly": true
"canFly": true,
"flySpeedHorizontal": 0.6
}
},
"resting": {
@@ -207,43 +264,5 @@
"evolutions": [],
"battleOnly": true
}
],
"riding": {
"stats": {
"SPEED": {
"ranges": {
"LAND": "5-15",
"AIR": "35-65"
}
},
"ACCELERATION": {
"ranges": {
"LAND": "10-100",
"AIR": "20-50"
}
},
"SKILL": {
"ranges": {
"LAND": "40-85",
"AIR": "25-50"
}
},
"JUMP": {
"ranges": {
"LAND": "20-55",
"AIR": "30-60"
}
},
"STAMINA": {
"ranges": {
"LAND": "55-85",
"AIR": "55-85"
}
}
},
"seats": [],
"behaviour": {
"key": "cobblemon:land/generic"
}
}
]
}
@@ -53,6 +53,68 @@
}
]
},
"riding": {
"stats": {
"SPEED": {
"displayName": "Speed",
"description": "Its top speed",
"ranges": {
"LAND": "50-100"
}
},
"ACCELERATION": {
"displayName": "Acceleration",
"description": "How fast it can speed up",
"ranges": {
"LAND": "50-100"
}
},
"SKILL": {
"displayName": "Handling",
"description": "How fast it can turn",
"ranges": {
"LAND": "50-100"
}
},
"JUMP": {
"displayName": "Altitude",
"description": "How high it can jump",
"ranges": {
"LAND": "50-100"
}
},
"STAMINA": {
"displayName": "Fuel/Stamina",
"description": "How long it can sprint",
"ranges": {
"LAND": "50-100"
}
}
},
"behaviour": {
"key": "cobblemon:land/generic"
},
"seats": [
{
"offset": {
"x": 0,
"y": 0,
"z": 0
}
}
]
},
"behaviour": {
"moving": {
"walk": {
"walkSpeed": 0.3
}
},
"resting": {
"canSleep": true,
"light": "0-4"
}
},
"moves": [
"1:tackle",
"1:wrap",
@@ -49,7 +49,63 @@
"height": 0.95,
"fixed": false
},
"riding": {
"stats": {
"SPEED": {
"displayName": "Speed",
"description": "Its top speed",
"ranges": {
"LAND": "50-100"
}
},
"ACCELERATION": {
"displayName": "Acceleration",
"description": "How fast it can speed up",
"ranges": {
"LAND": "50-100"
}
},
"SKILL": {
"displayName": "Handling",
"description": "How fast it can turn",
"ranges": {
"LAND": "50-100"
}
},
"JUMP": {
"displayName": "Altitude",
"description": "How high it can jump",
"ranges": {
"LAND": "50-100"
}
},
"STAMINA": {
"displayName": "Fuel/Stamina",
"description": "How long it can sprint",
"ranges": {
"LAND": "50-100"
}
}
},
"behaviour": {
"key": "cobblemon:land/generic"
},
"seats": [
{
"offset": {
"x": 0,
"y": 0,
"z": 0
}
}
]
},
"behaviour": {
"moving": {
"walk": {
"walkSpeed": 0.18
}
},
"resting": {
"canSleep": true,
"light": "0-4"