Compare commits

..
219 changed files with 5921 additions and 13048 deletions

No files matched your search

+3 -20
View File
@@ -13,10 +13,7 @@
- Added `visibility/hidden`, `visibility/hat` and `visibility/face` tags to control where and how certain items are rendered.
- Added Pokémon markings, toggleable within the summary.
- Added `/boxcount` command to change PC boxes amount
- Added cosmetics for Gurdurr, Conkeldurr, Squirtle Line, Sneasler, Sandile line, Treecko line, Braixen, Delphox, and Dragonite.
- Added cosmetics for Gurdurr, Conkeldurr, Squirtle Line, Sneasler, Sandle line, Treecko line, Braixen, Delphox, and Dragonite.
- Added `/transformmodelpart (position|rotation|scale) <modelPart> <transform: x y z>` command that can add transformations to a pokemon's model part.
- The player executing the command must be facing the target pokemon entity. Transformations are not persistent and will revert when resources are reloaded.
### Pokémon Added
@@ -69,13 +66,9 @@
### Animation updates for the following Pokémon
- Garchomp
- Tropius
- Torpius
- Nosepass
- Probopass
- Sneasler
- Braixen
- Delphox
### Model updates for the following Pokémon
- Gyarados
@@ -89,16 +82,13 @@
- Leafeon
- Glaceon
- Sylveon
- Treecko
- Grovyle
- Sceptile
- Honchkrow
- Garchomp
- Pidgeot
- Nosepass
- Probopass
- Magnezone
- Metagross
- Added `/transformmodelpart (position|rotation|scale) <modelPart> <transform: x y z>` command that can add transformations to a pokemon's model part.
- The player executing the command must be facing the target pokemon entity. Transformations are not persistent and will revert when resources are reloaded.
### Changes
- Renamed `chargeGainedPerTick` config to `secondsToChargeHealingMachine`.
@@ -154,7 +144,6 @@
- Updated NPCEntity beam positioning to properly account for the baseScale property.
- Updated NPCEntity pokeball throw positioning to properly account for the baseScale property.
- Fixed `[Pokemon].copyFrom` error causing forms, IVs, and EVs to not be applied properly when using `[Pokemon].loadFromJSON` or `[Pokemon].loadFromNBT`
- Added new item class, `WearableItem`. Instances of this class should have a corresponding 3D model. These models render when the items display context is `HEAD`.
### MoLang & Datapacks
- The following usages for item predicates can now use item conditions like advancements do, you can learn about them in the [Minecraft wiki](https://minecraft.wiki/w/Advancement_definition#minecraft:filled_bucket)
@@ -165,14 +154,9 @@
- Added `interpolate` boolean property to animated textures to allow gradual colour changes between frames.
- Fixed species additions not being capable of changing implemented status.
- Added support for action effects that are triggered by `|-activate|` Showdown instructions. `activate_{effect_id}` is the syntax.
- Added MoLang functions for rendering items `render_item(item_id, locator_name)` and `clear_items()`.
- Added Molang functions for rendering items `render_item(item_id, locator_name)` and `clear_items()`.
- Fixed location spawn filter components causing crashes
- Added `pokemon` as an available MoLang function for the `battleActor` functions.
- Added `spawn_pokemon` as an available MoLang function for the `worldHolder` functions.
- Added `attempt_wild_battle` as an available MoLang function.
- Added `pokemon` as an available Molang function for the `battleActor` functions.
- Fixed `heldItem` property inside spawn files not working and causing crashes
- Fixed `spawn_bedrock_particles` MoLang causing crashes when used in a server environment
## [1.6.1 (January 26th, 2025)](#1-6-1)
@@ -278,7 +262,6 @@
- Geodude
- Graveler
- Golem
- Magnezone
### Cry updates for the following Pokémon
- Sceptile
@@ -0,0 +1,30 @@
/*
* 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.mixin;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import net.minecraft.server.ServerInterface;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ServerLevel.class)
public abstract class MinecraftDedicatedServerMixin implements ServerInterface {
@Inject(method = "shouldDiscardEntity", at = @At(value = "HEAD"), cancellable = true)
public void cobblemon$allowPokemonSpawns(Entity entity, CallbackInfoReturnable<Boolean> callback) {
if (entity instanceof PokemonEntity) {
callback.setReturnValue(false);
}
}
}
@@ -1,53 +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.mixin;
import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.entity.pokemon.PokemonServerDelegate;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.block.LevelEvent;
import net.minecraft.world.phys.AABB;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ServerLevel.class)
public abstract class ServerLevelMixin {
@Inject(method = "shouldDiscardEntity", at = @At(value = "HEAD"), cancellable = true)
public void cobblemon$allowPokemonSpawns(Entity entity, CallbackInfoReturnable<Boolean> callback) {
if (entity instanceof PokemonEntity) {
callback.setReturnValue(false);
}
}
@Inject(method = "levelEvent(Lnet/minecraft/world/entity/player/Player;ILnet/minecraft/core/BlockPos;I)V", at = @At(value = "HEAD"))
public void cobblemon$setPokemonDancing(Player player, int type, BlockPos pos, int data, CallbackInfo ci) {
if (type == LevelEvent.SOUND_PLAY_JUKEBOX_SONG || type == LevelEvent.SOUND_STOP_JUKEBOX_SONG) {
cobblemon$notifyNearbyEntities((ServerLevel) ((Object) this), pos, type == LevelEvent.SOUND_PLAY_JUKEBOX_SONG);
}
}
@Unique
private void cobblemon$notifyNearbyEntities(ServerLevel level, BlockPos pos, boolean playing) {
for (PokemonEntity pokemonEntity : level.getEntitiesOfClass(PokemonEntity.class, new AABB(pos).inflate(Cobblemon.config.getPokemonDanceDistance()))) {
PokemonServerDelegate delegate = (PokemonServerDelegate) pokemonEntity.getDelegate();
delegate.setDancing(playing);
delegate.setJukeboxPos(pos);
pokemonEntity.setRecordPlayingNearby(pos, playing);
}
}
}
@@ -13,7 +13,7 @@ import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.api.orientation.OrientationController;
import com.cobblemon.mod.common.api.riding.Rideable;
import com.cobblemon.mod.common.api.riding.Seat;
import com.cobblemon.mod.common.client.MountedPokemonAnimationRenderController;
import com.cobblemon.mod.common.client.Test;
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate;
import com.cobblemon.mod.common.client.render.MatrixWrapper;
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState;
@@ -27,6 +27,7 @@ import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.HitResult;
@@ -62,6 +63,8 @@ public abstract class CameraMixin {
@Shadow
private BlockGetter level;
@Shadow public abstract float getPartialTickTime();
@Shadow private float partialTickTime;
@Unique private float returnTimer = 0;
@Unique private float rollAngleStart = 0;
@@ -70,7 +73,7 @@ public abstract class CameraMixin {
@Unique boolean disableRollableCameraDebug = false;
@Inject(method = "setRotation", at = @At("HEAD"), cancellable = true)
public void cobblemon$setRotation(float f, float g, CallbackInfo ci) {
public void open_camera$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) {
@@ -88,7 +91,7 @@ public abstract class CameraMixin {
return;
}
controller.getOrientation().rotateZ((float) Math.toRadians(-rollAngleStart*(1-returnTimer)));
cobblemon$applyRotation();
applyRotation();
this.returnTimer += .05F;
ci.cancel();
} else {
@@ -98,7 +101,7 @@ public abstract class CameraMixin {
return;
}
if (controller.getOrientation() == null) return;
cobblemon$applyRotation();
applyRotation();
this.returnTimer = 0;
this.rollAngleStart = controller.getRoll();
@@ -107,10 +110,9 @@ public abstract class CameraMixin {
//If you want to move this to a delagate you need an AW for position
@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) {
public void positionCamera(Camera instance, double x, double y, double z, Operation<Void> original, @Local(ordinal = 1, argsOnly = true) boolean thirdPersonReverse) {
Entity entity = instance.getEntity();
Entity vehicle = entity.getVehicle();
MountedPokemonAnimationRenderController.INSTANCE.reset();
if(vehicle instanceof Rideable){
//RidingCameraDelagate.INSTANCE.positionCamera(instance, x, y, z, original);
@@ -125,7 +127,35 @@ public abstract class CameraMixin {
Mth.lerp(instance.getPartialTickTime(), pokemon.yOld, pokemon.getY()),
Mth.lerp(instance.getPartialTickTime(), pokemon.zOld, pokemon.getZ())
);
MountedPokemonAnimationRenderController.INSTANCE.setup(pokemon, partialTickTime);
if (delegate.getCurrentModel() != null) {
float f = Mth.rotLerp(partialTickTime, pokemon.yBodyRotO, pokemon.yBodyRot);
float g = Mth.rotLerp(partialTickTime, pokemon.yHeadRotO, pokemon.yHeadRot);
float h = g - f;
float j = Mth.lerp(partialTickTime, entity.xRotO, entity.getXRot());
h = Mth.wrapDegrees(h);
float l = 0.0F;
float m = 0.0F;
if (!pokemon.isPassenger() && pokemon.isAlive()) {
l = pokemon.walkAnimation.speed(partialTickTime);
m = pokemon.walkAnimation.position(partialTickTime);
if (pokemon.isBaby()) {
m *= 3.0F;
}
if (l > 1.0F) {
l = 1.0F;
}
}
Test.INSTANCE.setLocked(false);
delegate.updatePartialTicks(partialTickTime);
delegate.updateLocatorPosition(entityPos);
delegate.getCurrentModel().applyAnimations(pokemon, delegate, l, m, partialTickTime, j, h);
Test.INSTANCE.setLocked(true);
}
int seatIndex = pokemon.getPassengers().indexOf(entity);
Seat seat = pokemon.getSeats().get(seatIndex);
@@ -185,7 +215,7 @@ public abstract class CameraMixin {
}
@Unique
private void cobblemon$applyRotation(){
private void 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());
@@ -59,21 +59,8 @@ public class HumanoidModelMixin {
}
Entity vehicle = entity.getVehicle();
if (vehicle instanceof PokemonEntity pokemonEntity && entity instanceof AbstractClientPlayer) {
var shouldRotatePlayerHead = pokemonEntity.ifRidingAvailableSupply(false, (behaviour, settings, state) -> {
return behaviour.shouldRotatePlayerHead(settings, state, pokemonEntity);
});
if (!shouldRotatePlayerHead) {
netHeadYaw = 0f;
headPitch = 0f;
if (this.head != null) {
this.head.yRot = 0f;
this.head.xRot = 0f;
}
}
MountedPlayerRenderer.INSTANCE.animate(pokemonEntity, (AbstractClientPlayer) entity, relevantPartsByName, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
if (vehicle instanceof PokemonEntity && entity instanceof AbstractClientPlayer) {
MountedPlayerRenderer.INSTANCE.animate((PokemonEntity) vehicle, (AbstractClientPlayer) entity, relevantPartsByName, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
}
}
}
@@ -12,7 +12,6 @@ import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.ModAPI;
import com.cobblemon.mod.common.item.PokeBallItem;
import com.cobblemon.mod.common.item.PokedexItem;
import com.cobblemon.mod.common.item.WearableItem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.ItemModelShaper;
@@ -55,18 +54,17 @@ public abstract class ItemRendererMixin {
)
private void cobblemon$overrideItemModel(ItemStack stack, ItemDisplayContext renderMode, boolean leftHanded, PoseStack matrices, MultiBufferSource multiBufferSource, int light, int overlay, BakedModel model, CallbackInfo ci) {
boolean shouldBe2d = renderMode == ItemDisplayContext.GUI || renderMode == ItemDisplayContext.FIXED;
ResourceLocation resourceLocation = null;
if (shouldBe2d) {
ResourceLocation resourceLocation = null;
if (stack.getItem() instanceof PokeBallItem pokeBallItem) resourceLocation = pokeBallItem.getPokeBall().getModel2d();
else if (stack.getItem() instanceof PokedexItem pokedexItem) resourceLocation = pokedexItem.getType().getItemSpritePath();
}
if (renderMode != ItemDisplayContext.HEAD && stack.getItem() instanceof WearableItem wearableItem) resourceLocation = wearableItem.getModel2d();
if (resourceLocation != null) {
BakedModel replacementModel = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation(resourceLocation, "inventory"));
if (!cobblemon$isSameModel(model, replacementModel)) {
ci.cancel();
render(stack, renderMode, leftHanded, matrices, multiBufferSource, light, overlay, replacementModel);
if (resourceLocation != null) {
BakedModel replacementModel = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation(resourceLocation, "inventory"));
if (!cobblemon$isSameModel(model, replacementModel)) {
ci.cancel();
render(stack, renderMode, leftHanded, matrices, multiBufferSource, light, overlay, replacementModel);
}
}
}
}
@@ -80,7 +78,6 @@ public abstract class ItemRendererMixin {
boolean canOpenScreen = entity != null && ((entity.getOffhandItem() == stack && !(entity.getMainHandItem().getItem() instanceof PokedexItem)) || entity.getMainHandItem() == stack);
resourceLocation = pokedexItem.getType().getItemModelPath(isScanModel ? "scanning" : (canOpenScreen ? null : "off"));
}
else if (stack.getItem() instanceof WearableItem wearableItem) resourceLocation = wearableItem.getModel3d();
if (resourceLocation != null) {
BakedModel model = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation(resourceLocation, MODEL_PATH));
@@ -15,7 +15,6 @@ import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.Blaze3D;
import net.minecraft.client.Minecraft;
import net.minecraft.client.MouseHandler;
import net.minecraft.client.player.LocalPlayer;
@@ -30,10 +29,9 @@ import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(MouseHandler.class)
public abstract class MouseHandlerMixin {
public class MouseHandlerMixin {
@Shadow private double accumulatedScrollY;
@Shadow @Final private Minecraft minecraft;
@@ -51,14 +49,6 @@ public abstract class MouseHandlerMixin {
@Shadow private double accumulatedDY;
@Shadow private double lastHandleMovementTime;
@Shadow public abstract boolean isMouseGrabbed();
@Shadow protected abstract void turnPlayer(double movementTime);
@Unique private double cobblemon$timeDelta;
@Inject(
method = "onScroll",
at = @At(
@@ -171,21 +161,16 @@ public abstract class MouseHandlerMixin {
return false;
}
@Inject(method = "handleAccumulatedMovement", at = @At("HEAD"))
private void cobblemon$maintainMovementWhenInScreens2(CallbackInfo ci) {
double time = Blaze3D.getTime();
cobblemon$timeDelta = time - this.lastHandleMovementTime;
}
@Inject(method = "handleAccumulatedMovement", at = @At("TAIL"))
private void cobblemon$maintainMovementWhenInScreens(CallbackInfo ci) {
@Inject(method = "handleAccumulatedMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MouseHandler;isMouseGrabbed()Z", ordinal = 0))
private void cobblemon$maintainMovementWhenInScreens(CallbackInfo ci, @Local(ordinal = 1) double e) {
if (minecraft.player == null) return;
if (!(minecraft.player instanceof OrientationControllable controllable)) return;
if (!controllable.getOrientationController().isActive()) return;
if (minecraft.isPaused()) return;
if (isMouseGrabbed()) return;
this.turnPlayer(cobblemon$timeDelta);
var pitch = pitchSmoother.getNewDeltaValue(0, e);
var roll = rollSmoother.getNewDeltaValue(0, e);
controllable.getOrientationController().rotate(0.0F, (float)pitch, (float)roll);
}
@Unique
@@ -0,0 +1,38 @@
/*
* 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.mixin.client;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PlayerModel.class)
public class PlayerModelMixin {
@Inject(method = "setupAnim(Lnet/minecraft/world/entity/LivingEntity;FFFFF)V", at = @At(value = "HEAD"))
private void cobblemon$setHeadRotation(LivingEntity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, CallbackInfo ci) {
if (!(entity instanceof Player)) return;
Entity vehicle = entity.getVehicle();
if (!(vehicle instanceof PokemonEntity pokemonEntity)) return;
var shouldRotatePlayerHead = pokemonEntity.ifRidingAvailableSupply(false, (behaviour, settings, state) -> {
return behaviour.shouldRotatePlayerHead(settings, state, pokemonEntity);
});
if (shouldRotatePlayerHead) return;
netHeadYaw = 0f;
headPitch = 0f;
}
}
@@ -281,6 +281,7 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
// Evolution items
@JvmField val LINK_CABLE = create("link_cable", LinkCableItem())
@JvmField val DRAGON_SCALE = noSettingsItem("dragon_scale")
@JvmField val KINGS_ROCK = noSettingsItem("kings_rock")
@JvmField val METAL_COAT = noSettingsItem("metal_coat")
@JvmField val UPGRADE = noSettingsItem("upgrade")
@JvmField val DUBIOUS_DISC = noSettingsItem("dubious_disc")
@@ -659,19 +660,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val WATER_STONE = noSettingsItem("water_stone")
val wearables = mutableListOf<WearableItem>()
//Wearable items (these items should have a corresponding 3D model)
@JvmField val BLACK_GLASSES = wearableItem("black_glasses")
@JvmField val CHOICE_BAND = wearableItem("choice_band")
@JvmField val CHOICE_SPECS = wearableItem("choice_specs")
@JvmField val EXP_SHARE = wearableItem("exp_share")
@JvmField val FOCUS_BAND = wearableItem("focus_band")
@JvmField val KINGS_ROCK = wearableItem("kings_rock")
@JvmField val MUSCLE_BAND = wearableItem("muscle_band")
@JvmField val ROCKY_HELMET = wearableItem("rocky_helmet")
@JvmField val SAFETY_GOGGLES = wearableItem("safety_goggles")
@JvmField val WISE_GLASSES = wearableItem("wise_glasses")
// Held Items
@JvmField
val ABILITY_SHIELD = heldItem("ability_shield")
@@ -688,6 +676,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val BLACK_BELT = heldItem("black_belt")
@JvmField
val BLACK_GLASSES = heldItem("black_glasses")
@JvmField
val BLACK_SLUDGE = heldItem("black_sludge")
@JvmField
val BLUNDER_POLICY = heldItem("blunder_policy")
@@ -696,8 +686,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val CHARCOAL = heldItem("charcoal_stick", remappedName = "charcoal")
@JvmField
val CHOICE_BAND = heldItem("choice_band")
@JvmField
val CHOICE_SCARF = heldItem("choice_scarf")
@JvmField
val CHOICE_SPECS = heldItem("choice_specs")
@JvmField
val CLEANSE_TAG = heldItem("cleanse_tag")
// @JvmField
// val CLEAR_AMULET = heldItem("clear_amulet")
@@ -718,6 +712,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val EVIOLITE = heldItem("eviolite")
@JvmField
val EXP_SHARE = heldItem("exp_share")
@JvmField
val EXPERT_BELT = heldItem("expert_belt")
@JvmField
val FAIRY_FEATHER = heldItem("fairy_feather")
@@ -726,6 +722,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val FLOAT_STONE = heldItem("float_stone")
@JvmField
val FOCUS_BAND = heldItem("focus_band")
@JvmField
val FOCUS_SASH = heldItem("focus_sash")
@JvmField
val GRASSY_SEED = heldItem("grassy_seed")
@@ -760,6 +758,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val MIRACLE_SEED = heldItem("miracle_seed")
@JvmField
val MUSCLE_BAND = heldItem("muscle_band")
@JvmField
val MYSTIC_WATER = heldItem("mystic_water")
@JvmField
val NEVER_MELT_ICE = heldItem("never_melt_ice")
@@ -790,8 +790,12 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val RING_TARGET = heldItem("ring_target")
@JvmField
val ROCKY_HELMET = heldItem("rocky_helmet")
@JvmField
val ROOM_SERVICE = heldItem("room_service")
@JvmField
val SAFETY_GOGGLES = heldItem("safety_goggles")
@JvmField
val SCOPE_LENS = heldItem("scope_lens")
@JvmField
val SHARP_BEAK = heldItem("sharp_beak")
@@ -828,6 +832,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val WIDE_LENS = heldItem("wide_lens")
@JvmField
val WISE_GLASSES = heldItem("wise_glasses")
@JvmField
val ZOOM_LENS = heldItem("zoom_lens")
@JvmField
val MENTAL_HERB = compostableHeldItem("mental_herb", null, 1F)
@@ -1257,16 +1263,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
return item
}
private fun wearableItem(name: String, heldItemRemappedName: String? = null): CobblemonItem = create(
name,
WearableItem(name).also {
wearables.add(it)
if (heldItemRemappedName != null) {
CobblemonHeldItemManager.registerRemap(it, heldItemRemappedName)
}
}
)
private fun heldItem(name: String, remappedName: String? = null): CobblemonItem = create(
name,
CobblemonItem(Item.Properties()).also {
@@ -20,4 +20,4 @@ interface EntitySideDelegate<T : Entity> {
fun tick(entity: T) {}
fun onSyncedDataUpdated(data: EntityDataAccessor<*>) {}
fun addToStruct(struct: QueryStruct) {}
}
}
@@ -22,5 +22,4 @@ interface PokemonSideDelegate : EntitySideDelegate<PokemonEntity> {
fun handleStatus(status: Byte) {}
fun spawnShinyParticle(player: Player) {}
fun positionRider(passenger: Entity, positionUpdater: MoveFunction)
fun updateAge(age: Int) {}
}
}
@@ -17,11 +17,7 @@ import com.bedrockk.molang.runtime.struct.VariableStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonActivities
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.CobblemonMemories
import com.cobblemon.mod.common.CobblemonUnlockableWallpapers
import com.cobblemon.mod.common.*
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.battles.model.actor.ActorType
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
@@ -31,13 +27,7 @@ import com.cobblemon.mod.common.api.mark.Marks
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
import com.cobblemon.mod.common.api.moves.animations.ActionEffects
import com.cobblemon.mod.common.api.moves.animations.NPCProvider
import com.cobblemon.mod.common.api.pokedex.AbstractPokedexManager
import com.cobblemon.mod.common.api.pokedex.CaughtCount
import com.cobblemon.mod.common.api.pokedex.CaughtPercent
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
import com.cobblemon.mod.common.api.pokedex.PokedexManager
import com.cobblemon.mod.common.api.pokedex.SeenCount
import com.cobblemon.mod.common.api.pokedex.SeenPercent
import com.cobblemon.mod.common.api.pokedex.*
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
import com.cobblemon.mod.common.api.pokemon.stats.Stats
@@ -48,11 +38,12 @@ import com.cobblemon.mod.common.api.storage.party.PartyStore
import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore
import com.cobblemon.mod.common.api.storage.pc.PCPosition
import com.cobblemon.mod.common.api.storage.pc.PCStore
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.battles.BattleRegistry
import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
import com.cobblemon.mod.common.client.particle.BedrockParticleOptionsRepository
import com.cobblemon.mod.common.client.particle.ParticleStorm
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunctions
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.npc.NPCBattleActor
@@ -70,36 +61,9 @@ import com.cobblemon.mod.common.pokemon.Species
import com.cobblemon.mod.common.pokemon.evolution.variants.ItemInteractionEvolution
import com.cobblemon.mod.common.pokemon.evolution.variants.LevelUpEvolution
import com.cobblemon.mod.common.pokemon.evolution.variants.TradeEvolution
import com.cobblemon.mod.common.util.asArrayValue
import com.cobblemon.mod.common.util.asBlockPos
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.asResource
import com.cobblemon.mod.common.util.asUUID
import com.cobblemon.mod.common.util.blockRegistry
import com.cobblemon.mod.common.util.cloneFrom
import com.cobblemon.mod.common.util.effectiveName
import com.cobblemon.mod.common.util.getBattleState
import com.cobblemon.mod.common.util.getBlockStatesWithPos
import com.cobblemon.mod.common.util.getBooleanOrNull
import com.cobblemon.mod.common.util.getDoubleOrNull
import com.cobblemon.mod.common.util.getIntOrNull
import com.cobblemon.mod.common.util.getIsSubmerged
import com.cobblemon.mod.common.util.getOrNull
import com.cobblemon.mod.common.util.getPlayer
import com.cobblemon.mod.common.util.getStringOrNull
import com.cobblemon.mod.common.util.isInBattle
import com.cobblemon.mod.common.util.isInt
import com.cobblemon.mod.common.util.isStandingOn
import com.cobblemon.mod.common.util.party
import com.cobblemon.mod.common.util.pc
import com.cobblemon.mod.common.util.pokedex
import com.cobblemon.mod.common.util.resolve
import com.cobblemon.mod.common.util.server
import com.cobblemon.mod.common.util.toProperties
import com.cobblemon.mod.common.util.withNPCValue
import com.cobblemon.mod.common.util.worldRegistry
import com.cobblemon.mod.common.util.*
import com.mojang.datafixers.util.Either
import net.minecraft.client.multiplayer.ClientLevel
import net.minecraft.commands.arguments.EntityAnchorArgument
import net.minecraft.core.BlockPos
import net.minecraft.core.Holder
@@ -107,11 +71,7 @@ import net.minecraft.core.Registry
import net.minecraft.core.RegistryAccess
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.DoubleTag
import net.minecraft.nbt.ListTag
import net.minecraft.nbt.StringTag
import net.minecraft.nbt.Tag
import net.minecraft.nbt.*
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.MinecraftServer
@@ -120,11 +80,7 @@ import net.minecraft.server.level.ServerPlayer
import net.minecraft.tags.TagKey
import net.minecraft.world.damagesource.DamageSource
import net.minecraft.world.damagesource.DamageTypes
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.EntityType
import net.minecraft.world.entity.LightningBolt
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.*
import net.minecraft.world.entity.ai.behavior.BlockPosTracker
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.MemoryStatus
@@ -139,45 +95,7 @@ import net.minecraft.world.level.dimension.DimensionType
import net.minecraft.world.level.levelgen.Heightmap
import net.minecraft.world.phys.AABB
import net.minecraft.world.phys.Vec3
import java.util.UUID
import kotlin.collections.HashMap
import kotlin.collections.Map
import kotlin.collections.MutableList
import kotlin.collections.MutableSet
import kotlin.collections.any
import kotlin.collections.associate
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.contains
import kotlin.collections.count
import kotlin.collections.emptyList
import kotlin.collections.filter
import kotlin.collections.filterIsInstance
import kotlin.collections.find
import kotlin.collections.flatMap
import kotlin.collections.forEach
import kotlin.collections.forEachIndexed
import kotlin.collections.getOrPut
import kotlin.collections.hashMapOf
import kotlin.collections.isNotEmpty
import kotlin.collections.iterator
import kotlin.collections.listOf
import kotlin.collections.map
import kotlin.collections.mapIndexed
import kotlin.collections.mapNotNull
import kotlin.collections.mapOf
import kotlin.collections.maxOfOrNull
import kotlin.collections.minByOrNull
import kotlin.collections.minOfOrNull
import kotlin.collections.mutableListOf
import kotlin.collections.mutableSetOf
import kotlin.collections.none
import kotlin.collections.random
import kotlin.collections.set
import kotlin.collections.setOf
import kotlin.collections.toList
import kotlin.collections.toMap
import kotlin.collections.toTypedArray
import java.util.*
import kotlin.math.sqrt
import kotlin.random.Random
@@ -371,32 +289,16 @@ object MoLangFunctions {
} as? ServerPlayer
val pos = Vec3(x, y, z)
val packet = SpawnSnowstormParticlePacket(particle, pos)
if (player != null) {
packet.sendToPlayer(player)
if (world !is ClientLevel) {
val packet = SpawnSnowstormParticlePacket(particle, pos)
if (player != null) {
packet.sendToPlayer(player)
} else {
packet.sendToPlayersAround(x, y, z, 64.0, world.dimension())
}
} else {
packet.sendToPlayersAround(x, y, z, 64.0, world.dimension())
}
}
map.put("spawn_pokemon") { params ->
val x = params.getInt(0)
val y = params.getInt(1)
val z = params.getInt(2)
val props = params.getString(3).toProperties()
val pos = BlockPos(x, y, z)
if (!Level.isInSpawnableBounds(pos)) {
return@put DoubleValue.ZERO
}
val pokemon = props.createEntity(world)
pokemon.moveTo(pos, pokemon.yRot, pokemon.xRot)
if (world.addFreshEntity(pokemon)) {
return@put pokemon.struct
} else {
return@put DoubleValue.ZERO
val effect = BedrockParticleOptionsRepository.getEffect(particle) ?: return@put DoubleValue.ZERO
ParticleStorm.createAtPosition(world, effect, pos).spawn()
}
}
map.put("get_entities_around") { params ->
@@ -916,14 +818,9 @@ object MoLangFunctions {
map.put("is_moving") { DoubleValue((pokemonEntity.moveControl as? PokemonMoveControl)?.hasWanted() == true) }
map.put("is_flying") { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
map.put("is_gliding") { DoubleValue(pokemonEntity.useRidingAltPose()) }
map.put("is_ridden") { DoubleValue(pokemonEntity.hasControllingPassenger()) }
map.put("has_aspect") { DoubleValue(it.getString(0) in pokemonEntity.aspects) }
map.put("is_pokemon") { DoubleValue.ONE }
map.put("is_holding_item") { DoubleValue(!pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).let {
it.isEmpty || it.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS) || it.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)
}) }
map.put("is_wearing_hat") { DoubleValue(pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS)) }
map.put("is_wearing_face") { DoubleValue(pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)) }
map.put("is_holding_item") { DoubleValue(!pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).isEmpty) }
map
}
)
@@ -19,4 +19,4 @@ interface Decodable {
*/
fun decode(buffer: RegistryFriendlyByteBuf)
}
}
@@ -25,4 +25,4 @@ interface Encodable {
*/
fun encode(buffer: RegistryFriendlyByteBuf)
}
}
@@ -107,22 +107,4 @@ open class OrientationController(val entity: LivingEntity) {
val roll: Float
get() = Mth.wrapDegrees(-upVector.angleSigned(UP, forwardVector).toDegrees())
fun applyGlobalYaw(deltaYawDegrees: Float) = updateOrientation { original ->
val euler = Vector3f()
original.getEulerAnglesXYZ(euler)
val pitch0 = euler.x
val roll0 = euler.z
val unroll = Matrix3f().rotateZ(-roll0)
val unpitch = Matrix3f().rotateX(-pitch0)
val flattened = Matrix3f(original).mul(unroll).mul(unpitch)
//Flip to reflect current acceptance of what direction is pos for yaw
val globalYaw = Matrix3f().rotationY(-1.0f * deltaYawDegrees.toRadians())
val rePitch = Matrix3f().rotateX(pitch0)
val reRoll = Matrix3f().rotateZ(roll0)
return@updateOrientation Matrix3f(globalYaw).mul(flattened).mul(rePitch).mul(reRoll)
}
}
@@ -41,6 +41,9 @@ class RidingProperties(
}
}
val canRide: Boolean
get() = seats.isNotEmpty() && behaviour != null
fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeMap(
stats,
@@ -50,6 +53,7 @@ class RidingProperties(
buffer.writeCollection(seats) { _, seat -> seat.encode(buffer) }
buffer.writeCollection(conditions) { _, condition -> buffer.writeString(condition.getString()) }
buffer.writeNullable(behaviour) { _, behaviour ->
buffer.writeResourceLocation(behaviour.key)
behaviour.encode(buffer)
}
}
@@ -18,6 +18,5 @@ package com.cobblemon.mod.common.api.riding
enum class RidingStyle {
LAND,
LIQUID,
AIR,
COMPOSITE
}
AIR
}
@@ -8,7 +8,6 @@
package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.resources.ResourceLocation
@@ -28,7 +27,6 @@ import net.minecraft.world.phys.Vec3
*/
interface RidingBehaviour<Settings : RidingBehaviourSettings, State : RidingBehaviourState> {
val key: ResourceLocation
val style: RidingStyle
fun isActive(settings: Settings, state: State, vehicle: PokemonEntity): Boolean
@@ -87,6 +85,6 @@ interface RidingBehaviour<Settings : RidingBehaviourSettings, State : RidingBeha
fun shouldRotatePlayerHead(settings: Settings, state: State, vehicle: PokemonEntity): Boolean
fun createDefaultState(settings: Settings): State
fun createDefaultState(): State
}
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.api.net.Decodable
import com.cobblemon.mod.common.api.net.Encodable
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.phys.Vec3
/**
* Represents static settings of a riding behaviour.
@@ -8,10 +8,15 @@
package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.api.net.Decodable
import com.cobblemon.mod.common.api.net.Encodable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.ifClient
import com.cobblemon.mod.common.util.ifServer
import net.minecraft.client.player.RemotePlayer
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.world.phys.Vec3
import net.minecraft.network.RegistryFriendlyByteBuf
import kotlin.reflect.KProperty
/**
* Represents the state of a Pokemon when being ridden.
@@ -22,38 +27,18 @@ import net.minecraft.world.phys.Vec3
*
* @author landonjw
*/
open class RidingBehaviourState {
open val rideVelocity: SidedRidingState<Vec3> = ridingState(Vec3.ZERO, Side.BOTH)
open val stamina: SidedRidingState<Float> = ridingState(1.0F, Side.BOTH)
open fun reset() {
rideVelocity.set(Vec3.ZERO, true)
stamina.set(1.0F, true)
}
open fun copy(): RidingBehaviourState {
val copy = RidingBehaviourState()
copy.rideVelocity.set(rideVelocity.get(), true)
copy.stamina.set(stamina.get(), true)
return copy
}
open fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous.rideVelocity.get() != rideVelocity.get()) return true
if (previous.stamina.get() != stamina.get()) return true
return false
}
open fun encode(buffer: FriendlyByteBuf) {
buffer.writeVec3(rideVelocity.get())
buffer.writeFloat(stamina.get())
}
open fun decode(buffer: FriendlyByteBuf) {
rideVelocity.set(buffer.readVec3(), true)
stamina.set(buffer.readFloat(), true)
}
interface RidingBehaviourState : Encodable, Decodable {
fun reset()
fun copy(): RidingBehaviourState
fun shouldSync(previous: RidingBehaviourState): Boolean
}
object NoState : RidingBehaviourState {
override fun encode(buffer: RegistryFriendlyByteBuf) = Unit
override fun decode(buffer: RegistryFriendlyByteBuf) = Unit
override fun copy() = NoState
override fun reset() = Unit
override fun shouldSync(previous: RidingBehaviourState) = false
}
fun <T> ridingState(value: T, side: Side) = SidedRidingState(value, side)
@@ -9,32 +9,32 @@
package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.*
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeBehaviour
import net.minecraft.resources.ResourceLocation
object RidingBehaviours {
val behaviours = mutableMapOf<ResourceLocation, RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState>>()
val behaviours = mutableMapOf<ResourceLocation, RidingBehaviour<*, *>>()
init {
register(BirdAirBehaviour.KEY, BirdAirBehaviour())
register(DolphinBehaviour.KEY, DolphinBehaviour())
register(FallToGlideCompositeBehaviour.KEY, FallToGlideCompositeBehaviour())
register(GenericLandBehaviour.KEY, GenericLandBehaviour())
register(GenericSwimBehaviour.KEY, GenericSwimBehaviour())
register(GliderAirBehaviour.KEY, GliderAirBehaviour())
register(HelicopterBehaviour.KEY, HelicopterBehaviour())
register(JetAirBehaviour.KEY, JetAirBehaviour())
register(JumpToFlightCompositeBehaviour.KEY, JumpToFlightCompositeBehaviour())
register(RunToJetCompositeBehaviour.KEY, RunToJetCompositeBehaviour())
register(SwimDashBehaviour.KEY, SwimDashBehaviour())
register(VehicleLandBehaviour.KEY, VehicleLandBehaviour())
register(HoverBehaviour.KEY, HoverBehaviour())
register(CompositeBehaviour.KEY, CompositeBehaviour())
}
fun register(key: ResourceLocation, behaviour: RidingBehaviour<out RidingBehaviourSettings, out RidingBehaviourState>) {
fun register(key: ResourceLocation, behaviour: RidingBehaviour<*, *>) {
if (behaviours.contains(key)) error("Behaviour already registered to key $key")
behaviours[key] = RidingController(behaviour) as RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState>
behaviours[key] = RidingController(behaviour)
}
fun get(key: ResourceLocation): RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState> {
fun get(key: ResourceLocation): RidingBehaviour<*, *> {
if (!behaviours.contains(key)) error("Behaviour not registered to key $key")
return behaviours[key]!!
}
@@ -8,7 +8,6 @@
package com.cobblemon.mod.common.api.riding.behaviour
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
@@ -25,7 +24,6 @@ import net.minecraft.world.phys.Vec3
class RidingController<Settings : RidingBehaviourSettings, State : RidingBehaviourState>(val behaviour: RidingBehaviour<Settings, State>) : RidingBehaviour<Settings, State> {
override val key = behaviour.key
override val style = behaviour.style
override fun isActive(settings: Settings, state: State, vehicle: PokemonEntity) =
behaviour.isActive(settings, state, vehicle)
@@ -41,13 +39,8 @@ class RidingController<Settings : RidingBehaviourSettings, State : RidingBehavio
return behaviour.speed(settings, state, vehicle, driver)
}
override fun clampPassengerRotation(settings: Settings, state: State, vehicle: PokemonEntity, driver: LivingEntity) {
if (!isActive(settings, state, vehicle)) return
return behaviour.clampPassengerRotation(settings, state, vehicle, driver)
}
override fun rotation(settings: Settings, state: State, vehicle: PokemonEntity, driver: LivingEntity): Vec2 {
if (!isActive(settings, state, vehicle)) return driver.rotationVector
if (!isActive(settings, state, vehicle)) return vehicle.rotationVector
return behaviour.rotation(settings, state, vehicle, driver)
}
@@ -171,8 +164,8 @@ class RidingController<Settings : RidingBehaviourSettings, State : RidingBehavio
return behaviour.setRideBar(settings, state, vehicle, driver)
}
override fun createDefaultState(settings: Settings): State {
return behaviour.createDefaultState(settings)
override fun createDefaultState(): State {
return behaviour.createDefaultState()
}
}
@@ -12,14 +12,12 @@ import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
@@ -27,9 +25,6 @@ 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
import org.joml.Matrix3f
import org.joml.Quaternionf
import org.joml.Vector3f
import kotlin.math.*
class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
@@ -38,10 +33,9 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
}
override val key: ResourceLocation = KEY
override val style = RidingStyle.AIR
val poseProvider = PoseProvider<BirdAirSettings, BirdAirState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVelocity.get().z > 0.2 })
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVel.get().z > 0.2 })
override fun isActive(settings: BirdAirSettings, state: BirdAirState, vehicle: PokemonEntity): Boolean {
return true
@@ -57,7 +51,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
vehicle: PokemonEntity,
driver: Player
): Float {
return state.rideVelocity.get().length().toFloat()
return state.rideVel.get().length().toFloat()
}
override fun rotation(
@@ -89,11 +83,11 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
if (controller != null) {
//Need to deadzone this when straight up or down
upForce += -1.0 * sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().z
forwardForce += cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().z
upForce += -1.0 * sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().z
forwardForce += cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().z
upForce += cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().y
forwardForce += sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().y
upForce += cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().y
forwardForce += sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().y
}
@@ -110,7 +104,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
upForce = if (vehicle.y >= altitudeLimit && upForce > 0) 0.0 else upForce
}
val velocity = Vec3(state.rideVelocity.get().x , upForce, forwardForce)
val velocity = Vec3(state.rideVel.get().x , upForce, forwardForce)
return velocity
}
@@ -126,12 +120,12 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
var glideSpeedChange = 0.0
val currSpeed = state.rideVelocity.get().length()
val currSpeed = state.rideVel.get().length()
//Flag for determining if player is actively inputting
var activeInput = false
var newVelocity = Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, state.rideVelocity.get().z)
var newVelocity = Vec3(state.rideVel.get().x, state.rideVel.get().y, state.rideVel.get().z)
//speed up and slow down based on input
if (driver.zza != 0.0f && state.stamina.get() > 0.0) {
@@ -182,26 +176,26 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
}
//Lateral movement based on driver input.
// val latTopSpeed = topSpeed / 2.0
// if (driver.xxa != 0.0f && state.stamina.get() > 0.0) {
// newVelocity = Vec3(
// (newVelocity.x + (accel * driver.xxa)).coerceIn(-latTopSpeed, latTopSpeed),
// newVelocity.y,
// newVelocity.z)
// activeInput = true
// }
// else {
// newVelocity = Vec3(
// lerp(newVelocity.x, 0.0, latTopSpeed / 20.0),
// newVelocity.y,
// newVelocity.z)
// }
val latTopSpeed = topSpeed / 2.0
if (driver.xxa != 0.0f && state.stamina.get() > 0.0) {
newVelocity = Vec3(
(newVelocity.x + (accel * driver.xxa)).coerceIn(-latTopSpeed, latTopSpeed),
newVelocity.y,
newVelocity.z)
activeInput = true
}
else {
newVelocity = Vec3(
lerp(newVelocity.x, 0.0, latTopSpeed / 20.0),
newVelocity.y,
newVelocity.z)
}
//Vertical movement based on driver input.
val vertTopSpeed = topSpeed / 2.0
val vertInput = when {
driver.jumping && state.rideVelocity.get().length() < 0.3 -> 1.0
driver.isShiftKeyDown && state.rideVelocity.get().length() < 0.3 -> -1.0
driver.jumping -> 1.0
driver.isShiftKeyDown -> -1.0
else -> 0.0
}
@@ -228,26 +222,25 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
}
}
//TODO: Reintroduce stamina drain once stats start to be polished and tweaked
// //Only perform stamina logic if the ride does not have infinite stamina
// if (!vehicle.runtime.resolveBoolean(settings.infiniteStamina)) {
// if (activeInput) {
// state.stamina.set(state.stamina.get() - (0.05 / staminaStat).toFloat())
// }
//
// //Lose a base amount of stamina just for being airborne
// state.stamina.set(state.stamina.get() - (0.01 / staminaStat).toFloat())
// }
// else
// {
// state.stamina.set(1.0f)
// }
//Only perform stamina logic if the ride does not have infinite stamina
if (!vehicle.runtime.resolveBoolean(settings.infiniteStamina)) {
if (activeInput) {
state.stamina.set(state.stamina.get() - (0.05 / staminaStat).toFloat())
}
//Lose a base amount of stamina just for being airborne
state.stamina.set(state.stamina.get() - (0.01 / staminaStat).toFloat())
}
else
{
state.stamina.set(1.0f)
}
//air resistance
if( abs(newVelocity.z) > 0) {
newVelocity = newVelocity.subtract(0.0, 0.0, min(0.0015 * newVelocity.z.sign, newVelocity.z))
newVelocity = newVelocity.subtract(0.0, 0.0, min(0.003 * newVelocity.z.sign, newVelocity.z))
}
state.rideVelocity.set(newVelocity)
state.rideVel.set(newVelocity)
}
override fun angRollVel(
@@ -260,17 +253,10 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
if (driver !is OrientationControllable) return Vec3.ZERO
val controller = (driver as OrientationControllable).orientationController
//limit rolling based on handling and current speed.
//modulated by speed so that when flapping idle in air you are ont wobbling around to look around
//TODO: Tie handling into yaw rate
//TODO: Tie into handling
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
//This rotation limit will be used to know if the ride has exceeded it and its needs correcting.
val rotMin = 15.0
val rotLimit = max(handling * sqrt(normalizeVal(state.rideVelocity.get().length(), 0.0, topSpeed)), rotMin)
val rotationChangeRate = 100.0
val rotationChangeRate = 10.0
var yawForce = rotationChangeRate * sin(Math.toRadians(controller.roll.toDouble()))
//for a bit of correction on the rolls limit it to a quarter the amount
@@ -280,28 +266,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
yawForce *= abs(cos(Math.toRadians(controller.pitch.toDouble())))
pitchForce *= abs(cos(Math.toRadians(controller.pitch.toDouble()))) * 1.5
var yawDeltaDeg = deltaTime * rotationChangeRate * sin(Math.toRadians(controller.roll.toDouble())) //sin(Math.toRadians(controller.roll.toDouble())) * abs(cos(Math.toRadians(controller.pitch.toDouble())))
val trueYawDelt = yawDeltaDeg * abs(cos(Math.toRadians(controller.pitch.toDouble())))
//val pitchedYawDelt = yawDeltaDeg - trueYawDelt
controller.applyGlobalYaw(trueYawDelt.toFloat())
val correctionRate = 5.0
//Calculate correcting roll force.
if(abs(controller.roll) > rotLimit) {
state.currRollCorrectionForce.set(
state.currRollCorrectionForce.get() + ((abs(controller.roll) - rotLimit) / 180 - rotLimit) * controller.roll.sign * correctionRate * deltaTime * 0.01
)
} else {
state.currRollCorrectionForce.set(
//reduce rollCorrection gradually and make sure to
//state.currRollCorrectionForce.get() - max(correctionRate * deltaTime * 0.04, abs(state.currRollCorrectionForce.get())) * state.currRollCorrectionForce.get().sign
lerp(state.currRollCorrectionForce.get(), 0.0, deltaTime * 0.98)
)
}
//yaw, pitch, roll
return Vec3(0.0, 0.0, state.currRollCorrectionForce.get())
return Vec3(yawForce, pitchForce, 0.0)
}
override fun rotationOnMouseXY(
@@ -335,14 +300,13 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
//modulated by speed so that when flapping idle in air you are ont wobbling around to look around
val rotMin = 15.0
var rollForce = xInput
val rotLimit = max(handling * sqrt(normalizeVal(state.rideVelocity.get().length(), 0.0, topSpeed)), rotMin)
val rotLimit = max(handling * normalizeVal(state.rideVel.get().length(), 0.0, topSpeed).pow(3), rotMin)
//Limit roll by non linearly decreasing inputs towards
// a rotation limit based on the current distance from
// that rotation limit
if (abs(controller.roll + rollForce) < rotLimit) {
if (sign(rollForce) == sign(controller.roll).toDouble()) {
//Grab how far the current roll is away from the roll limit
val d = abs(abs(controller.roll) - rotLimit)
rollForce *= (d.pow(2)) / (rotLimit.pow(2))
}
@@ -351,18 +315,10 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
}
//Give the ability to yaw with x mouse input when at low speeds.
val yawForce = xInput * ( 1.0 - sqrt(normalizeVal(state.rideVelocity.get().length(), 0.0, topSpeed)))
//Yaw locally a bit when up or down so that its more intuitive to make it out of a dive or a straight vertical
//climb
val yawForcePitched = xInput * sin(Math.toRadians(abs(controller.pitch.toDouble()))) * 0.25
//Apply yaw globally as we don't want roll or pitch changes due to local yaw when looking up or down.
controller.applyGlobalYaw(yawForce.toFloat())
val yawForce = xInput * ( 1.0 - normalizeVal(state.rideVel.get().length(), 0.0, topSpeed).pow(3))
//yaw, pitch, roll
return Vec3(yawForcePitched, yInput, rollForce)
return Vec3(yawForce, yInput, rollForce)
}
/*
@@ -422,7 +378,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
val glideTopSpeed = vehicle.runtime.resolveDouble(settings.glidespeedExpr)
//Must I ensure that topspeed is greater than minimum?
val normalizedGlideSpeed = normalizeVal(state.rideVelocity.get().length(), topSpeed, glideTopSpeed)
val normalizedGlideSpeed = normalizeVal(state.rideVel.get().length(), topSpeed, glideTopSpeed)
//Only ever want the fov change to be a max of 0.2 and for it to have non linear scaling.
return 1.0f + normalizedGlideSpeed.pow(2).toFloat() * 0.2f
@@ -477,7 +433,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
return false
}
override fun createDefaultState(settings: BirdAirSettings) = BirdAirState()
override fun createDefaultState() = BirdAirState()
}
@@ -501,7 +457,6 @@ class BirdAirSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(infiniteAltitude)
buffer.writeExpression(infiniteStamina)
buffer.writeExpression(glidespeedExpr)
@@ -524,44 +479,47 @@ class BirdAirSettings : RidingBehaviourSettings {
}
}
class BirdAirState : RidingBehaviourState() {
class BirdAirState : RidingBehaviourState {
var rideVel = ridingState(Vec3.ZERO, Side.CLIENT)
var stamina = ridingState(1.0f, Side.CLIENT)
var gliding = ridingState(false, Side.CLIENT)
var lastGlide = ridingState(-100L, Side.CLIENT)
var currRollCorrectionForce = ridingState(0.0, Side.CLIENT)
override fun encode(buffer: FriendlyByteBuf) {
super.encode(buffer)
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeVec3(rideVel.get())
buffer.writeFloat(stamina.get())
buffer.writeBoolean(gliding.get())
}
override fun decode(buffer: FriendlyByteBuf) {
super.decode(buffer)
override fun decode(buffer: RegistryFriendlyByteBuf) {
rideVel.set(buffer.readVec3(), forced = true)
stamina.set(buffer.readFloat(), forced = true)
gliding.set(buffer.readBoolean(), forced = true)
}
override fun reset() {
super.reset()
rideVel.set(Vec3.ZERO, forced = true)
stamina.set(1.0f, forced = true)
gliding.set(false, forced = true)
lastGlide.set(-100L, forced = true)
currRollCorrectionForce.set(0.0, forced = true)
}
override fun toString(): String {
return "BirdAirState(rideVelocity=${rideVelocity.get()}, stamina=${stamina.get()}, gliding=${gliding.get()})"
return "BirdAirState(rideVel=${rideVel.get()}, stamina=${stamina.get()}, gliding=${gliding.get()})"
}
override fun copy() = BirdAirState().also {
it.rideVelocity.set(this.rideVelocity.get(), forced = true)
it.rideVel.set(this.rideVel.get(), forced = true)
it.stamina.set(this.stamina.get(), forced = true)
it.gliding.set(this.gliding.get(), forced = true)
it.lastGlide.set(this.lastGlide.get(), forced = true)
it.currRollCorrectionForce.set(this.currRollCorrectionForce.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is BirdAirState) return false
if (previous.gliding.get() != gliding.get()) return true
return super.shouldSync(previous)
if (previous.rideVel != rideVel) return true
if (previous.stamina != stamina) return true
if (previous.gliding != gliding) return true
return false
}
}
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
@@ -19,6 +18,7 @@ import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
@@ -35,7 +35,6 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
}
override val key = KEY
override val style = RidingStyle.LIQUID
val poseProvider = PoseProvider<DolphinSettings, DolphinState>(PoseType.FLOAT)
.with(PoseOption(PoseType.SWIM) { _, _, entity -> entity.entityData.get(PokemonEntity.MOVING) })
@@ -257,7 +256,7 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
return false
}
override fun createDefaultState(settings: DolphinSettings) = DolphinState()
override fun createDefaultState() = DolphinState()
}
@@ -283,7 +282,6 @@ class DolphinSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(canJump)
buffer.writeExpression(jumpVector[0])
buffer.writeExpression(jumpVector[1])
@@ -308,11 +306,13 @@ class DolphinSettings : RidingBehaviourSettings {
}
}
class DolphinState : RidingBehaviourState() {
class DolphinState : RidingBehaviourState {
var lastVelocity = ridingState(Vec3.ZERO, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) = Unit
override fun decode(buffer: RegistryFriendlyByteBuf) = Unit
override fun reset() {
super.reset()
lastVelocity.set(Vec3.ZERO, forced = true)
}
@@ -321,8 +321,8 @@ class DolphinState : RidingBehaviourState() {
}
override fun copy() = DolphinState().also {
it.stamina.set(stamina.get(), forced = true)
it.rideVelocity.set(rideVelocity.get(), forced = true)
it.lastVelocity.set(lastVelocity.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState) = false
}
@@ -0,0 +1,434 @@
/*
* 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.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.riding.behaviour.*
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.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
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 FallToGlideCompositeBehaviour : RidingBehaviour<FallToGlideCompositeSettings, FallToGlideCompositeState> {
companion object {
val KEY = cobblemonResource("composite/fall_to_glide")
}
override val key = KEY
val landBehaviour: GenericLandBehaviour = GenericLandBehaviour()
val glideBehaviour: GliderAirBehaviour = GliderAirBehaviour()
override fun tick(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
val shouldBeFlying = checkShouldBeFlying(settings, vehicle, state.activeController.get() == GliderAirBehaviour.KEY)
if (state.activeController.get() == GliderAirBehaviour.KEY && !shouldBeFlying) { // && entity.onGround() && state.timeTransitioned + 20 < entity.level().gameTime) {
state.activeController.set(GenericLandBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, false)
} else if (state.activeController.get() == GenericLandBehaviour.KEY && shouldBeFlying) {
state.activeController.set(GliderAirBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, true)
}
}
private fun checkShouldBeFlying(
settings: FallToGlideCompositeSettings,
vehicle: PokemonEntity,
isFlyingAlready: Boolean
): Boolean {
val runtime = vehicle.runtime
val minFallingSpeed = runtime.resolveFloat(settings.minimumFallSpeed)
val minForwardSpeed = runtime.resolveFloat(settings.minimumForwardSpeed)
val grounded = vehicle.onGround()
return if (isFlyingAlready) {
!grounded
} else {
vehicle.deltaMovement.y <= -minFallingSpeed && vehicle.deltaMovement.horizontalDistance() >= minForwardSpeed
}
}
override fun isActive(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return true
}
override fun pose(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): PoseType {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.pose(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.pose(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun speed(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.speed(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.speed(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotation(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotation(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.rotation(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun velocity(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.velocity(settings.land, state.landState, vehicle, driver, input)
GliderAirBehaviour.KEY -> glideBehaviour.velocity(settings.glide, NoState, vehicle, driver, input)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun angRollVel(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.angRollVel(
settings.land,
state.landState,
vehicle,
driver,
deltaTime
)
GliderAirBehaviour.KEY -> glideBehaviour.angRollVel(settings.glide, NoState, vehicle, driver, deltaTime)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotationOnMouseXY(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
mouseX: Double,
mouseYSmoother: SmoothDouble,
mouseXSmoother: SmoothDouble,
sensitivity: Double,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotationOnMouseXY(
settings.land,
state.landState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
GliderAirBehaviour.KEY -> glideBehaviour.rotationOnMouseXY(
settings.glide,
NoState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun canJump(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.canJump(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.canJump(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun setRideBar(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.setRideBar(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.setRideBar(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun jumpForce(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.jumpForce(
settings.land,
state.landState,
vehicle,
driver,
jumpStrength
)
GliderAirBehaviour.KEY -> glideBehaviour.jumpForce(settings.glide, NoState, vehicle, driver, jumpStrength)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun gravity(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.gravity(settings.land, state.landState, vehicle, regularGravity)
GliderAirBehaviour.KEY -> glideBehaviour.gravity(settings.glide, NoState, vehicle, regularGravity)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rideFovMultiplier(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rideFovMultiplier(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.rideFovMultiplier(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useAngVelSmoothing(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useAngVelSmoothing(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.useAngVelSmoothing(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useRidingAltPose(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useRidingAltPose(settings.land, state.landState, vehicle, driver)
GliderAirBehaviour.KEY -> glideBehaviour.useRidingAltPose(settings.glide, NoState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun inertia(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.inertia(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.inertia(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRoll(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRoll(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.shouldRoll(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun turnOffOnGround(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.turnOffOnGround(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.turnOffOnGround(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun dismountOnShift(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.dismountOnShift(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.dismountOnShift(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePokemonHead(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePokemonHead(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.shouldRotatePokemonHead(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePlayerHead(
settings: FallToGlideCompositeSettings,
state: FallToGlideCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePlayerHead(settings.land, state.landState, vehicle)
GliderAirBehaviour.KEY -> glideBehaviour.shouldRotatePlayerHead(settings.glide, NoState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun createDefaultState() = FallToGlideCompositeState()
}
class FallToGlideCompositeSettings : RidingBehaviourSettings {
override val key = FallToGlideCompositeBehaviour.KEY
var glide: GliderAirSettings = GliderAirSettings()
private set
var land: GenericLandSettings = GenericLandSettings()
private set
var minimumForwardSpeed: Expression = "0.0".asExpression()
private set
var minimumFallSpeed: Expression = "0.5".asExpression()
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
glide.encode(buffer)
land.encode(buffer)
buffer.writeExpression(minimumForwardSpeed)
buffer.writeExpression(minimumFallSpeed)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
glide.decode(buffer)
land.decode(buffer)
minimumForwardSpeed = buffer.readExpression()
minimumFallSpeed = buffer.readExpression()
}
}
class FallToGlideCompositeState : RidingBehaviourState {
var activeController = ridingState(GenericLandBehaviour.KEY, Side.CLIENT)
var landState: GenericLandState = GenericLandState()
var timeTransitioned = ridingState(-100L, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(activeController.get())
landState.encode(buffer)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
activeController.set(buffer.readResourceLocation(), forced = true)
landState.decode(buffer)
}
override fun reset() {
activeController.set(GenericLandBehaviour.KEY, forced = true)
landState.reset()
timeTransitioned.set(-100L, forced = true)
}
override fun toString(): String {
return "FallToGlideCompositeState(activeController=$activeController, landState=$landState, timeTransitioned=$timeTransitioned)"
}
override fun copy() = FallToGlideCompositeState().also {
it.activeController.set(activeController.get(), forced = true)
it.landState = landState.copy()
it.timeTransitioned.set(timeTransitioned.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is FallToGlideCompositeState) return false
if (activeController != previous.activeController) return true
if (landState.shouldSync(previous.landState)) return true
return false
}
}
@@ -9,8 +9,7 @@
package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
@@ -18,14 +17,15 @@ import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.util.Mth
import net.minecraft.util.SmoothDouble
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
import net.minecraft.world.phys.shapes.Shapes
import kotlin.math.*
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow
class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandState> {
companion object {
@@ -33,11 +33,10 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
}
override val key = KEY
override val style = RidingStyle.LAND
val poseProvider = PoseProvider<GenericLandSettings, GenericLandState>(PoseType.STAND)
.with(PoseOption(PoseType.WALK) { _, state, _ ->
return@PoseOption abs(state.rideVelocity.get().z) > 0.2
return@PoseOption state.rideVel.get().z > 0.1
})
override fun isActive(
@@ -73,102 +72,18 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
vehicle: PokemonEntity,
driver: Player
): Float {
return state.rideVelocity.get().length().toFloat()
return state.rideVel.get().length().toFloat()
}
override fun updatePassengerRotation(
settings: GenericLandSettings,
state: GenericLandState,
vehicle: PokemonEntity,
driver: LivingEntity
) {
//Take the inverse so that it cancels out how
//much the entity rotates.
val turnAmount = calcRotAmount(settings, state, vehicle, driver)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val maxYawDiff = 90.0f
//Normalize the current rotation diff
val rotMod = Mth.wrapDegrees(driver.yRot - vehicle.yRot) / maxYawDiff
val rotAmount = 10.0f
//Take the inverse so that you turn more at higher speeds
val normSpeed = 1.0f - 0.5f*normalizeVal(state.rideVelocity.get().length(), 0.0, topSpeed).toFloat()
//driver.yRot += (entity.riding.deltaRotation.y - turnAmount)
//driver.setYHeadRot(driver.yHeadRot + (entity.riding.deltaRotation.y) - turnAmount)
}
override fun clampPassengerRotation(
settings: GenericLandSettings,
state: GenericLandState,
vehicle: PokemonEntity,
driver: LivingEntity
) {
val f = Mth.wrapDegrees(driver.yRot - vehicle.yRot)
val lookYawLimit = 90.0f
val g = Mth.clamp(f, -lookYawLimit, lookYawLimit)
driver.yRotO += g - f
driver.yRot = driver.yRot + g - f
driver.setYHeadRot(driver.yRot)
}
override fun rotation(
settings: GenericLandSettings,
state: GenericLandState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
val turnAmount = calcRotAmount(settings, state, vehicle, driver)
return Vec2(vehicle.xRot, vehicle.yRot + turnAmount )
return Vec2(driver.xRot * 0.5f, driver.yRot)
}
/*
* Calculates the rotation amount given the difference between
* the current player y rot and entity y rot. This gives the
* affect of influencing a rides rotation through the mouse
* without it being instant.
*/
fun calcRotAmount(
settings: GenericLandSettings,
state: GenericLandState,
vehicle: PokemonEntity,
driver: LivingEntity
): Float {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
//In degrees per second
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val maxYawDiff = 90.0f
//Normalize the current rotation diff
val rotDiff = Mth.wrapDegrees(driver.yRot - vehicle.yRot)
val rotDiffNorm = rotDiff / maxYawDiff
//Take the square root so that the ride levels out quicker when at lower differences between entity
//y and driver y
//This influences the speed of the turn based on how far in one direction you're looking
val rotDiffMod = (sqrt(abs(rotDiffNorm)) * rotDiffNorm.sign)
//Take the inverse so that you turn less at higher speeds
val normSpeed = 1.0f // = 1.0f - 0.5f*normalizeVal(state.rideVelocityocity.length(), 0.0, topSpeed).toFloat()
// TODO: This needs to be tweaked with in game results and testing
val turnRate = (handling.toFloat() / 20.0f) * 2
//Ensure you only ever rotate as much difference as there is between the angles.
val turnSpeed = turnRate * rotDiffMod * normSpeed
val rotAmount = turnSpeed.coerceIn(-abs(rotDiff), abs(rotDiff))
return rotAmount
}
override fun velocity(
settings: GenericLandSettings,
state: GenericLandState,
@@ -176,16 +91,24 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
driver: Player,
input: Vec3
): Vec3 {
//Limit horizontal velocity that may have accumulated through alternate behaviour
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val currVel = state.rideVelocity.get()
// state.rideVelocity.set(Vec3(
// max(currVel.x, topSpeed),
// currVel.y,
// max(currVel.z, topSpeed)
// ))
val runtime = vehicle.runtime
val driveFactor = runtime.resolveFloat(settings.driveFactor)
val strafeFactor = runtime.resolveFloat(settings.strafeFactor)
val f = driver.xxa * strafeFactor
var g = driver.zza * driveFactor
if (g <= 0.0f) {
g *= runtime.resolveFloat(settings.reverseDriveFactor)
}
val gravity = -1.0
state.rideVelocity.set(calculateRideSpaceVel(settings, state, vehicle, driver))
val newVelocity = calculateRideSpaceVel(settings, state, vehicle, driver)
//Jump the thang!
if (driver.jumping && vehicle.onGround()) {
state.rideVel.set(Vec3(newVelocity.x, 2.0, newVelocity.z))
} else {
state.rideVel.set(newVelocity)
}
//This is cheap.
//Also make it stop quicker the slower it is.
@@ -195,7 +118,7 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
//entity.deltaMovement = entity.deltaMovement.lerp(velocity, 1.0)
//state.currVel = state.currVel.add( f.toDouble() / 20.0, gravity / 20.0 , g.toDouble() / 20.0)
return state.rideVelocity.get()
return state.rideVel.get()
}
private fun calculateRideSpaceVel(
@@ -204,59 +127,35 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
vehicle: PokemonEntity,
driver: Player
): Vec3 {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr)
val speed = state.rideVelocity.get().length()
val topSpeed = vehicle.runtime.resolveDouble(settings.topSpeedExpr)
val accel = vehicle.runtime.resolveDouble(settings.accelExpr)
val speed = state.rideVel.get().length()
//Flag for determining if player is actively inputting
var activeInput = false
var newVelocity = Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, state.rideVelocity.get().z)
val minSpeed = 0.0
var newVelocity = Vec3(state.rideVel.get().x, state.rideVel.get().y, state.rideVel.get().z)
//speed up and slow down based on input
if (driver.zza != 0.0f && state.stamina.get() > 0.0) {
//make sure it can't exceed top speed
val forwardInput = when {
driver.zza > 0 && newVelocity.z > topSpeed -> 0.0
driver.zza < 0 && newVelocity.z < (-topSpeed / 3.0) -> 0.0
else -> driver.zza.sign
}
if (driver.zza > 0.0 && speed <= topSpeed && state.stamina.get() > 0.0f) {
//modify acceleration to be slower when at closer speeds to top speed
val accelMod = max((normalizeSpeed(speed, minSpeed, topSpeed) - 1).pow(2), 0.1)
newVelocity = Vec3(newVelocity.x, newVelocity.y, min(newVelocity.z + (accel * accelMod), topSpeed))
} else if (driver.zza >= 0.0 && state.stamina.get() == 0.0f || speed > topSpeed) {
newVelocity = Vec3(newVelocity.x, newVelocity.y, max(newVelocity.z - ((accel) / 4), minSpeed))
} else if (driver.zza < 0.0 && speed > minSpeed) {
//modify deccel to be slower when at closer speeds to minimum speed
val deccelMod = max(-(normalizeSpeed(speed, minSpeed, topSpeed)) + 1, 0.0)
newVelocity = Vec3(
newVelocity.x,
newVelocity.y,
(newVelocity.z + (accel * forwardInput.toDouble())))
activeInput = true
//Decelerate currently always a constant half of max acceleration.
newVelocity =
Vec3(newVelocity.x, newVelocity.y, max(newVelocity.z - ((accel * deccelMod) / 2), minSpeed))
}
//Gravity logic
if (vehicle.onGround()) {
newVelocity = Vec3(newVelocity.x, 0.0, newVelocity.z)
} else {
val gravity = (9.8 / ( 20.0)) * 0.2
val terminalVel = 2.0
val fallingForce = gravity - ( newVelocity.z.sign *gravity *(abs(newVelocity.z) / 2.0))
newVelocity = Vec3(newVelocity.x, max(newVelocity.y - fallingForce, -terminalVel), newVelocity.z)
newVelocity = Vec3(newVelocity.x, max(newVelocity.y - 0.2, -1.0), newVelocity.z)
}
//ground Friction
if( abs(newVelocity.z) > 0 && vehicle.onGround() && !activeInput) {
newVelocity = newVelocity.subtract(0.0, 0.0, min(0.03 * newVelocity.z.sign, newVelocity.z))
}
//Jump the thang!
if (driver.jumping && vehicle.onGround()) {
val jumpVel = 1.0
newVelocity = newVelocity.add(0.0, 1.0, 0.0)
//Ensure this doesn't add unwanted forward velocity
val mag = if(newVelocity.length() < topSpeed) newVelocity.length() else topSpeed
newVelocity = newVelocity.normalize().scale(mag)
}
return newVelocity
}
@@ -264,7 +163,7 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
* Normalizes the current speed between minSpeed and maxSpeed.
* The result is clamped between 0.0 and 1.0, where 0.0 represents minSpeed and 1.0 represents maxSpeed.
*/
private fun normalizeVal(currSpeed: Double, minSpeed: Double, maxSpeed: Double): Double {
private fun normalizeSpeed(currSpeed: Double, minSpeed: Double, maxSpeed: Double): Double {
require(maxSpeed > minSpeed) { "maxSpeed must be greater than minSpeed" }
return ((currSpeed - minSpeed) / (maxSpeed - minSpeed)).coerceIn(0.0, 1.0)
}
@@ -316,6 +215,8 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
driver: Player
): Float {
//Retrieve stamina from state and tick up at a rate of 0.1 a second
val staminaGain = (1.0 / 20.0) * 0.1
state.stamina.set(min(state.stamina.get() + staminaGain, 1.0).toFloat())
return (state.stamina.get() / 1.0f)
}
@@ -326,7 +227,10 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
driver: Player,
jumpStrength: Int
): Vec3 {
return Vec3.ZERO
val runtime = vehicle.runtime
runtime.environment.query.addFunction("jump_strength") { DoubleValue(jumpStrength.toDouble()) }
val jumpVector = settings.jumpVector.map { runtime.resolveFloat(it) }
return Vec3(jumpVector[0].toDouble(), jumpVector[1].toDouble(), jumpVector[2].toDouble())
}
override fun gravity(
@@ -412,21 +316,30 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
return false
}
override fun createDefaultState(settings: GenericLandSettings) = GenericLandState()
override fun createDefaultState() = GenericLandState()
}
class GenericLandSettings : RidingBehaviourSettings {
override val key = GenericLandBehaviour.KEY
var canJump = "true".asExpression()
var driveFactor = "1.0".asExpression()
private set
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'LAND', 1.0, 0.3)".asExpression()
var strafeFactor = "0.2".asExpression()
private set
var reverseDriveFactor = "0.25".asExpression()
private set
var topSpeedExpr: Expression = "q.get_ride_stats('SPEED', 'LAND', 1.0, 0.3)".asExpression()
private set
// Max accel is a whole 1.0 in 1 second. The conversion in the function below is to convert seconds to ticks
var accelerationExpr: Expression =
"q.get_ride_stats('ACCELERATION', 'LAND', (1.0 / (20.0 * 1.5)), (1.0 / (20.0 * 5.0)))".asExpression()
var accelExpr: Expression =
"q.get_ride_stats('ACCELERATION', 'LAND', (1.0 / (20.0 * 0.5)), (1.0 / (20.0 * 5.0)))".asExpression()
private set
var jumpVector = listOf("0".asExpression(), "0.3".asExpression(), "0".asExpression())
private set
// Between 30 seconds and 10 seconds at the lowest when at full speed.
@@ -441,17 +354,30 @@ class GenericLandSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(speedExpr)
buffer.writeExpression(accelerationExpr)
buffer.writeExpression(driveFactor)
buffer.writeExpression(strafeFactor)
buffer.writeExpression(reverseDriveFactor)
buffer.writeExpression(topSpeedExpr)
buffer.writeExpression(accelExpr)
buffer.writeExpression(jumpVector[0])
buffer.writeExpression(jumpVector[1])
buffer.writeExpression(jumpVector[2])
buffer.writeExpression(staminaExpr)
buffer.writeExpression(jumpExpr)
buffer.writeExpression(handlingExpr)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
speedExpr = buffer.readExpression()
accelerationExpr = buffer.readExpression()
driveFactor = buffer.readExpression()
strafeFactor = buffer.readExpression()
reverseDriveFactor = buffer.readExpression()
topSpeedExpr = buffer.readExpression()
accelExpr = buffer.readExpression()
jumpVector = listOf(
buffer.readExpression(),
buffer.readExpression(),
buffer.readExpression()
)
staminaExpr = buffer.readExpression()
jumpExpr = buffer.readExpression()
handlingExpr = buffer.readExpression()
@@ -459,16 +385,41 @@ class GenericLandSettings : RidingBehaviourSettings {
}
class GenericLandState : RidingBehaviourState() {
class GenericLandState : RidingBehaviourState {
var rideVel = ridingState(Vec3.ZERO, Side.CLIENT)
var stamina = ridingState(1.0f, Side.CLIENT)
var currSpeed = ridingState(0.0, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeVec3(rideVel.get())
buffer.writeFloat(stamina.get())
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
rideVel.set(buffer.readVec3(), forced = true)
stamina.set(buffer.readFloat(), forced = true)
}
override fun reset() {
rideVel.set(Vec3.ZERO, forced = true)
stamina.set(1.0f, forced = true)
currSpeed.set(0.0, forced = true)
}
override fun toString(): String {
return "GenericLandState(rideVel=${rideVel.get()}, stamina=${stamina.get()}, currSpeed=${currSpeed.get()})"
}
override fun copy() = GenericLandState().also {
it.rideVelocity.set(this.rideVelocity.get(), forced = true)
it.rideVel.set(this.rideVel.get(), forced = true)
it.stamina.set(this.stamina.get(), forced = true)
it.currSpeed.set(this.currSpeed.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is GenericLandState) return false
return super.shouldSync(previous)
if (rideVel != previous.rideVel) return true
if (stamina != previous.stamina) return true
return false
}
}
@@ -11,8 +11,7 @@ package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.NoState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.posing.PoseOption
@@ -29,18 +28,17 @@ import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviourState> {
class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
companion object {
val KEY = cobblemonResource("swim/generic")
}
override val key = KEY
override val style = RidingStyle.LIQUID
val poseProvider = PoseProvider<GenericSwimSettings, RidingBehaviourState>(PoseType.FLOAT)
val poseProvider = PoseProvider<GenericSwimSettings, NoState>(PoseType.FLOAT)
.with(PoseOption(PoseType.SWIM) { _, _, entity -> entity.isSwimming && entity.entityData.get(PokemonEntity.MOVING) })
override fun isActive(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun isActive(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return Shapes.create(vehicle.boundingBox).blockPositionsAsListRounded().any {
if (vehicle.isInWater || vehicle.isUnderWater) {
return@any true
@@ -50,17 +48,17 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviou
}
}
override fun pose(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): PoseType {
override fun pose(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): PoseType {
return poseProvider.select(settings, state, vehicle)
}
override fun speed(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Float {
override fun speed(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Float {
return vehicle.runtime.resolveFloat(settings.speed)
}
override fun rotation(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
@@ -69,7 +67,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviou
override fun velocity(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
@@ -90,7 +88,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviou
override fun angRollVel(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
@@ -100,7 +98,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviou
override fun rotationOnMouseXY(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
@@ -120,7 +118,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviou
override fun canJump(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
@@ -129,7 +127,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviou
override fun setRideBar(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player
): Float {
@@ -138,7 +136,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviou
override fun jumpForce(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
@@ -151,7 +149,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviou
override fun gravity(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
@@ -160,45 +158,45 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviou
override fun rideFovMultiplier(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun useAngVelSmoothing(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun useRidingAltPose(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun inertia(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Double {
override fun inertia(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Double {
return 0.5
}
override fun shouldRoll(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun shouldRoll(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun turnOffOnGround(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun turnOffOnGround(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun dismountOnShift(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun dismountOnShift(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePokemonHead(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity
): Boolean {
return false
@@ -206,13 +204,13 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviou
override fun shouldRotatePlayerHead(
settings: GenericSwimSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun createDefaultState(settings: GenericSwimSettings) = RidingBehaviourState()
override fun createDefaultState() = NoState
}
@@ -238,7 +236,6 @@ class GenericSwimSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(canJump)
buffer.writeExpression(jumpVector[0])
buffer.writeExpression(jumpVector[1])
@@ -12,7 +12,7 @@ import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.NoState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.posing.PoseOption
@@ -29,32 +29,31 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, RidingBehaviourState> {
class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
companion object {
val KEY = cobblemonResource("air/glider")
}
override val key = KEY
override val style = RidingStyle.AIR
val poseProvider = PoseProvider<GliderAirSettings, RidingBehaviourState>(PoseType.HOVER)
val poseProvider = PoseProvider<GliderAirSettings, NoState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, _, entity -> entity.entityData.get(PokemonEntity.MOVING) })
override fun isActive(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun isActive(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return true
}
override fun pose(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): PoseType {
override fun pose(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): PoseType {
return poseProvider.select(settings, state, vehicle)
}
override fun speed(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Float {
override fun speed(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Float {
return vehicle.runtime.resolveFloat(settings.speed)
}
override fun rotation(
settings: GliderAirSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
@@ -63,7 +62,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, RidingBehaviourSta
override fun velocity(
settings: GliderAirSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
@@ -78,7 +77,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, RidingBehaviourSta
override fun angRollVel(
settings: GliderAirSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
@@ -88,7 +87,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, RidingBehaviourSta
override fun rotationOnMouseXY(
settings: GliderAirSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
@@ -106,13 +105,13 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, RidingBehaviourSta
return Vec3(0.0, mouseY * invertPitch, mouseX * invertRoll)
}
override fun canJump(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Boolean {
override fun canJump(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Boolean {
return false
}
override fun setRideBar(
settings: GliderAirSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player
): Float {
@@ -121,7 +120,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, RidingBehaviourSta
override fun jumpForce(
settings: GliderAirSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
@@ -131,7 +130,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, RidingBehaviourSta
override fun gravity(
settings: GliderAirSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
@@ -140,51 +139,51 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, RidingBehaviourSta
override fun rideFovMultiplier(
settings: GliderAirSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun useAngVelSmoothing(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun useRidingAltPose(
settings: GliderAirSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun inertia(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Double {
override fun inertia(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Double {
return 0.5
}
override fun shouldRoll(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun shouldRoll(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun turnOffOnGround(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun turnOffOnGround(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun dismountOnShift(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun dismountOnShift(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePokemonHead(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun shouldRotatePokemonHead(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePlayerHead(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun shouldRotatePlayerHead(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun createDefaultState(settings: GliderAirSettings) = RidingBehaviourState()
override fun createDefaultState() = NoState
}
class GliderAirSettings : RidingBehaviourSettings {
@@ -200,7 +199,6 @@ class GliderAirSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(glideSpeed)
buffer.writeExpression(speed)
buffer.writeExpression(canStrafe)
@@ -11,8 +11,7 @@ package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.NoState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.posing.PoseOption
@@ -32,19 +31,18 @@ import kotlin.math.abs
import kotlin.math.pow
import kotlin.math.sin
class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourState> {
class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
companion object {
val KEY = cobblemonResource("air/helicopter")
val ROTATION_LIMIT = 30.0f
}
override val key = KEY
override val style = RidingStyle.AIR
val poseProvider = PoseProvider<HelicopterSettings, RidingBehaviourState>(PoseType.HOVER)
val poseProvider = PoseProvider<HelicopterSettings, NoState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, _, entity -> entity.entityData.get(PokemonEntity.MOVING) })
override fun isActive(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun isActive(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
//If there are only fluid blocks or air block below the ride
//then activate the controller. If it is in water the ride will
//dismount accordingly
@@ -58,11 +56,11 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
}
}
override fun pose(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): PoseType {
override fun pose(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): PoseType {
return poseProvider.select(settings, state, vehicle)
}
override fun speed(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Float {
override fun speed(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Float {
//Increased max speed to exaggerate movement.
//This likely just needs to be a static number if it really is just
//the scalar for the velocity vector
@@ -71,7 +69,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
override fun rotation(
settings: HelicopterSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
@@ -80,7 +78,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
override fun velocity(
settings: HelicopterSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
@@ -109,7 +107,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
override fun angRollVel(
settings: HelicopterSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
@@ -164,7 +162,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
override fun rotationOnMouseXY(
settings: HelicopterSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
@@ -184,7 +182,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
override fun canJump(
settings: HelicopterSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
@@ -193,7 +191,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
override fun setRideBar(
settings: HelicopterSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player
): Float {
@@ -202,7 +200,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
override fun jumpForce(
settings: HelicopterSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
@@ -212,7 +210,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
override fun gravity(
settings: HelicopterSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
@@ -221,55 +219,55 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourS
override fun rideFovMultiplier(
settings: HelicopterSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun useAngVelSmoothing(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return true
}
override fun useRidingAltPose(
settings: HelicopterSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun inertia(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Double {
override fun inertia(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Double {
return 0.1
}
override fun shouldRoll(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun shouldRoll(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return true
}
override fun turnOffOnGround(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun turnOffOnGround(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun dismountOnShift(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun dismountOnShift(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePokemonHead(
settings: HelicopterSettings,
state: RidingBehaviourState,
state: NoState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun shouldRotatePlayerHead(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
override fun shouldRotatePlayerHead(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
return false
}
override fun createDefaultState(settings: HelicopterSettings) = RidingBehaviourState()
override fun createDefaultState() = NoState
}
@@ -289,7 +287,6 @@ class HelicopterSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(gravity)
buffer.writeExpression(horizontalAcceleration)
buffer.writeExpression(verticalVelocity)
@@ -1,479 +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.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.MoLangMath.lerp
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.util.Mth
import net.minecraft.util.SmoothDouble
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
import net.minecraft.world.phys.shapes.Shapes
import kotlin.math.*
class HoverBehaviour : RidingBehaviour<HoverSettings, HoverState> {
companion object {
val KEY = cobblemonResource("air/hover")
}
override val key = KEY
override val style = RidingStyle.AIR
val poseProvider = PoseProvider<HoverSettings, HoverState>(PoseType.STAND)
.with(PoseOption(PoseType.WALK) { _, state, _ ->
return@PoseOption abs(state.rideVelocity.get().z) > 0.2
})
override fun isActive(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return Shapes.create(vehicle.boundingBox).blockPositionsAsListRounded().any {
//Need to check other fluids
if (vehicle.isInWater || vehicle.isUnderWater) {
return@any false
}
//This might not actually work, depending on what the yPos actually is. yPos of the middle of the entity? the feet?
if (it.y.toDouble() == (vehicle.position().y)) {
val blockState = vehicle.level().getBlockState(it.below())
return@any !blockState.isAir && blockState.fluidState.isEmpty
}
true
}
}
override fun pose(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): PoseType {
return this.poseProvider.select(settings, state, vehicle)
}
override fun speed(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Float {
return state.rideVelocity.get().length().toFloat()
}
override fun updatePassengerRotation(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: LivingEntity
) {
//Take the inverse so that it cancels out how
//much the entity rotates.
val turnAmount = calcRotAmount(settings, state, vehicle, driver)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val maxYawDiff = 90.0f
//Normalize the current rotation diff
val rotMod = Mth.wrapDegrees(driver.yRot - vehicle.yRot) / maxYawDiff
val rotAmount = 10.0f
//Take the inverse so that you turn more at higher speeds
val normSpeed = 1.0f - 0.5f*normalizeVal(state.rideVelocity.get().length(), 0.0, topSpeed).toFloat()
//driver.yRot += (entity.riding.deltaRotation.y - turnAmount)
//driver.setYHeadRot(driver.yHeadRot + (entity.riding.deltaRotation.y) - turnAmount)
}
override fun clampPassengerRotation(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: LivingEntity
) {
val f = Mth.wrapDegrees(driver.yRot - vehicle.yRot)
val lookYawLimit = 90.0f
val g = Mth.clamp(f, -lookYawLimit, lookYawLimit)
driver.yRotO += g - f
driver.yRot = driver.yRot + g - f
driver.setYHeadRot(driver.yRot)
}
override fun rotation(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
val turnAmount = calcRotAmount(settings, state, vehicle, driver)
return Vec2(driver.xRot, vehicle.yRot + turnAmount )
}
/*
* Calculates the rotation amount given the difference between
* the current player y rot and entity y rot. This gives the
* affect of influencing a rides rotation through the mouse
* without it being instant.
*/
fun calcRotAmount(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: LivingEntity
): Float {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
//In degrees per second
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val maxYawDiff = 90.0f
//Normalize the current rotation diff
val rotDiff = Mth.wrapDegrees(driver.yRot - vehicle.yRot)
val rotDiffNorm = rotDiff / maxYawDiff
//Take the square root so that the ride levels out quicker when at lower differences between entity
//y and driver y
//This influences the speed of the turn based on how far in one direction you're looking
val rotDiffMod = (sqrt(abs(rotDiffNorm)) * rotDiffNorm.sign)
//Take the inverse so that you turn less at higher speeds
val normSpeed = 1.0f // = 1.0f - 0.5f*normalizeVal(state.rideVelocityocity.length(), 0.0, topSpeed).toFloat()
// TODO: This needs to be tweaked with in game results and testing
val turnRate = (handling.toFloat() / 20.0f) * 2
//Ensure you only ever rotate as much difference as there is between the angles.
val turnSpeed = turnRate * rotDiffMod * normSpeed
val rotAmount = turnSpeed.coerceIn(-abs(rotDiff), abs(rotDiff))
return rotAmount
}
override fun velocity(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
val strafeFactor = 0.2
val f = driver.xxa * strafeFactor
var g = driver.zza
if (g <= 0.0f) {
g *= -1.0f
}
return calculateRideSpaceVel(settings, state, vehicle, driver).scale(10.0)
}
private fun calculateRideSpaceVel(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Vec3 {
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr)
val speed = state.rideVelocity.get().length()
//Flag for determining if player is actively inputting
var activeInput = false
val minSpeed = 0.0
var newVelocity = Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, state.rideVelocity.get().z)
var jumpVec = Vec3.ZERO
//speed up and slow down based on input
if (driver.zza != 0.0f && state.stamina.get() > 0.0) {
//make sure it can't exceed top speed
val forwardInput = when {
driver.zza > 0 && newVelocity.z > topSpeed -> 0.0
driver.zza < 0 && newVelocity.z < (-topSpeed / 3.0) -> 0.0
else -> driver.zza.sign
}
newVelocity = Vec3(
newVelocity.x,
newVelocity.y,
(newVelocity.z + (accel * forwardInput.toDouble())))
activeInput = true
jumpVec = jumpVec.add(0.0, 0.0, forwardInput.toDouble())
}
//speed up and slow down based on input
if (driver.xxa != 0.0f && state.stamina.get() > 0.0) {
//make sure it can't exceed top speed
val forwardInput = when {
driver.xxa > 0 && newVelocity.x > topSpeed -> 0.0
driver.xxa < 0 && newVelocity.x < (-topSpeed / 3.0) -> 0.0
else -> driver.xxa.sign
}
newVelocity = Vec3(
newVelocity.x + (accel * forwardInput.toDouble()),
newVelocity.y,
(newVelocity.z ))
activeInput = true
}
//Vertical movement based on driver input.
val vertTopSpeed = topSpeed / 2.0
val vertInput = when {
driver.jumping -> 1.0
driver.isShiftKeyDown -> -1.0
else -> 0.0
}
if (vertInput != 0.0 && state.stamina.get() > 0.0) {
newVelocity = Vec3(
newVelocity.x,
(newVelocity.y + (accel * vertInput)).coerceIn(-vertTopSpeed, vertTopSpeed),
newVelocity.z)
activeInput = true
}
//air Friction
return newVelocity
}
/*
* Normalizes the current speed between minSpeed and maxSpeed.
* The result is clamped between 0.0 and 1.0, where 0.0 represents minSpeed and 1.0 represents maxSpeed.
*/
private fun normalizeVal(currSpeed: Double, minSpeed: Double, maxSpeed: Double): Double {
require(maxSpeed > minSpeed) { "maxSpeed must be greater than minSpeed" }
return ((currSpeed - minSpeed) / (maxSpeed - minSpeed)).coerceIn(0.0, 1.0)
}
override fun angRollVel(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
return Vec3.ZERO
}
override fun rotationOnMouseXY(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
mouseX: Double,
mouseYSmoother: SmoothDouble,
mouseXSmoother: SmoothDouble,
sensitivity: Double,
deltaTime: Double
): Vec3 {
//Smooth out mouse input.
val smoothingSpeed = 4
val xInput = mouseXSmoother.getNewDeltaValue(mouseX * 0.1, deltaTime * smoothingSpeed);
val yInput = mouseYSmoother.getNewDeltaValue(mouseY * 0.1, deltaTime * smoothingSpeed);
//yaw, pitch, roll
return Vec3(0.0, yInput, xInput)
}
override fun canJump(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun setRideBar(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Float {
//Retrieve stamina from state and use it to set the "stamina bar"
return (state.stamina.get() / 1.0f)
}
override fun jumpForce(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return Vec3.ZERO
}
override fun gravity(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return 0.0
}
override fun rideFovMultiplier(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun useRidingAltPose(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun inertia(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Double {
return 0.05
}
override fun shouldRoll(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun turnOffOnGround(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun dismountOnShift(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun shouldRotatePokemonHead(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun shouldRotatePlayerHead(
settings: HoverSettings,
state: HoverState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun createDefaultState(settings: HoverSettings) = HoverState()
}
class HoverSettings : RidingBehaviourSettings {
override val key = HoverBehaviour.KEY
var canJump = "true".asExpression()
private set
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'AIR', 1.0, 0.3)".asExpression()
private set
// Max accel is a whole 1.0 in 1 second. The conversion in the function below is to convert seconds to ticks
var accelerationExpr: Expression =
"q.get_ride_stats('ACCELERATION', 'AIR', (1.0 / (20.0 * 0.5)), (1.0 / (20.0 * 5.0)))".asExpression()
private set
// Between 30 seconds and 10 seconds at the lowest when at full speed.
var staminaExpr: Expression = "q.get_ride_stats('STAMINA', 'AIR', 30.0, 10.0)".asExpression()
private set
//Between a one block jump and a ten block jump
var jumpExpr: Expression = "q.get_ride_stats('JUMP', 'AIR', 10.0, 1.0)".asExpression()
private set
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 140.0, 20.0)".asExpression()
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(speedExpr)
buffer.writeExpression(accelerationExpr)
buffer.writeExpression(staminaExpr)
buffer.writeExpression(jumpExpr)
buffer.writeExpression(handlingExpr)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
speedExpr = buffer.readExpression()
accelerationExpr = buffer.readExpression()
staminaExpr = buffer.readExpression()
jumpExpr = buffer.readExpression()
handlingExpr = buffer.readExpression()
}
}
class HoverState : RidingBehaviourState() {
override fun copy() = HoverState().also {
it.rideVelocity.set(this.rideVelocity.get(), forced = true)
it.stamina.set(this.stamina.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is HoverState) return false
return super.shouldSync(previous)
}
}
@@ -11,14 +11,12 @@ package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
@@ -26,7 +24,6 @@ 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
import net.minecraft.world.phys.shapes.Shapes
import kotlin.math.*
class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
@@ -35,24 +32,12 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
}
override val key = KEY
override val style = RidingStyle.AIR
val poseProvider = PoseProvider<JetAirSettings, JetAirState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVelocity.get().z > 0.1 })
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVel.get().z > 0.1 })
override fun isActive(settings: JetAirSettings, state: JetAirState, vehicle: PokemonEntity): Boolean {
return Shapes.create(vehicle.boundingBox).blockPositionsAsListRounded().any {
//Need to check other fluids
if (vehicle.isInWater || vehicle.isUnderWater) {
return@any false
}
//This might not actually work, depending on what the yPos actually is. yPos of the middle of the entity? the feet?
if (it.y.toDouble() == (vehicle.position().y)) {
val blockState = vehicle.level().getBlockState(it.below())
return@any !(!blockState.isAir && blockState.fluidState.isEmpty)
}
true
}
return true
}
override fun pose(settings: JetAirSettings, state: JetAirState, vehicle: PokemonEntity): PoseType {
@@ -67,26 +52,24 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
//retrieve minSpeed
val minSpeed = vehicle.runtime.resolveDouble(settings.minSpeed)
//TODO: Reintroduce stamina drain once stats start to be polished and tweaked
state.stamina.set(1.0f)
// //Reduce stamina unless stamina is infinite
// if (!vehicle.runtime.resolveBoolean(settings.infiniteStamina)) {
// //Calculate stamina loss due to speed
// //At max speed it will tick down 0.1 a second so the stamina will last ten seconds
// //There has got to be a better way to express this equation. It interpolates between 0.5 and 1.0
// var staminaRate = (normalizeSpeed(state.rideVelocity.get().length(), minSpeed, topSpeed))
//
// //interpolate between 0.25 and 1.0 so that you always have at least a min of 0.25 stam loss
// staminaRate = 0.25 + (0.75 * staminaRate.pow(3))
//
// //Calculate stamina loss in seconds achievable at top speed
// val staminaLoss = staminaRate * (1.0 / (20.0 * staminaStat))
// state.stamina.set(max(state.stamina.get() - staminaLoss, 0.0).toFloat())
// } else {
// state.stamina.set(1.0f)
// }
//Reduce stamina unless stamina is infinite
if (!vehicle.runtime.resolveBoolean(settings.infiniteStamina)) {
//Calculate stamina loss due to speed
//At max speed it will tick down 0.1 a second so the stamina will last ten seconds
//There has got to be a better way to express this equation. It interpolates between 0.5 and 1.0
var staminaRate = (normalizeSpeed(state.rideVel.get().length(), minSpeed, topSpeed))
return state.rideVelocity.get().length().toFloat()
//interpolate between 0.25 and 1.0 so that you always have at least a min of 0.25 stam loss
staminaRate = 0.25 + (0.75 * staminaRate.pow(3))
//Calculate stamina loss in seconds achievable at top speed
val staminaLoss = staminaRate * (1.0 / (20.0 * staminaStat))
state.stamina.set(max(state.stamina.get() - staminaLoss, 0.0).toFloat())
} else {
state.stamina.set(1.0f)
}
return state.rideVel.get().length().toFloat()
}
//TODO: Move these functions to a riding util class.
@@ -125,8 +108,8 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
//Translate ride space velocity to world space velocity.
if (controller != null) {
upForce = -1.0 * sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().z
forwardForce = cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().z
upForce = -1.0 * sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().z
forwardForce = cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().z
}
//If stamina has run out then initiate forced glide down.
@@ -158,7 +141,7 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr)
val altitudeLimit = vehicle.runtime.resolveDouble(settings.jumpExpr)
val minSpeed = vehicle.runtime.resolveDouble(settings.minSpeed)
val speed = state.rideVelocity.get().length()
val speed = state.rideVel.get().length()
//Give no altitude limit if at max jump stat.
val pushingHeightLimit = if (vehicle.runtime.resolveBoolean(settings.infiniteStamina)) false
@@ -169,15 +152,15 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
if (driver.zza > 0.0 && speed < topSpeed && state.stamina.get() > 0.0f && !pushingHeightLimit) {
//modify acceleration to be slower when at closer speeds to top speed
val accelMod = max(-(normalizeSpeed(speed, minSpeed, topSpeed)) + 1, 0.0)
state.rideVelocity.set(Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, min(state.rideVelocity.get().z + (accel * accelMod), topSpeed)))
state.rideVel.set(Vec3(state.rideVel.get().x, state.rideVel.get().y, min(state.rideVel.get().z + (accel * accelMod), topSpeed)))
} else if (driver.zza >= 0.0 && (state.stamina.get() == 0.0f || pushingHeightLimit)) {
state.rideVelocity.set(Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, max(state.rideVelocity.get().z - ((accel) / 4), minSpeed)))
state.rideVel.set(Vec3(state.rideVel.get().x, state.rideVel.get().y, max(state.rideVel.get().z - ((accel) / 4), minSpeed)))
} else if (driver.zza < 0.0 && speed > minSpeed) {
//modify deccel to be slower when at closer speeds to minimum speed
val deccelMod = max((normalizeSpeed(speed, minSpeed, topSpeed) - 1).pow(2) * 8, 0.1)
val deccelMod = max((normalizeSpeed(speed, minSpeed, topSpeed) - 1).pow(2), 0.1)
//Decelerate currently always a constant half of max acceleration.
state.rideVelocity.set(Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, max(state.rideVelocity.get().z - ((accel * deccelMod) / 2), minSpeed)))
state.rideVel.set(Vec3(state.rideVel.get().x, state.rideVel.get().y, max(state.rideVel.get().z - ((accel * deccelMod) / 2), minSpeed)))
}
}
@@ -226,13 +209,8 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
val invertRoll = if (Cobblemon.config.invertRoll) -1 else 1
val invertPitch = if (Cobblemon.config.invertPitch) -1 else 1
// Smooth out and accumulate roll input
val smoothingSpeed = 4.0
val mouseXc = (mouseX).coerceIn(-60.0, 60.0)
val xInput = mouseXSmoother.getNewDeltaValue(mouseXc * 0.1 * invertRoll, deltaTime * smoothingSpeed);
// Accumulate the y mouse input for pitch
//state.currMouseXForce.set((state.currMouseXForce.get() + (0.0015 * mouseX * invertRoll)).coerceIn(-1.0, 1.0))
// Accumulate the mouse input
state.currMouseXForce.set((state.currMouseXForce.get() + (0.0015 * mouseX * invertRoll)).coerceIn(-1.0, 1.0))
state.currMouseYForce.set((state.currMouseYForce.get() + (0.0015 * mouseY * invertPitch)).coerceIn(-1.0, 1.0))
//Get handling in degrees per second
@@ -254,9 +232,8 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
val pitchRot = handling * state.currMouseYForce.get()
//Roll is 1.5 times as fast as pitch
val rollRot = handling * 1.5 * state.currMouseXForce.get()
//val rollRot = handling * 1.5 * state.currMouseXForce.get()
val rollRot = handling * 1.5 * xInput.coerceIn(-1.0,1.0)
//yaw, pitch, roll
return Vec3(0.0, pitchRot, rollRot)
}
@@ -308,7 +285,7 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
val minSpeed = vehicle.runtime.resolveDouble(settings.minSpeed)
//Must I ensure that topspeed is greater than minimum?
val normalizedSpeed = normalizeSpeed(state.rideVelocity.get().length(), minSpeed, topSpeed)
val normalizedSpeed = normalizeSpeed(state.rideVel.get().length(), minSpeed, topSpeed)
//TODO: Determine if this should be based on max possible speed instead of top speed.
//Only ever want the fov change to be a max of 0.2 and for it to have non linear scaling.
@@ -356,7 +333,7 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
return false
}
override fun createDefaultState(settings: JetAirSettings) = JetAirState()
override fun createDefaultState() = JetAirState()
}
class JetAirSettings : RidingBehaviourSettings {
@@ -365,10 +342,10 @@ class JetAirSettings : RidingBehaviourSettings {
var gravity: Expression = "0".asExpression()
private set
var minSpeed: Expression = "0.8".asExpression()
var minSpeed: Expression = "1.2".asExpression()
private set
var handlingYawExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 50.0, 25.0)".asExpression()
var handlingYawExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 25.0, 8.0)".asExpression()
private set
// Make configurable by json
@@ -382,7 +359,7 @@ class JetAirSettings : RidingBehaviourSettings {
private set
var handlingExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 140.0, 20.0)".asExpression()
private set
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'AIR', 1.8, 1.0)".asExpression()
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'AIR', 2.5, 1.0)".asExpression()
private set
var accelerationExpr: Expression = "q.get_ride_stats('ACCELERATION', 'AIR', (1.0 / (20.0 * 1.0)), (1.0 / (20.0 * 5.0)))".asExpression()
private set
@@ -390,7 +367,6 @@ class JetAirSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(gravity)
buffer.writeExpression(minSpeed)
buffer.writeExpression(handlingYawExpr)
@@ -417,40 +393,50 @@ class JetAirSettings : RidingBehaviourSettings {
}
}
class JetAirState : RidingBehaviourState() {
class JetAirState : RidingBehaviourState {
var currSpeed = ridingState(0.0, Side.CLIENT)
var currMouseXForce = ridingState(0.0, Side.CLIENT)
var currMouseYForce = ridingState(0.0, Side.CLIENT)
var stamina = ridingState(1.0f, Side.CLIENT)
var rideVel = ridingState(Vec3.ZERO, Side.CLIENT)
var currMouseXForce = ridingState(0.0, Side.BOTH)
var currMouseYForce = ridingState(0.0, Side.BOTH)
override fun encode(buffer: FriendlyByteBuf) {
super.encode(buffer)
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeDouble(currSpeed.get())
buffer.writeFloat(stamina.get())
buffer.writeVec3(rideVel.get())
}
override fun decode(buffer: FriendlyByteBuf) {
super.decode(buffer)
override fun decode(buffer: RegistryFriendlyByteBuf) {
currSpeed.set(buffer.readDouble(), forced = true)
stamina.set(buffer.readFloat(), forced = true)
rideVel.set(buffer.readVec3(), forced = true)
}
override fun reset() {
super.reset()
currSpeed.set(0.0, forced = true)
stamina.set(1.0f, forced = true)
rideVel.set(Vec3.ZERO, forced = true)
currMouseXForce.set(0.0, forced = true)
currMouseYForce.set(0.0, forced = true)
}
override fun toString(): String {
return "JetAirState(currSpeed=${currSpeed.get()}, stamina=${stamina.get()}, rideVel=${rideVel.get()}, currMouseXForce=${currMouseXForce.get()}, currMouseYForce=${currMouseYForce.get()})"
}
override fun copy() = JetAirState().also {
it.currSpeed.set(currSpeed.get(), forced = true)
it.stamina.set(stamina.get(), forced = true)
it.rideVelocity.set(rideVelocity.get(), forced = true)
// it.currMouseXForce.set(currMouseXForce.get(), forced = true)
// it.currMouseYForce.set(currMouseYForce.get(), forced = true)
it.rideVel.set(rideVel.get(), forced = true)
it.currMouseXForce.set(currMouseXForce.get(), forced = true)
it.currMouseYForce.set(currMouseYForce.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is JetAirState) return false
if (previous.currSpeed != currSpeed) return true
return super.shouldSync(previous)
if (previous.stamina != stamina) return true
if (previous.rideVel != rideVel) return true
return false
}
}
@@ -0,0 +1,469 @@
/*
* 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.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.riding.behaviour.*
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.util.asExpression
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readExpression
import com.cobblemon.mod.common.util.writeExpression
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
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 JumpToFlightCompositeBehaviour : RidingBehaviour<JumpToFlightCompositeSettings, JumpToFlightCompositeState> {
companion object {
val KEY = cobblemonResource("composite/jump_to_flight")
}
override val key = KEY
val landBehaviour: GenericLandBehaviour = GenericLandBehaviour()
val birdBehaviour: BirdAirBehaviour = BirdAirBehaviour()
override fun tick(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
val flightState = state.flightState
val groundState = state.landState
if (shouldTransitionToGround(state, vehicle)) {
//Pass the speed to the next state
// groundState.currSpeed = flightState.currSpeed
groundState.rideVel.set(flightState.rideVel.get())
groundState.stamina.set(flightState.stamina.get())
state.activeController.set(GenericLandBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, false)
state.timeTransitioned.set(vehicle.level().gameTime)
} else if (shouldTransitionToAir(state, vehicle, driver)) {
//Pass the speed to the next state
// flightState.currSpeed = groundState.currSpeed
flightState.rideVel.set(groundState.rideVel.get())
flightState.stamina.set(groundState.stamina.get())
state.activeController.set(BirdAirBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, true)
state.timeTransitioned.set(vehicle.level().gameTime)
}
}
override fun isActive(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return true
}
private fun shouldTransitionToGround(state: JumpToFlightCompositeState, entity: PokemonEntity): Boolean {
return state.activeController.get() == BirdAirBehaviour.KEY
&& entity.onGround()
&& state.timeTransitioned.get() + 20 < entity.level().gameTime
}
private fun shouldTransitionToAir(
state: JumpToFlightCompositeState,
entity: PokemonEntity,
driver: Player
): Boolean {
return state.activeController.get() == GenericLandBehaviour.KEY
&& driver.jumping
&& state.timeTransitioned.get() + 20 < entity.level().gameTime
}
override fun pose(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): PoseType {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.pose(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.pose(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun speed(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.speed(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.speed(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotation(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotation(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.rotation(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun velocity(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.velocity(settings.land, state.landState, vehicle, driver, input)
BirdAirBehaviour.KEY -> birdBehaviour.velocity(settings.bird, state.flightState, vehicle, driver, input)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun angRollVel(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.angRollVel(
settings.land,
state.landState,
vehicle,
driver,
deltaTime
)
BirdAirBehaviour.KEY -> birdBehaviour.angRollVel(
settings.bird,
state.flightState,
vehicle,
driver,
deltaTime
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotationOnMouseXY(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
mouseX: Double,
mouseYSmoother: SmoothDouble,
mouseXSmoother: SmoothDouble,
sensitivity: Double,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotationOnMouseXY(
settings.land,
state.landState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
BirdAirBehaviour.KEY -> birdBehaviour.rotationOnMouseXY(
settings.bird,
state.flightState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun canJump(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.canJump(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.canJump(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun setRideBar(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.setRideBar(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.setRideBar(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun jumpForce(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.jumpForce(
settings.land,
state.landState,
vehicle,
driver,
jumpStrength
)
BirdAirBehaviour.KEY -> birdBehaviour.jumpForce(
settings.bird,
state.flightState,
vehicle,
driver,
jumpStrength
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun gravity(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.gravity(settings.land, state.landState, vehicle, regularGravity)
BirdAirBehaviour.KEY -> birdBehaviour.gravity(settings.bird, state.flightState, vehicle, regularGravity)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rideFovMultiplier(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rideFovMultiplier(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.rideFovMultiplier(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useAngVelSmoothing(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useAngVelSmoothing(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.useAngVelSmoothing(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useRidingAltPose(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useRidingAltPose(settings.land, state.landState, vehicle, driver)
BirdAirBehaviour.KEY -> birdBehaviour.useRidingAltPose(settings.bird, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun inertia(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.inertia(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.inertia(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRoll(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRoll(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.shouldRoll(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun turnOffOnGround(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.turnOffOnGround(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.turnOffOnGround(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun dismountOnShift(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.dismountOnShift(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.dismountOnShift(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePokemonHead(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePokemonHead(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.shouldRotatePokemonHead(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePlayerHead(
settings: JumpToFlightCompositeSettings,
state: JumpToFlightCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePlayerHead(settings.land, state.landState, vehicle)
BirdAirBehaviour.KEY -> birdBehaviour.shouldRotatePlayerHead(settings.bird, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun createDefaultState() = JumpToFlightCompositeState()
}
class JumpToFlightCompositeSettings : RidingBehaviourSettings {
override val key = JumpToFlightCompositeBehaviour.KEY
var bird: BirdAirSettings = BirdAirSettings()
private set
var land: GenericLandSettings = GenericLandSettings()
private set
var minimumSpeed: Expression = "0.5".asExpression()
private set
var minimumJump: Expression = "0.5".asExpression()
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
bird.encode(buffer)
land.encode(buffer)
buffer.writeExpression(minimumSpeed)
buffer.writeExpression(minimumJump)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
bird.decode(buffer)
land.decode(buffer)
minimumSpeed = buffer.readExpression()
minimumJump = buffer.readExpression()
}
}
class JumpToFlightCompositeState : RidingBehaviourState {
var activeController = ridingState(GenericLandBehaviour.KEY, Side.CLIENT)
var currSpeed = ridingState(0.0, Side.BOTH)
var timeTransitioned = ridingState(-100L, Side.BOTH)
var landState = GenericLandState()
var flightState = BirdAirState()
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(activeController.get())
landState.encode(buffer)
flightState.encode(buffer)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
activeController.set(buffer.readResourceLocation(), forced = true)
landState.decode(buffer)
flightState.decode(buffer)
}
override fun reset() {
activeController.set(GenericLandBehaviour.KEY, forced = true)
timeTransitioned.set(-100L, forced = true)
currSpeed.set(0.0, forced = true)
}
override fun toString(): String {
return "JumpToFlightCompositeState(activeController=${activeController.get()}, landState=$landState, flightState=$flightState, currSpeed=${currSpeed.get()}, timeTransitioned=${timeTransitioned.get()})"
}
override fun copy() = JumpToFlightCompositeState().also {
it.activeController.set(activeController.get(), forced = true)
it.landState = landState.copy()
it.flightState = flightState.copy()
it.currSpeed.set(currSpeed.get(), forced = true)
it.timeTransitioned.set(timeTransitioned.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is JumpToFlightCompositeState) return false
if (activeController != previous.activeController) return true
if (landState.shouldSync(previous.landState)) return true
if (flightState.shouldSync(previous.flightState)) return true
return false
}
}
@@ -0,0 +1,450 @@
/*
* 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.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.riding.behaviour.*
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.util.asExpression
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readExpression
import com.cobblemon.mod.common.util.writeExpression
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
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 RunToJetCompositeBehaviour : RidingBehaviour<RunToJetCompositeSettings, RunToJetCompositeState> {
companion object {
val KEY = cobblemonResource("composite/run_to_jet")
}
override val key = KEY
val landBehaviour: GenericLandBehaviour = GenericLandBehaviour()
val jetBehaviour: JetAirBehaviour = JetAirBehaviour()
override fun tick(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
val flightState = state.flightState
val groundState = state.landState
if (shouldTransitionToGround(state, vehicle, driver)) {
groundState.currSpeed = flightState.currSpeed
groundState.stamina = flightState.stamina
groundState.rideVel = flightState.rideVel
state.activeController.set(GenericLandBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, false)
state.timeTransitioned.set(vehicle.level().gameTime)
} else if (shouldTransitionToAir(state, vehicle, driver, input)) {
flightState.currSpeed = groundState.currSpeed
flightState.stamina = groundState.stamina
flightState.rideVel = groundState.rideVel
state.activeController.set(JetAirBehaviour.KEY)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, true)
state.timeTransitioned.set(vehicle.level().gameTime)
}
}
private fun shouldTransitionToGround(
state: RunToJetCompositeState,
entity: PokemonEntity,
driver: Player
): Boolean {
if (state.activeController.get() != JetAirBehaviour.KEY) return false
if (state.timeTransitioned.get() + 20 >= entity.level().gameTime) return false
return driver.isSprinting || entity.onGround()
}
private fun shouldTransitionToAir(
state: RunToJetCompositeState,
entity: PokemonEntity,
driver: Player,
input: Vec3
): Boolean {
if (state.activeController.get() != GenericLandBehaviour.KEY) return false
if (state.timeTransitioned.get() + 20 >= entity.level().gameTime) return false
return driver.isSprinting && input.z > 0.5
}
override fun isActive(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return true
}
override fun pose(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): PoseType {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.pose(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.pose(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun speed(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.speed(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.speed(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotation(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotation(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.rotation(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun velocity(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.velocity(settings.land, state.landState, vehicle, driver, input)
JetAirBehaviour.KEY -> jetBehaviour.velocity(settings.jet, state.flightState, vehicle, driver, input)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun angRollVel(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.angRollVel(
settings.land,
state.landState,
vehicle,
driver,
deltaTime
)
JetAirBehaviour.KEY -> jetBehaviour.angRollVel(settings.jet, state.flightState, vehicle, driver, deltaTime)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rotationOnMouseXY(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
mouseX: Double,
mouseYSmoother: SmoothDouble,
mouseXSmoother: SmoothDouble,
sensitivity: Double,
deltaTime: Double
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rotationOnMouseXY(
settings.land,
state.landState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
JetAirBehaviour.KEY -> jetBehaviour.rotationOnMouseXY(
settings.jet,
state.flightState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun canJump(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.canJump(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.canJump(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun setRideBar(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.setRideBar(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.setRideBar(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun jumpForce(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.jumpForce(settings.land, state.landState, vehicle, driver, jumpStrength)
JetAirBehaviour.KEY -> jetBehaviour.jumpForce(settings.jet, state.flightState, vehicle, driver, jumpStrength)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun gravity(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.gravity(settings.land, state.landState, vehicle, regularGravity)
JetAirBehaviour.KEY -> jetBehaviour.gravity(settings.jet, state.flightState, vehicle, regularGravity)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun rideFovMultiplier(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.rideFovMultiplier(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.rideFovMultiplier(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useAngVelSmoothing(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useAngVelSmoothing(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.useAngVelSmoothing(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun useRidingAltPose(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.useRidingAltPose(settings.land, state.landState, vehicle, driver)
JetAirBehaviour.KEY -> jetBehaviour.useRidingAltPose(settings.jet, state.flightState, vehicle, driver)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun inertia(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Double {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.inertia(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.inertia(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRoll(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRoll(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.shouldRoll(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun turnOffOnGround(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.turnOffOnGround(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.turnOffOnGround(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun dismountOnShift(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.dismountOnShift(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.dismountOnShift(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePokemonHead(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePokemonHead(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.shouldRotatePokemonHead(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun shouldRotatePlayerHead(
settings: RunToJetCompositeSettings,
state: RunToJetCompositeState,
vehicle: PokemonEntity
): Boolean {
return when (state.activeController.get()) {
GenericLandBehaviour.KEY -> landBehaviour.shouldRotatePlayerHead(settings.land, state.landState, vehicle)
JetAirBehaviour.KEY -> jetBehaviour.shouldRotatePlayerHead(settings.jet, state.flightState, vehicle)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun createDefaultState() = RunToJetCompositeState()
}
class RunToJetCompositeSettings : RidingBehaviourSettings {
override val key = RunToJetCompositeBehaviour.KEY
var jet: JetAirSettings = JetAirSettings()
private set
var land: GenericLandSettings = GenericLandSettings()
private set
var minimumSpeed: Expression = "0.5".asExpression()
private set
var minimumJump: Expression = "0.5".asExpression()
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
jet.encode(buffer)
land.encode(buffer)
buffer.writeExpression(minimumSpeed)
buffer.writeExpression(minimumJump)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
jet.decode(buffer)
land.decode(buffer)
minimumSpeed = buffer.readExpression()
minimumJump = buffer.readExpression()
}
}
class RunToJetCompositeState : RidingBehaviourState {
var activeController = ridingState(GenericLandBehaviour.KEY, Side.CLIENT)
var landState: GenericLandState = GenericLandState()
var flightState: JetAirState = JetAirState()
var currSpeed = ridingState(0.0, Side.BOTH)
var timeTransitioned = ridingState(-100L, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(activeController.get())
landState.encode(buffer)
flightState.encode(buffer)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
activeController.set(buffer.readResourceLocation(), forced = true)
landState.decode(buffer)
flightState.decode(buffer)
}
override fun reset() {
activeController.set(GenericLandBehaviour.KEY, forced = true)
timeTransitioned.set(-100L, forced = true)
currSpeed.set(0.0, forced = true)
}
override fun toString(): String {
return "RunToJetCompositeState(activeController=${activeController.get()}, landState=$landState, flightState=$flightState, currSpeed=${currSpeed.get()}, timeTransitioned=${timeTransitioned.get()})"
}
override fun copy() = RunToJetCompositeState().also {
it.activeController.set(activeController.get(), forced = true)
it.landState = landState.copy()
it.flightState = flightState.copy()
it.currSpeed.set(currSpeed.get(), forced = true)
it.timeTransitioned.set(timeTransitioned.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is RunToJetCompositeState) return false
if (activeController != previous.activeController) return true
if (landState.shouldSync(previous.landState)) return true
if (flightState.shouldSync(previous.flightState)) return true
return false
}
}
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.api.riding.behaviour.types
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
@@ -34,7 +33,6 @@ class SwimDashBehaviour : RidingBehaviour<SwimDashSettings, SwimDashState> {
}
override val key = KEY
override val style = RidingStyle.LIQUID
val poseProvider = PoseProvider<SwimDashSettings, SwimDashState>(PoseType.FLOAT)
.with(PoseOption(PoseType.SWIM) { _, _, entity -> entity.isSwimming && entity.entityData.get(PokemonEntity.MOVING) })
@@ -219,7 +217,7 @@ class SwimDashBehaviour : RidingBehaviour<SwimDashSettings, SwimDashState> {
return false
}
override fun createDefaultState(settings: SwimDashSettings) = SwimDashState()
override fun createDefaultState() = SwimDashState()
}
class SwimDashSettings : RidingBehaviourSettings {
@@ -229,7 +227,6 @@ class SwimDashSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeFloat(dashSpeed)
}
@@ -238,12 +235,14 @@ class SwimDashSettings : RidingBehaviourSettings {
}
}
class SwimDashState : RidingBehaviourState() {
class SwimDashState : RidingBehaviourState {
var dashing = ridingState(false, Side.BOTH)
var ticks = ridingState(0, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) = Unit
override fun decode(buffer: RegistryFriendlyByteBuf) = Unit
override fun reset() {
super.reset()
dashing.set(false, forced = true)
ticks.set(0, forced = true)
}
@@ -253,9 +252,9 @@ class SwimDashState : RidingBehaviourState() {
}
override fun copy() = SwimDashState().also {
it.rideVelocity.set(rideVelocity.get(), forced = true)
it.stamina.set(stamina.get(), forced = true)
it.dashing.set(dashing.get(), forced = true)
it.ticks.set(ticks. get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState) = false
}
@@ -53,7 +53,6 @@ class VehicleLandBehaviour : RidingBehaviour<VehicleLandSettings, VehicleLandSta
}
override val key = KEY
override val style = RidingStyle.LAND
val poseProvider = PoseProvider<VehicleLandSettings, VehicleLandState>(PoseType.STAND)
.with(PoseOption(PoseType.WALK) { _, _, entity -> entity.entityData.get(PokemonEntity.MOVING) })
@@ -266,7 +265,7 @@ class VehicleLandBehaviour : RidingBehaviour<VehicleLandSettings, VehicleLandSta
return false
}
override fun createDefaultState(settings: VehicleLandSettings) = VehicleLandState()
override fun createDefaultState() = VehicleLandState()
}
class VehicleLandSettings : RidingBehaviourSettings {
@@ -297,7 +296,6 @@ class VehicleLandSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(canJump)
buffer.writeExpression(jumpVector[0])
buffer.writeExpression(jumpVector[1])
@@ -326,12 +324,14 @@ class VehicleLandSettings : RidingBehaviourSettings {
}
}
class VehicleLandState : RidingBehaviourState() {
class VehicleLandState : RidingBehaviourState {
var currSpeed = ridingState(0.0, Side.BOTH)
var deltaRotation = ridingState(Vec2.ZERO, Side.BOTH)
override fun encode(buffer: RegistryFriendlyByteBuf) = Unit
override fun decode(buffer: RegistryFriendlyByteBuf) = Unit
override fun reset() {
super.reset()
currSpeed.set(0.0, forced = true)
deltaRotation.set(Vec2.ZERO, forced = true)
}
@@ -341,9 +341,9 @@ class VehicleLandState : RidingBehaviourState() {
}
override fun copy() = VehicleLandState().also {
it.rideVelocity.set(rideVelocity.get(), forced = true)
it.stamina.set(stamina.get(), forced = true)
it.currSpeed.set(currSpeed.get(), forced = true)
it.deltaRotation.set(deltaRotation.get(), forced = true)
}
override fun shouldSync(previous: RidingBehaviourState) = false
}
@@ -1,426 +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.api.riding.behaviour.types.composite
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.*
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies.CompositeRidingStrategies
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.adapters.RidingBehaviourSettingsAdapter
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.SmoothDouble
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 CompositeBehaviour : RidingBehaviour<CompositeSettings, CompositeState> {
companion object {
val KEY = cobblemonResource("composite")
}
override val key = KEY
override val style = RidingStyle.COMPOSITE
override fun createDefaultState(settings: CompositeSettings): CompositeState {
val defaultBehaviour = RidingBehaviours.get(settings.defaultBehaviour.key)
val defaultState = defaultBehaviour.createDefaultState(settings.defaultBehaviour)
val alternateBehaviour = RidingBehaviours.get(settings.alternateBehaviour.key)
val alternativeState = alternateBehaviour.createDefaultState(settings.alternateBehaviour)
return CompositeState(
defaultBehaviour = settings.defaultBehaviour.key,
defaultBehaviourState = defaultState,
alternateBehaviourState = alternativeState
)
}
fun <T> chooseBehaviour(
settings: CompositeSettings,
state: CompositeState,
action: (behaviour: RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState>, settings: RidingBehaviourSettings, state: RidingBehaviourState) -> T
): T {
val defaultBehaviour = RidingBehaviours.get(settings.defaultBehaviour.key)
val alternativeBehaviour = RidingBehaviours.get(settings.alternateBehaviour.key)
return when (state.activeController.get()) {
settings.defaultBehaviour.key -> action(
defaultBehaviour,
settings.defaultBehaviour,
state.defaultBehaviourState
)
settings.alternateBehaviour.key -> action(
alternativeBehaviour,
settings.alternateBehaviour,
state.alternateBehaviourState
)
else -> error("Invalid controller: ${state.activeController.get()}")
}
}
override fun tick(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
val strategy = CompositeRidingStrategies.get(settings.transitionStrategy)
strategy.tick(settings, state, state.defaultBehaviourState, state.alternateBehaviourState, vehicle, driver, input)
}
override fun clampPassengerRotation(
settings: CompositeSettings,
state: CompositeState,
entity: PokemonEntity,
driver: LivingEntity
) {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.clampPassengerRotation(behaviourSettings, behaviourState, entity, driver)
}
}
override fun updatePassengerRotation(
settings: CompositeSettings,
state: CompositeState,
entity: PokemonEntity,
driver: LivingEntity
) {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.updatePassengerRotation(behaviourSettings, behaviourState, entity, driver)
}
}
override fun shouldRotatePlayerHead(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.shouldRotatePlayerHead(behaviourSettings, behaviourState, vehicle)
}
}
override fun shouldRotatePokemonHead(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.shouldRotatePokemonHead(behaviourSettings, behaviourState, vehicle)
}
}
override fun dismountOnShift(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.dismountOnShift(behaviourSettings, behaviourState, vehicle)
}
}
override fun turnOffOnGround(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.turnOffOnGround(behaviourSettings, behaviourState, vehicle)
}
}
override fun shouldRoll(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.shouldRoll(behaviourSettings, behaviourState, vehicle)
}
}
override fun inertia(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Double {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.inertia(behaviourSettings, behaviourState, vehicle)
}
}
override fun useRidingAltPose(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.useRidingAltPose(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun useAngVelSmoothing(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.useAngVelSmoothing(behaviourSettings, behaviourState, vehicle)
}
}
override fun rideFovMultiplier(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.rideFovMultiplier(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun gravity(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.gravity(behaviourSettings, behaviourState, vehicle, regularGravity)
}
}
override fun jumpForce(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
): Vec3 {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.jumpForce(behaviourSettings, behaviourState, vehicle, driver, jumpStrength)
}
}
override fun setRideBar(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.setRideBar(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun canJump(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.canJump(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun rotationOnMouseXY(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
mouseX: Double,
mouseYSmoother: SmoothDouble,
mouseXSmoother: SmoothDouble,
sensitivity: Double,
deltaTime: Double
): Vec3 {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.rotationOnMouseXY(
behaviourSettings,
behaviourState,
vehicle,
driver,
mouseY,
mouseX,
mouseYSmoother,
mouseXSmoother,
sensitivity,
deltaTime
)
}
}
override fun angRollVel(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
): Vec3 {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.angRollVel(behaviourSettings, behaviourState, vehicle, driver, deltaTime)
}
}
override fun velocity(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
): Vec3 {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.velocity(behaviourSettings, behaviourState, vehicle, driver, input)
}
}
override fun rotation(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.rotation(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun speed(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity,
driver: Player
): Float {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.speed(behaviourSettings, behaviourState, vehicle, driver)
}
}
override fun pose(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): PoseType {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.pose(behaviourSettings, behaviourState, vehicle)
}
}
override fun isActive(
settings: CompositeSettings,
state: CompositeState,
vehicle: PokemonEntity
): Boolean {
return chooseBehaviour(settings, state) { behaviour, behaviourSettings, behaviourState ->
behaviour.isActive(behaviourSettings, behaviourState, vehicle)
}
}
}
open class CompositeSettings : RidingBehaviourSettings {
lateinit var transitionStrategy: ResourceLocation
private set
lateinit var defaultBehaviour: RidingBehaviourSettings
private set
lateinit var alternateBehaviour: RidingBehaviourSettings
private set
override val key: ResourceLocation = CompositeBehaviour.KEY
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeResourceLocation(transitionStrategy)
defaultBehaviour.encode(buffer)
alternateBehaviour.encode(buffer)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
transitionStrategy = buffer.readResourceLocation()
val defaultBehaviourKey = buffer.readResourceLocation()
defaultBehaviour = RidingBehaviourSettingsAdapter.types[defaultBehaviourKey]?.getConstructor()?.newInstance()
?: error("Unknown controller key: $key")
defaultBehaviour.decode(buffer)
val alternativeBehaviourKey = buffer.readResourceLocation()
alternateBehaviour =
RidingBehaviourSettingsAdapter.types[alternativeBehaviourKey]?.getConstructor()?.newInstance()
?: error("Unknown controller key: $key")
alternateBehaviour.decode(buffer)
}
}
class CompositeState(
private val defaultBehaviour: ResourceLocation,
val defaultBehaviourState: RidingBehaviourState,
val alternateBehaviourState: RidingBehaviourState
) : RidingBehaviourState() {
var activeController = ridingState(defaultBehaviour, Side.CLIENT)
var lastTransition = ridingState(-100L, Side.BOTH)
override val rideVelocity: SidedRidingState<Vec3>
get() = when (activeController.get()) {
defaultBehaviour -> defaultBehaviourState.rideVelocity
else -> alternateBehaviourState.rideVelocity
}
override val stamina: SidedRidingState<Float>
get() = when (activeController.get()) {
defaultBehaviour -> defaultBehaviourState.stamina
else -> alternateBehaviourState.stamina
}
override fun reset() {
super.reset()
activeController.set(defaultBehaviour, forced = true)
lastTransition.set(-100L, forced = true)
defaultBehaviourState.reset()
alternateBehaviourState.reset()
}
override fun copy(): CompositeState {
val state =
CompositeState(defaultBehaviour, defaultBehaviourState.copy(), alternateBehaviourState.copy())
state.activeController.set(activeController.get(), forced = true)
state.lastTransition.set(lastTransition.get(), forced = true)
state.rideVelocity.set(rideVelocity.get(), forced = true)
state.stamina.set(stamina.get(), forced = true)
return state
}
override fun shouldSync(previous: RidingBehaviourState): Boolean {
if (previous !is CompositeState) return false
if (previous.activeController.get() != activeController.get()) return true
if (defaultBehaviourState.shouldSync(previous.defaultBehaviourState)) return true
if (alternateBehaviourState.shouldSync(previous.alternateBehaviourState)) return true
return super.shouldSync(previous)
}
override fun encode(buffer: FriendlyByteBuf) {
super.encode(buffer)
buffer.writeResourceLocation(activeController.get())
defaultBehaviourState.encode(buffer)
alternateBehaviourState.encode(buffer)
}
override fun decode(buffer: FriendlyByteBuf) {
super.decode(buffer)
activeController.set(buffer.readResourceLocation(), forced = true)
defaultBehaviourState.decode(buffer)
alternateBehaviourState.decode(buffer)
}
}
@@ -1,32 +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.api.riding.behaviour.types.composite.strategies
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import net.minecraft.resources.ResourceLocation
object CompositeRidingStrategies {
val strategies = mutableMapOf<ResourceLocation, CompositeRidingStrategy<out CompositeSettings>>()
init {
register(RunStrategy.key, RunStrategy)
register(JumpStrategy.key, JumpStrategy)
register(FallStrategy.key, FallStrategy)
}
fun register(key: ResourceLocation, strategy: CompositeRidingStrategy<out CompositeSettings>) {
if (strategies.contains(key)) error("Strategy already registered to key $key")
strategies[key] = strategy
}
fun get(key: ResourceLocation): CompositeRidingStrategy<CompositeSettings> {
if (!strategies.contains(key)) error("Strategy not registered to key $key")
return strategies[key]!! as CompositeRidingStrategy<CompositeSettings>
}
}
@@ -1,53 +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.api.riding.behaviour.types.composite.strategies
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviours
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeState
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
interface CompositeRidingStrategy<T : CompositeSettings> {
val key: ResourceLocation
fun tick(
settings: T,
state: CompositeState,
defaultState: RidingBehaviourState,
alternateState: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
)
fun transition(
vehicle: PokemonEntity,
settings: CompositeSettings,
state: CompositeState,
fromState: RidingBehaviourState,
toState: RidingBehaviourState,
toSettings: RidingBehaviourSettings
) {
toState.stamina.set(fromState.stamina.get())
toState.rideVelocity.set(fromState.rideVelocity.get())
fromState.reset()
state.activeController.set(toSettings.key)
state.lastTransition.set(vehicle.level().gameTime)
val behaviour = RidingBehaviours.get(toSettings.key)
vehicle.setBehaviourFlag(PokemonBehaviourFlag.FLYING, behaviour.style == RidingStyle.AIR)
}
}
@@ -1,99 +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.api.riding.behaviour.types.composite.strategies
import com.bedrockk.molang.Expression
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviours
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeState
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.*
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
object FallStrategy : CompositeRidingStrategy<FallCompositeSettings> {
override val key = cobblemonResource("strategy/fall")
override fun tick(
settings: FallCompositeSettings,
state: CompositeState,
defaultState: RidingBehaviourState,
alternateState: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
if (shouldTransitionToDefault(state, settings.defaultBehaviour, vehicle)) {
transition(vehicle, settings, state, alternateState, defaultState, settings.defaultBehaviour)
} else if (shouldTransitionToAlternate(settings, state, settings.alternateBehaviour, vehicle, driver)) {
transition(vehicle, settings, state, defaultState, alternateState, settings.alternateBehaviour)
}
}
private fun shouldTransitionToDefault(
state: CompositeState,
defaultSettings: RidingBehaviourSettings,
vehicle: PokemonEntity
): Boolean {
if (state.activeController.get() == defaultSettings.key) return false
if (state.lastTransition.get() + 20 >= vehicle.level().gameTime) return false
if (!vehicle.onGround()) return false
val defaultBehaviour = RidingBehaviours.get(defaultSettings.key)
return defaultBehaviour.isActive(defaultSettings, state.defaultBehaviourState, vehicle)
}
private fun shouldTransitionToAlternate(
settings: FallCompositeSettings,
state: CompositeState,
alternateSettings: RidingBehaviourSettings,
vehicle: PokemonEntity,
driver: Player
): Boolean {
if (state.activeController.get() == alternateSettings.key) return false
if (!driver.jumping) return false
if (state.lastTransition.get() + 20 >= vehicle.level().gameTime) return false
val runtime = vehicle.runtime
val minFallingSpeed = runtime.resolveFloat(settings.minimumFallSpeed)
val minForwardSpeed = runtime.resolveFloat(settings.minimumForwardSpeed)
if (vehicle.deltaMovement.y < -minFallingSpeed) return false
if (vehicle.deltaMovement.horizontalDistance() < minForwardSpeed) return false
val alternativeBehaviour = RidingBehaviours.get(alternateSettings.key)
return alternativeBehaviour.isActive(alternateSettings, state.alternateBehaviourState, vehicle)
}
}
class FallCompositeSettings : CompositeSettings() {
override val key = FallStrategy.key
var minimumForwardSpeed: Expression = "0.0".asExpression()
private set
var minimumFallSpeed: Expression = "0.5".asExpression()
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
super.encode(buffer)
buffer.writeExpression(minimumForwardSpeed)
buffer.writeExpression(minimumFallSpeed)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
super.decode(buffer)
minimumForwardSpeed = buffer.readExpression()
minimumFallSpeed = buffer.readExpression()
}
}
@@ -1,68 +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.api.riding.behaviour.types.composite.strategies
import com.cobblemon.mod.common.api.riding.RidingStyle
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviours
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeState
import com.cobblemon.mod.common.entity.pokemon.PokemonBehaviourFlag
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
object JumpStrategy : CompositeRidingStrategy<CompositeSettings> {
override val key = cobblemonResource("strategy/jump")
override fun tick(
settings: CompositeSettings,
state: CompositeState,
defaultState: RidingBehaviourState,
alternateState: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
if (shouldTransitionToDefault(state, settings.defaultBehaviour, vehicle)) {
transition(vehicle, settings, state, alternateState, defaultState, settings.defaultBehaviour)
} else if (shouldTransitionToAlternative(state, settings.alternateBehaviour, vehicle, driver)) {
transition(vehicle, settings, state, defaultState, alternateState, settings.alternateBehaviour)
}
}
private fun shouldTransitionToDefault(
state: CompositeState,
defaultSettings: RidingBehaviourSettings,
vehicle: PokemonEntity
): Boolean {
if (state.activeController.get() == defaultSettings.key) return false
if (!vehicle.onGround()) return false
if (state.lastTransition.get() + 20 >= vehicle.level().gameTime) return false
val defaultBehaviour = RidingBehaviours.get(defaultSettings.key)
return defaultBehaviour.isActive(defaultSettings, state.defaultBehaviourState, vehicle)
}
private fun shouldTransitionToAlternative(
state: CompositeState,
alternativeSettings: RidingBehaviourSettings,
vehicle: PokemonEntity,
driver: Player
): Boolean {
if (state.activeController.get() == alternativeSettings.key) return false
if (!driver.jumping) return false
if (state.lastTransition.get() + 20 >= vehicle.level().gameTime) return false
val alternativeBehaviour = RidingBehaviours.get(alternativeSettings.key)
return alternativeBehaviour.isActive(alternativeSettings, state.alternateBehaviourState, vehicle)
}
}
@@ -1,69 +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.api.riding.behaviour.types.composite.strategies
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviours
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeState
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec3
object RunStrategy : CompositeRidingStrategy<CompositeSettings> {
override val key = cobblemonResource("strategy/run")
override fun tick(
settings: CompositeSettings,
state: CompositeState,
defaultState: RidingBehaviourState,
alternateState: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
) {
if (shouldTransitionToDefault(state, settings.defaultBehaviour, vehicle, driver)) {
transition(vehicle, settings, state, alternateState, defaultState, settings.defaultBehaviour)
}
else if (shouldTransitionToAlternate(state, settings.alternateBehaviour, vehicle, driver, input)) {
transition(vehicle, settings, state, defaultState, alternateState, settings.alternateBehaviour)
}
}
private fun shouldTransitionToDefault(
state: CompositeState,
defaultSettings: RidingBehaviourSettings,
entity: PokemonEntity,
driver: Player
): Boolean {
if (state.activeController.get() == defaultSettings.key) return false
if (!entity.onGround()) return false
if (state.lastTransition.get() + 20 >= entity.level().gameTime) return false
val defaultBehaviour = RidingBehaviours.get(defaultSettings.key)
val ret = defaultBehaviour.isActive(defaultSettings, state.defaultBehaviourState, entity)
return ret
}
private fun shouldTransitionToAlternate(
state: CompositeState,
alternativeSettings: RidingBehaviourSettings,
entity: PokemonEntity,
driver: Player,
input: Vec3
): Boolean {
if (state.activeController.get() == alternativeSettings.key) return false
if (state.lastTransition.get() + 20 >= entity.level().gameTime) return false
val alternativeBehaviour = RidingBehaviours.get(alternativeSettings.key)
return driver.isSprinting && input.z > 0.5 && alternativeBehaviour.isActive(alternativeSettings, state.alternateBehaviourState, entity)
}
}
@@ -1,143 +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.api.riding.util
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.math.geometry.toRadians
import net.minecraft.util.Mth
import net.minecraft.world.phys.Vec3
import org.joml.Matrix3f
import org.joml.Quaternionf
import org.joml.Vector3f
/**
* Class to handle the updating and containment of ride data used in animation.
*
* @author Jackowes
* @since April 7th, 2025
*/
class RidingAnimationData
{
var prevOrientation: Matrix3f = Matrix3f()
var prevRot: Vec3 = Vec3.ZERO
var velocitySpring: Vec3Spring = Vec3Spring()
var rotSpring: Vec3Spring = Vec3Spring()
var rotDeltaSpring: Vec3Spring = Vec3Spring()
var localVelocitySpring: Vec3Spring = Vec3Spring()
fun update(entity: PokemonEntity) {
var currRot = Vec3.ZERO
var angDelta = Vec3.ZERO
// val stiffness = 90.0
// val damping = 18.0
val stiffness = 16.0
val damping = 8.0
// Update velocity first
val currentVelocity = Vec3(
entity.x - entity.xOld,
entity.y - entity.yOld,
entity.z - entity.zOld
)
val r = entity.ifRidingAvailableSupply(false) { behaviour, settings, state ->
behaviour.shouldRoll(settings, state, entity);
}
if( r ) {
//TODO: should this return?
val controller = (entity.firstPassenger as? OrientationControllable)?.orientationController ?: return
val orientation = controller.orientation ?: Matrix3f()
val currPitch = controller.pitch
val currYaw = controller.yaw
val currRoll = controller.roll
currRot = Vec3(currPitch.toDouble(), currYaw.toDouble(), currRoll.toDouble())
val currOrientation = orientation
/******************************************************
* Calculate current 3d euler rotation deltas in the
* entities local space
*****************************************************/
// Get current and previous orientation as quaternions
val currQuat = Quaternionf().setFromUnnormalized(currOrientation)
val prevQuat = Quaternionf().setFromUnnormalized(prevOrientation)
// Compute deltaQuat = current * inverse(previous)
val deltaQuat = Quaternionf(currQuat).mul(Quaternionf(prevQuat).invert())
// Transform delta into the local space of the current orientation
val localDeltaQuat = Quaternionf(currQuat).invert().mul(deltaQuat).mul(currQuat)
// Convert delta rotation to Euler angles
val euler = Vector3f()
localDeltaQuat.getEulerAnglesXYZ(euler) // Angles are in radians
// Convert to degrees
val pitchDegrees = Math.toDegrees(euler.x.toDouble()) // Rotation around X axis = pitch
val yawDegrees = Math.toDegrees(euler.y.toDouble()) // Rotation around Y axis = yaw
val rollDegrees = Math.toDegrees(euler.z.toDouble()) // Rotation around Z axis = roll
//Scale rotation delta by 20 to represent degree per second instead of tick
angDelta = Vec3(pitchDegrees, yawDegrees, rollDegrees).scale(20.0)
/******************************************************
* Calculate ride local velocity
*****************************************************/
val velocityWorldF = Vector3f(currentVelocity.x.toFloat(), currentVelocity.y.toFloat(), currentVelocity.z.toFloat())
val localVelocityF = Matrix3f(orientation).transpose().transform(velocityWorldF)
val localVelocity = Vec3(localVelocityF.x.toDouble(), localVelocityF.y.toDouble(), localVelocityF.z.toDouble())
localVelocitySpring.update(localVelocity, stiffness, damping)
// Update previous values
prevOrientation.set(currOrientation)
} else {
val currPitch = entity.xRot
val currYaw = entity.yRot
val currRoll = 0.0f
currRot = Vec3(currPitch.toDouble(), currYaw.toDouble(), currRoll.toDouble())
//Scale rotation delta by 20 to represent degree per second instead of tick
angDelta = Vec3(
(currRot.x - prevRot.x),
Mth.degreesDifference(currRot.y.toFloat(), prevRot.y.toFloat()).toDouble(),
Mth.degreesDifference(currRot.z.toFloat(), prevRot.z.toFloat()).toDouble()
).scale(20.0)
/******************************************************
* Calculate ride local velocity
*****************************************************/
val yaw360 = -1.0 * (entity.yRot + 360.0f) % 360.0f
val orientationNonRollable = Matrix3f().rotateY(yaw360.toRadians())
//Convert to Vector3f
var velocityWorldF = Vector3f(currentVelocity.x.toFloat(), currentVelocity.y.toFloat(), currentVelocity.z.toFloat())
val localVelocityF = Matrix3f(orientationNonRollable).transpose().transform(velocityWorldF)
val localVelocity = Vec3(localVelocityF.x.toDouble(), localVelocityF.y.toDouble(), localVelocityF.z.toDouble())
localVelocitySpring.update(localVelocity, stiffness, damping)
}
/******************************************************
* Update springs
*****************************************************/
rotDeltaSpring.update(angDelta, stiffness, damping)
velocitySpring.update(currentVelocity, stiffness, damping)
rotSpring.update(currRot, stiffness, damping)
prevRot = currRot
}
}
@@ -1,68 +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.api.riding.util
import net.minecraft.world.phys.Vec3
import kotlin.math.min
/**
* A spring-based smoother for Vec3 values, designed for applying damped spring motion to riding data.
* Stores the previous and current values, along with a history buffer for lookback-based interpolation.
*
* @author Jackowes
* @since March 27th, 2025
*/
class Vec3Spring(
var value: Vec3 = Vec3.ZERO,
var velocity: Vec3 = Vec3.ZERO
) {
val history = ArrayDeque<Vec3>()
//Hold up to a seconds worth of values
val lookBackSize = 20
fun update(target: Vec3, stiffness: Double, damping: Double) {
//Hooke's Law f = kx where:
//f is force
//k is the spring constant or stiffness of this spring
//x is the distance from rest and in this case the difference between the most recent
//rotation delta ( the target ) and the springs current value for delta rot
val force = target.subtract(value).scale(stiffness)
//Now calculate acceleration and apply damping
val accel = force.subtract(velocity.scale(damping))
velocity = velocity.add(accel.scale(1.0/20.0))
value = value.add(velocity.scale(1.0/20.0))
history.addFirst(value)
//Adding one since if we want to check max look back point it needs something to interp with.
if( history.size > lookBackSize + 1) {
history.removeLast()
}
}
fun getInterpolated(partialTick: Double, lookBackTick: Int): Vec3 {
if (history.size < 2) {
return value // or Vec3.ZERO if you prefer
}
val tick = min(lookBackTick, history.size - 2)
var ret = Vec3.ZERO
for( i in 0..tick) {
val older = history.get(i + 1).scale(1.0)
val newer = history.get(i).scale(1.0)
ret = ret.add(older.add(newer.subtract(older).scale(partialTick)))
}
return ret.scale(1.0/(tick+1))
}
}
@@ -1,77 +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
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.util.Mth
import net.minecraft.world.phys.Vec3
/**
* This class is responsible for setting up the animation state of a Pokemon entity before it begins to render.
*
* Sometimes we depend on the animation state of the Pokemon to be set up before we begin rendering it, so this class
* allows us to do that. It also caches which Pokemon have been pre-animated to avoid doing it multiple times.
*
* @author landonjw
*/
object MountedPokemonAnimationRenderController {
private val forcedDeltas = mutableMapOf<Int, Float>()
fun setup(pokemon: PokemonEntity, partialTickTime: Float) {
if (forcedDeltas.contains(pokemon.id)) return
val delegate = pokemon.delegate as? PokemonClientDelegate ?: return
val model = delegate.currentModel ?: return
if (!model.isReadyForAnimation()) return
val entityPos = Vec3(
Mth.lerp(partialTickTime.toDouble(), pokemon.xOld, pokemon.x),
Mth.lerp(partialTickTime.toDouble(), pokemon.yOld, pokemon.y),
Mth.lerp(partialTickTime.toDouble(), pokemon.zOld, pokemon.z)
)
val f = Mth.rotLerp(partialTickTime, pokemon.yBodyRotO, pokemon.yBodyRot)
val g = Mth.rotLerp(partialTickTime, pokemon.yHeadRotO, pokemon.yHeadRot)
var h = g - f
val j = Mth.lerp(partialTickTime, pokemon.xRotO, pokemon.xRot)
h = Mth.wrapDegrees(h)
var l = 0.0f
var m = 0.0f
if (!pokemon.isPassenger && pokemon.isAlive) {
l = pokemon.walkAnimation.speed(partialTickTime)
m = pokemon.walkAnimation.position(partialTickTime)
if (pokemon.isBaby) {
m *= 3.0f
}
if (l > 1.0f) {
l = 1.0f
}
}
delegate.updatePartialTicks(partialTickTime)
delegate.updateLocatorPosition(entityPos)
delegate.currentModel?.applyAnimations(pokemon, delegate, l, m, partialTickTime, j, h)
forcedDeltas[pokemon.id] = partialTickTime
}
fun getPartialTick(pokemon: PokemonEntity) : Float? {
return forcedDeltas[pokemon.id]
}
/**
* Resets the prerendered list. This should be called in the render loop before we begin setting up any pokemon with `setup`.
*/
fun reset() {
forcedDeltas.clear()
}
}
@@ -0,0 +1,5 @@
package com.cobblemon.mod.common.client
object Test {
var locked: Boolean = true
}
@@ -34,11 +34,7 @@ import com.cobblemon.mod.common.client.render.pokemon.PokemonRenderer.Companion.
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.net.messages.server.pokemon.update.ServerboundUpdateRidingStatePacket
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.MovingSoundInstance
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.resolve
import com.cobblemon.mod.common.util.*
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.Minecraft
import net.minecraft.network.syncher.EntityDataAccessor
@@ -349,12 +345,9 @@ class PokemonClientDelegate : PosableState(), PokemonSideDelegate {
runtime.environment.query = struct
}
override fun updateAge(age: Int) {
this.age = age
}
override fun initialize(entity: PokemonEntity) {
this.currentEntity = entity
this.age = entity.tickCount
this.runtime.environment.query.addFunctions(mapOf(
"in_battle" to java.util.function.Function {
@@ -98,13 +98,13 @@ class CobblemonConfigIntVariable(
override fun getConfigValueAsString(): String = (config.getter.call(parent.parent.clonedConfig) as Int?).toString()
init {
editBox.setFilter { value -> value.toIntOrNull() != null || value.isBlank() || value == "-" }
editBox.setFilter { value -> value.toIntOrNull() != null || value.isBlank() }
editBox.setResponder { value ->
if (value.isBlank()) {
return@setResponder
}
val intValue = value.toIntOrNull() ?: return@setResponder
val intValue = value.toInt()
setConfigValue(intValue, false)
if (intConstraintAnnotation != null) {
@@ -129,7 +129,7 @@ class CobblemonConfigFloatVariable(
override fun getConfigValueAsString(): String = (config.getter.call(parent.parent.clonedConfig) as Float?).toString()
init {
editBox.setFilter { value -> value.toFloatOrNull() != null || value.isBlank() || value == "." || value == "-" }
editBox.setFilter { value -> value.toFloatOrNull() != null || value.isBlank() }
editBox.setResponder { value ->
if (value.toFloatOrNull() != null) {
setConfigValue(value.toFloat(), false)
@@ -145,7 +145,7 @@ class CobblemonConfigDoubleVariable(
override fun getConfigValueAsString(): String = (config.getter.call(parent.parent.clonedConfig) as Double?).toString()
init {
editBox.setFilter { value -> value.toDoubleOrNull() != null || value.isBlank() || value == "." || value == "-" }
editBox.setFilter { value -> value.toDoubleOrNull() != null || value.isBlank() }
editBox.setResponder { value ->
if (value.toDoubleOrNull() != null) {
setConfigValue(value.toDouble(), false)
@@ -125,7 +125,6 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
private lateinit var markingsWidget: MarkingsWidget
private val summaryTabs = mutableListOf<SummaryTab>()
private var showCosmeticItem = false
private lateinit var heldItemVisibilityButton: SummaryButton
private var mainScreenIndex = INFO
var sideScreenIndex = PARTY
private val party = ArrayList(party)
@@ -182,7 +181,7 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
)
//Item Visibility Button
heldItemVisibilityButton = SummaryButton(
val HeldItemVisibilityButton = SummaryButton(
buttonX = x + 3F,
buttonY = y + 104F,
buttonWidth = 32,
@@ -192,7 +191,7 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
activeResource = itemHiddenResource,
clickAction = {
selectedPokemon.heldItemVisible = !selectedPokemon.heldItemVisible
heldItemVisibilityButton.buttonActive = !selectedPokemon.heldItemVisible
(it as SummaryButton).buttonActive = !selectedPokemon.heldItemVisible
modelWidget.heldItem = if (selectedPokemon.heldItemVisible) selectedPokemon.heldItem else null
// Send item visibility update to server
sendToServer(SetItemHiddenPacket(selectedPokemon.uuid, selectedPokemon.heldItemVisible))
@@ -200,8 +199,8 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
renderRequirement = { !selectedPokemon.heldItemNoCopy().isEmpty && !showCosmeticItem },
clickRequirement = { !selectedPokemon.heldItemNoCopy().isEmpty && !showCosmeticItem }
)
heldItemVisibilityButton.buttonActive = !selectedPokemon.heldItemVisible
addRenderableWidget(heldItemVisibilityButton)
addRenderableWidget(HeldItemVisibilityButton)
// Held/Cosmetic Item Button
addRenderableWidget(
@@ -332,7 +331,6 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
if (::modelWidget.isInitialized) {
modelWidget.pokemon = selectedPokemon.asRenderablePokemon()
modelWidget.heldItem = if (selectedPokemon.heldItemVisible) selectedPokemon.heldItem else null
heldItemVisibilityButton.buttonActive = !selectedPokemon.heldItemVisible
}
if (::nicknameEntryWidget.isInitialized) nicknameEntryWidget.setSelectedPokemon(selectedPokemon)
@@ -18,6 +18,7 @@ import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraft.world.phys.Vec3
import org.joml.Quaternionf
import org.joml.Vector3f
@@ -113,13 +114,12 @@ class ModelWidget(
)
heldItemRenderer.renderOnModel(
heldItem?: ItemStack.EMPTY,
state.currentModel!!,
heldItem?: ItemStack.EMPTY,
state,
matrices,
context.bufferSource(),
light = 0xF000F0,
true
Vec3(0.0,-90.0,-90.0)
)
matrices.popPose()
@@ -11,12 +11,9 @@ package com.cobblemon.mod.common.client.render.item
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
import com.cobblemon.mod.common.api.tags.CobblemonItemTags.WEARABLE_FACE_ITEMS
import com.cobblemon.mod.common.api.tags.CobblemonItemTags.WEARABLE_HAT_ITEMS
import com.cobblemon.mod.common.client.entity.NPCClientDelegate
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.MatrixWrapper
import com.cobblemon.mod.common.client.render.models.blockbench.PosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.Minecraft
@@ -27,7 +24,7 @@ import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.item.ItemDisplayContext
import net.minecraft.world.item.ItemStack
import org.joml.Vector3f
import net.minecraft.world.phys.Vec3
class HeldItemRenderer {
private val itemRenderer: ItemRenderer = Minecraft.getInstance().itemRenderer
@@ -37,91 +34,133 @@ class HeldItemRenderer {
const val ITEM_FACE = "item_face"
const val ITEM_HAT = "item_hat"
const val ITEM = "item"
private fun PoseStack.setOriginAndScale(x:Float,y:Float,z:Float,scale:Float=1f) {
this.translate(x*.0625*scale, y*.0625*scale, z*.0625*scale)
this.scale(scale, scale, scale)
}
}
fun renderOnModel(
item: ItemStack,
model: PosableModel,
state: PosableState,
poseStack: PoseStack,
buffer: MultiBufferSource,
light: Int = LightTexture.pack(11, 7),
frontLight: Boolean = false,
entity: LivingEntity? = null
) {
if (!item.`is`(CobblemonItemTags.HIDDEN_ITEMS)) renderAtLocator(item, model, state, entity, poseStack, buffer, light, 0, frontLight)
state.animationItems.forEach { (targetLocator, item) -> renderAtLocator(item, model, state, entity, poseStack, buffer, light, 0, frontLight, targetLocator) }
}
private fun renderAtLocator(
item: ItemStack,
model: PosableModel,
state: PosableState,
fun render(
entity: LivingEntity?,
model: PosableModel,
item: ItemStack,
locators: Map<String, MatrixWrapper>,
poseStack: PoseStack,
buffer: MultiBufferSource,
light: Int,
seed: Int,
frontLight: Boolean = false,
targetLocator: String =
if (item.`is`(WEARABLE_FACE_ITEMS) && state.locatorStates.containsKey(ITEM_FACE)) ITEM_FACE
else if (item.`is`(WEARABLE_HAT_ITEMS) && state.locatorStates.containsKey(ITEM_HAT)) ITEM_HAT
else ITEM
rotation: Vec3
) {
if (item.isEmpty) return
displayContext = ItemDisplayContext.FIXED
if (state.locatorStates.containsKey(targetLocator)) {
poseStack.pushPose()
when {
//item_face locator
(locators.containsKey(ITEM_FACE) && item.`is`(WEARABLE_FACE_ITEMS)) -> {
displayContext = model.getLocatorDisplayContext(ITEM_FACE) ?: ItemDisplayContext.HEAD
poseStack.mulPose(locators[ITEM_FACE]!!.matrix)
poseStack.translate(0f, 0f, .28f)
poseStack.scale(0.7f, 0.7f, 0.7f)
}
//item_hat locator
(locators.containsKey(ITEM_HAT) && item.`is`(WEARABLE_HAT_ITEMS)) -> {
displayContext = model.getLocatorDisplayContext(ITEM_HAT) ?: ItemDisplayContext.HEAD
poseStack.mulPose(locators[ITEM_HAT]!!.matrix)
poseStack.translate(0f, -0.26f, 0f)
poseStack.scale(.68f, .68f, .68f)
}
//item locator
(locators.containsKey(ITEM)) -> {
displayContext = model.getLocatorDisplayContext(ITEM) ?: ItemDisplayContext.FIXED
poseStack.mulPose(locators[ITEM]!!.matrix)
applyContextTransformation(poseStack, rotation)
}
// Don't render any item
else -> {
poseStack.popPose()
return
}
}
itemRenderer.renderStatic(entity, item, displayContext, (displayContext==ItemDisplayContext.THIRD_PERSON_LEFT_HAND), poseStack, buffer, null, light, OverlayTexture.NO_OVERLAY, seed)
poseStack.popPose()
}
private fun renderAnimationItem(
model: PosableModel,
state: PosableState,
locators: Map<String, MatrixWrapper>,
poseStack: PoseStack,
buffer: MultiBufferSource,
light: Int,
entity: LivingEntity?,
rotation: Vec3
) {
state.itemRenderingLocations.forEach { (locatorName, item) ->
poseStack.pushPose()
RenderSystem.applyModelViewMatrix()
displayContext = model.getLocatorDisplayContext(targetLocator)?:
if ((item.`is`(WEARABLE_FACE_ITEMS) && targetLocator==ITEM_FACE) || (item.`is`(WEARABLE_HAT_ITEMS) && targetLocator== ITEM_HAT)) ItemDisplayContext.HEAD
else ItemDisplayContext.FIXED
poseStack.mulPose(state.locatorStates[targetLocator]!!.matrix)
when (displayContext) {
ItemDisplayContext.FIXED -> {
poseStack.setOriginAndScale(0f,.5f,0f, .5f)
poseStack.mulPose(Axis.XP.rotationDegrees(90.0f))
}
ItemDisplayContext.THIRD_PERSON_RIGHT_HAND, ItemDisplayContext.THIRD_PERSON_LEFT_HAND -> {
//For Minecraft player models
if (state is NPCClientDelegate) {
poseStack.mulPose(Axis.XP.rotationDegrees(-90.0F))
}
//for T-Posing Models
else if (state is PokemonClientDelegate || state is FloatingState) {
poseStack.mulPose(Axis.YP.rotationDegrees(-90.0F))
poseStack.mulPose(Axis.ZP.rotationDegrees(90.0F))
}
poseStack.translate(0.025f * if (displayContext==ItemDisplayContext.THIRD_PERSON_LEFT_HAND) 1 else -1 , 0.0f, 0.0f)
}
ItemDisplayContext.HEAD -> {
if (state is NPCClientDelegate) {
if (item.`is`(WEARABLE_FACE_ITEMS)) poseStack.setOriginAndScale(0f,-2f,7.25f, 0.62f)
else if (item.`is`(WEARABLE_HAT_ITEMS)) poseStack.setOriginAndScale(0f,-10.25f,0f, 0.62f)
}
else {
if (item.`is`(WEARABLE_FACE_ITEMS)) poseStack.setOriginAndScale(0f,1f,(7.25f)-.5f, 0.62f)
else if (item.`is`(WEARABLE_HAT_ITEMS)) poseStack.setOriginAndScale(0f,(-7.25f)+.5f,0f, 0.62f)
}
}
else -> {}
if (locators.containsKey(locatorName)) {
displayContext = model.getLocatorDisplayContext(locatorName)?: ItemDisplayContext.FIXED
poseStack.mulPose(locators[locatorName]!!.matrix)
applyContextTransformation(poseStack, rotation)
}
//Render front lighting for UI Models
if (frontLight) {
RenderSystem.setShaderLights(Vector3f(0F,0F,1F), Vector3f(0F,0F,1F))
}
itemRenderer.renderStatic(entity, item, displayContext, (displayContext==ItemDisplayContext.THIRD_PERSON_LEFT_HAND), poseStack, buffer, null, light, OverlayTexture.NO_OVERLAY, seed)
itemRenderer.renderStatic(entity, item, displayContext, (displayContext==ItemDisplayContext.THIRD_PERSON_LEFT_HAND), poseStack, buffer, null, light, OverlayTexture.NO_OVERLAY, 0)
poseStack.popPose()
}
}
fun renderOnModel(
model: PosableModel,
item: ItemStack,
state: PosableState,
poseStack: PoseStack,
buffer: MultiBufferSource,
rotation: Vec3 = Vec3(0.0,0.0,0.0),
light: Int = LightTexture.pack(11, 7),
) {
val locators: Map<String, MatrixWrapper> = state.locatorStates
if (state.itemRenderingLocations.isNotEmpty()) {
renderAnimationItem(model, state, locators, poseStack, buffer, light, null, rotation)
}
else if (!item.`is`(CobblemonItemTags.HIDDEN_ITEMS)) {
render(null, model, item, locators, poseStack, buffer, light, 0, rotation)
}
}
fun renderOnEntity(
entity: LivingEntity,
item: ItemStack,
model: PosableModel,
state: PosableState,
poseStack: PoseStack,
buffer: MultiBufferSource,
light: Int,
rotation: Vec3 = Vec3(0.0,0.0,0.0)
) {
val locators: Map<String, MatrixWrapper> = state.locatorStates
if (state.itemRenderingLocations.isNotEmpty()) {
renderAnimationItem(model, state, locators, poseStack, buffer, light, entity, rotation)
}
else {
render(entity, model, item, locators, poseStack, buffer, light, 0, rotation)
}
}
private fun applyContextTransformation(poseStack: PoseStack, rotation: Vec3) {
when (displayContext) {
ItemDisplayContext.FIXED -> {
poseStack.mulPose(Axis.XP.rotationDegrees(90.0f))
poseStack.scale(.5f, .5f, .5f )
poseStack.translate(0f, 0.01666f, 0f)
}
ItemDisplayContext.THIRD_PERSON_RIGHT_HAND, ItemDisplayContext.THIRD_PERSON_LEFT_HAND -> {
poseStack.mulPose(Axis.XP.rotationDegrees((rotation.x).toFloat()))
poseStack.mulPose(Axis.YP.rotationDegrees((rotation.y).toFloat()))
poseStack.mulPose(Axis.ZP.rotationDegrees((rotation.z).toFloat()))
poseStack.translate(0.025f * if (displayContext==ItemDisplayContext.THIRD_PERSON_LEFT_HAND) 1 else -1 , 0.0f, 0.0f)
}
ItemDisplayContext.HEAD -> {
poseStack.mulPose(Axis.XP.rotationDegrees(90.0f))
poseStack.scale(.6f, .6f, .6f)
poseStack.translate(0f, -0.6f, 0f)
}
else -> {}
}
}
}
@@ -37,6 +37,7 @@ import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.phys.Vec3
class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent<T, PlayerModel<T>>) : RenderLayer<T, PlayerModel<T>>(renderLayerParent) {
@@ -161,12 +162,12 @@ class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent
}
heldItemRenderer.renderOnModel(
shoulderData.shownItem,
model,
shoulderData.shownItem,
state,
matrixStack,
buffer,
packedLight
Vec3(0.0,-90.0,-90.0)
)
model.setDefault()
@@ -17,6 +17,7 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.addFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.client.ClientMoLangFunctions.animationFunctions
import com.cobblemon.mod.common.client.ClientMoLangFunctions.setupClient
import com.cobblemon.mod.common.client.Test
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.AnimatedModelTextureSupplier
import com.cobblemon.mod.common.client.render.ModelLayer
@@ -590,6 +591,9 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
headYaw: Float,
headPitch: Float
) {
if (entity is PokemonEntity && entity.passengers.contains(Minecraft.getInstance().player) && Test.locked) {
return
}
context.put(RenderContext.ENTITY, entity)
setupEntityTypeContext(entity)
state.currentModel = this
@@ -827,6 +831,4 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
condition = condition,
animations = { animations(it) }
)
fun isReadyForAnimation() = ::context.isInitialized
}
@@ -35,10 +35,8 @@ import com.cobblemon.mod.common.client.render.models.blockbench.quirk.ModelQuirk
import com.cobblemon.mod.common.client.render.models.blockbench.quirk.QuirkData
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.mojang.brigadier.StringReader
import com.mojang.brigadier.exceptions.CommandSyntaxException
import net.minecraft.client.Minecraft
import net.minecraft.client.multiplayer.ClientLevel
import net.minecraft.client.resources.sounds.SimpleSoundInstance
@@ -48,6 +46,7 @@ import net.minecraft.sounds.SoundSource
import net.minecraft.world.entity.Entity
import net.minecraft.world.item.ItemStack
import net.minecraft.world.phys.Vec3
import org.joml.Matrix4f
import java.util.*
import java.util.concurrent.ConcurrentLinkedQueue
@@ -129,140 +128,12 @@ abstract class PosableState : Schedulable {
/** This gets called 500 million times so use a mutable value for runtime */
private val reusableAnimTime = DoubleValue(0.0)
/** A list of items to be rendered on a PosableModel during an animation */
val animationItems = mutableMapOf<String, ItemStack>()
/** All of the MoLang functions that can be expose current riding data. */
val ridingFunctions = QueryStruct(hashMapOf())
.addFunction("pitch") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickPitch = pokemon.ridingAnimationData.rotSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).x
val maxPitch = 90.0
return@addFunction DoubleValue((partialTickPitch / maxPitch).coerceIn(-1.0,1.0))
}
.addFunction("yaw") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickYaw = pokemon.ridingAnimationData.rotSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).y
val maxYaw = 180.0
return@addFunction DoubleValue((partialTickYaw / maxYaw).coerceIn(-1.0,1.0))
}
.addFunction("roll") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickRoll = pokemon.ridingAnimationData.rotSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).z
val maxRoll = 180.0
return@addFunction DoubleValue((partialTickRoll / maxRoll).coerceIn(-1.0,1.0))
}
.addFunction("pitch_change") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickPitchDelta = pokemon.ridingAnimationData.rotDeltaSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).x
//TODO: hook back up the retrieval of the current behaviors stat for this and the following functions
val maxRotRate = 140.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SKILL)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickPitchDelta / maxRotRate).coerceIn(-1.0,1.0))
}
.addFunction("yaw_change") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickYawDelta = pokemon.ridingAnimationData.rotDeltaSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).y
//TODO: make this not hardcoded
val maxRotRate = 140.0 //pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SKILL)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickYawDelta / maxRotRate).coerceIn(-1.0,1.0))
}
.addFunction("roll_change") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickRollDelta = pokemon.ridingAnimationData.rotDeltaSpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).z
val maxRotRate = 140.0 //pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SKILL)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickRollDelta / maxRotRate).coerceIn(-1.0,1.0))
}
.addFunction("speed") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickSpeed = pokemon.ridingAnimationData.velocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).length()
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickSpeed / topSpeed).coerceIn(-1.0,1.0))
}
.addFunction("velocity_x") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickXVel = pokemon.ridingAnimationData.velocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).x
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickXVel / topSpeed).coerceIn(-1.0,1.0))
}
.addFunction("velocity_y") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickYVel = pokemon.ridingAnimationData.velocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).y
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickYVel / topSpeed).coerceIn(-1.0,1.0))
}
.addFunction("velocity_z") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickZVel = pokemon.ridingAnimationData.velocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).z
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickZVel / topSpeed).coerceIn(-1.0,1.0))
}
.addFunction("velocity_right") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickZVel = pokemon.ridingAnimationData.localVelocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).x
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickZVel / topSpeed).coerceIn(-1.0,1.0) * -1.0)
}
.addFunction("velocity_upward") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickZVel = pokemon.ridingAnimationData.localVelocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).y
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickZVel / topSpeed).coerceIn(-1.0,1.0))
}
.addFunction("velocity_forward") { params ->
val lookBackTick = params.getInt(0)
val pokemon = getEntity() as? PokemonEntity ?: return@addFunction DoubleValue(0.0)
val partialTickZVel = pokemon.ridingAnimationData.localVelocitySpring.getInterpolated(currentPartialTicks.toDouble(), lookBackTick).z
val topSpeed = 1.0//pokemon.riding.getController(pokemon)?.getStat(pokemon, RidingStat.SPEED)
//?: return@addFunction DoubleValue(0.0)
return@addFunction DoubleValue((partialTickZVel / topSpeed).coerceIn(-1.0,1.0))
}
val itemRenderingLocations = mutableMapOf<String, ItemStack>()
// var itemRenderingLocation = ""
// var animationItem : ItemStack? = null
/** All of the MoLang functions that can be applied to something with this state. */
val functions = QueryStruct(hashMapOf(
"riding" to java.util.function.Function { ridingFunctions },
"r" to java.util.function.Function { ridingFunctions }
))
val functions = QueryStruct(hashMapOf())
.addFunction("anim_time") {
reusableAnimTime.value = animationSeconds.toDouble()
reusableAnimTime
@@ -288,27 +159,21 @@ abstract class PosableState : Schedulable {
.addFunction("render_item") { params ->
if (params.get<MoValue>(0) !is StringValue) return@addFunction Unit
val item: ItemStack
try {
val client = Minecraft.getInstance().connection ?: return@addFunction Unit
val result = ItemParser(client.registryAccess()).parse(StringReader(params.getString(0)))
item = ItemStack(result.item)
item.applyComponents(result.components)
}
catch (_: CommandSyntaxException) {
return@addFunction Unit
}
val client = Minecraft.getInstance().connection ?: return@addFunction Unit
val result = ItemParser(client.registryAccess()).parse(StringReader(params.getString(0)))
val item = ItemStack(result.item)
item.applyComponents(result.components)
val renderLocation = if (params.contains(1)) params.getString(1) else "item"
if (!item.isEmpty && locatorStates.containsKey(renderLocation)) {
animationItems.put(renderLocation, item)
itemRenderingLocations.put(renderLocation, item)
} else {
if (animationItems.containsKey(renderLocation)) animationItems.remove(renderLocation)
if (itemRenderingLocations.containsKey(renderLocation)) itemRenderingLocations.remove(renderLocation)
return@addFunction Unit
}
}
.addFunction("clear_items") { animationItems.clear() }
.addFunction("clear_items") { itemRenderingLocations.clear() }
.addFunction("play_animation") { params ->
val animationParameter = params.get<MoValue>(0)
val animation = if (animationParameter is ObjectValue<*>) {
@@ -8,13 +8,17 @@
package com.cobblemon.mod.common.client.render.models.blockbench
import com.cobblemon.mod.common.client.Test
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.client.renderer.RenderType
import com.mojang.blaze3d.vertex.VertexConsumer
import net.minecraft.client.renderer.entity.LivingEntityRenderer
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.Minecraft
import net.minecraft.client.model.EntityModel
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.LivingEntity
@@ -34,6 +38,7 @@ abstract class PosableEntityModel<T : Entity>(
val context: RenderContext = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.WORLD)
}
lateinit var posableModel: PosableModel
override fun renderToBuffer(
@@ -76,25 +81,11 @@ abstract class PosableEntityModel<T : Entity>(
) {
setupEntityTypeContext(entity)
if (entity is PosableEntity) {
val ticks = getTicksForAnimation(entity, limbSwing, limbSwingAmount, ageInTicks, headYaw, headPitch)
posableModel.applyAnimations(entity, entity.delegate as PosableState, limbSwing, limbSwingAmount, ticks, headYaw, headPitch)
val state = entity.delegate as PosableState
posableModel.applyAnimations(entity, state, limbSwing, limbSwingAmount, ageInTicks, headYaw, headPitch)
}
}
/**
* This is to support cases where the ageInTicks value that should go to the animator is not the same as the entity's
* normal value. This can happen in the case of riding where it has been rendered in a different part of the pipeline
* and we want to prevent stuttering / re-render it for a specific moment.
*/
open fun getTicksForAnimation(
entity: T,
limbSwing: Float,
limbSwingAmount: Float,
ageInTicks: Float,
headYaw: Float,
headPitch: Float
): Float = ageInTicks
open fun setupEntityTypeContext(entity: Entity?) {
entity?.let {
context.put(RenderContext.ENTITY, entity)
@@ -8,16 +8,12 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon
import com.cobblemon.mod.common.client.MountedPokemonAnimationRenderController
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.models.blockbench.PosableEntityModel
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.util.Mth
import net.minecraft.world.entity.Entity
import net.minecraft.world.phys.Vec3
class PosablePokemonEntityModel : PosableEntityModel<PokemonEntity>() {
override fun setupEntityTypeContext(entity: Entity?) {
@@ -30,28 +26,4 @@ class PosablePokemonEntityModel : PosableEntityModel<PokemonEntity>() {
.let { texture -> context.put(RenderContext.TEXTURE, texture) }
}
}
// TODO: This is a bit of a hack, but it works for now. We should find a better way to do this.
override fun getTicksForAnimation(
entity: PokemonEntity,
limbSwing: Float,
limbSwingAmount: Float,
ageInTicks: Float,
headYaw: Float,
headPitch: Float
): Float {
val delegate = entity.delegate as? PosableState
val forcedTick = MountedPokemonAnimationRenderController.getPartialTick(entity)
if (entity.passengers.isEmpty() || delegate == null || forcedTick == null) {
return ageInTicks
}
delegate.updatePartialTicks(forcedTick)
val entityPos = Vec3(
Mth.lerp(forcedTick.toDouble(), entity.xOld, entity.x),
Mth.lerp(forcedTick.toDouble(), entity.yOld, entity.y),
Mth.lerp(forcedTick.toDouble(), entity.zOld, entity.z)
)
delegate.updateLocatorPosition(entityPos)
return forcedTick
}
}
@@ -0,0 +1,72 @@
/*
* 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.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
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.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class GrovyleModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame {
override val rootPart = root.registerChildWithAllChildren("grovyle")
override val head = getPart("head")
override val leftLeg = getPart("left_upper_leg")
override val rightLeg = getPart("right_upper_leg")
override var portraitScale = 2.31F
override var portraitTranslation = Vec3(-0.24, 1.29, 0.0)
override var profileScale = 0.66F
override var profileTranslation = Vec3(0.01, 0.87, 0.0)
//lateinit var sleep: CobblemonPose
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("grovyle", "cry") }
override fun registerPoses() {
//sleep = registerPose(
// poseType = PoseType.SLEEP,
// animations = arrayOf(bedrock("grovyle", "sleep"))
//)
val blink = quirk { bedrockStateful("grovyle", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("grovyle", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("grovyle", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
)
)
}
//override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
//) = if (state.isNotPosedIn(sleep)) bedrockStateful("grovyle", "faint") else null
}
@@ -8,11 +8,11 @@
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
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.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
@@ -38,7 +38,6 @@ class LudicoloModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame,
lateinit var floating: Pose
lateinit var swim: Pose
lateinit var sleep: Pose
lateinit var dance: Pose
override fun registerPoses() {
val blink = quirk { bedrockStateful("ludicolo", "blink") }
@@ -88,17 +87,6 @@ class LudicoloModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame,
)
)
dance = registerPose(
poseName = "dance",
poseType = PoseType.DANCE,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("ludicolo", "dance"),
)
)
}
override fun getFaintAnimation(state: PosableState) = if (state.isNotPosedIn(sleep)) bedrockStateful("ludicolo", "faint") else null
}
}
@@ -0,0 +1,95 @@
/*
* 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.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.util.isBattling
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class MetagrossModel (root: ModelPart) : PokemonPosableModel(root) {
override val rootPart = root.registerChildWithAllChildren("metagross")
override var portraitScale = 1.1F
override var portraitTranslation = Vec3(-0.45, 0.5, 0.0)
override var profileScale = 0.4F
override var profileTranslation = Vec3(0.0, 1.0, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var hover: Pose
lateinit var fly: Pose
lateinit var sleep: Pose
lateinit var battleidle: Pose
override val cryAnimation = CryProvider { bedrockStateful("metagross", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("metagross", "blink")}
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("metagross", "sleep"))
)
standing = registerPose(
poseName = "stand",
poseTypes = PoseType.STATIONARY_POSES - PoseType.HOVER - PoseType.FLOAT + PoseType.UI_POSES,
condition = { !it.isBattling },
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metagross", "ground_idle")
)
)
hover = registerPose(
poseName = "hover",
poseTypes = setOf(PoseType.HOVER, PoseType.FLOAT),
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metagross", "air_idle")
)
)
fly = registerPose(
poseName = "fly",
poseTypes = setOf(PoseType.FLY, PoseType.SWIM),
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metagross", "air_fly")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES - PoseType.FLY - PoseType.SWIM,
transformTicks = 5,
quirks = arrayOf(blink),
animations = arrayOf(
bedrock("metagross", "ground_walk")
)
)
battleidle = registerPose(
poseName = "battle_idle",
poseTypes = PoseType.STATIONARY_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
condition = { it.isBattling },
animations = arrayOf(
bedrock("metagross", "battle_idle")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("metagross", "faint") else null
}
@@ -0,0 +1,72 @@
/*
* 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.gen3
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
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.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SceptileModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame {
override val rootPart = root.registerChildWithAllChildren("sceptile")
override val head = getPart("head")
override val leftLeg = getPart("left_upper_leg")
override val rightLeg = getPart("right_upper_leg")
override var portraitScale = 2.34F
override var portraitTranslation = Vec3(-0.25, 2.22, 0.0)
override var profileScale = 0.63F
override var profileTranslation = Vec3(0.06, 0.91, 0.0)
lateinit var sleep: CobblemonPose
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("sceptile", "cry") }
override fun registerPoses() {
// sleep = registerPose(
// poseType = PoseType.SLEEP,
// animations = arrayOf(bedrock("sceptile", "sleep"))
// )
val blink = quirk { bedrockStateful("sceptile", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("sceptile", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("sceptile", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
)
)
}
//override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
//) = if (state.isNotPosedIn(sleep)) bedrockStateful("sceptile", "faint") else null
}
@@ -0,0 +1,66 @@
/*
* 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.gen3
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.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class TreeckoModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame {
override val rootPart = root.registerChildWithAllChildren("treecko")
override val head = getPart("head")
override var portraitScale = 2.25F
override var portraitTranslation = Vec3(0.02, 0.12, 0.0)
override var profileScale = 0.74F
override var profileTranslation = Vec3(0.0, 0.6, 0.0)
lateinit var sleep: CobblemonPose
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("treecko", "cry") }
override fun registerPoses() {
//sleep = registerPose(
// poseType = PoseType.SLEEP,
// animations = arrayOf(bedrock("treecko", "sleep"))
//)
val blink = quirk { bedrockStateful("treecko", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES + PoseType.SLEEP,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("treecko", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("treecko", "ground_walk"),
)
)
}
//override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
//) = if (state.isNotPosedIn(sleep)) bedrockStateful("treecko", "faint") else null
}
@@ -38,7 +38,6 @@ class AmbipomModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, B
lateinit var walking: Pose
lateinit var sleep: Pose
lateinit var battleidle: Pose
lateinit var dancing: Pose
override val cryAnimation = CryProvider { bedrockStateful("ambipom", "cry") }
@@ -51,7 +50,8 @@ class AmbipomModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, B
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.UI_POSES + PoseType.STAND,
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
condition = { !it.isBattling },
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
@@ -80,20 +80,10 @@ class AmbipomModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, B
bedrock("ambipom", "ground_idle")
)
)
dancing = registerPose(
poseName = "dancing",
poseType = PoseType.DANCE,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("ambipom", "dance")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("ambipom", "faint") else null
}
}
@@ -0,0 +1,76 @@
/*
* 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.gen7
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.frame.QuadrupedFrame
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
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 MudsdaleModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, QuadrupedFrame {
override val rootPart = root.registerChildWithAllChildren("mudsdale")
override val head = getPart("neck")
override val foreLeftLeg = getPart("leg_front_left")
override val foreRightLeg = getPart("leg_front_right")
override val hindLeftLeg = getPart("leg_back_left")
override val hindRightLeg = getPart("leg_back_right")
override var portraitScale = 1.5F
override var portraitTranslation = Vec3(-1.0, 1.76, 0.0)
override var profileScale = 0.5F
override var profileTranslation = Vec3(0.0, 1.0, 0.0)
lateinit var standing: Pose
lateinit var walk: Pose
lateinit var sleep: Pose
override val cryAnimation = CryProvider { bedrockStateful("mudsdale", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("mudsdale", "blink") }
sleep = registerPose(
poseType = PoseType.SLEEP,
animations = arrayOf(bedrock("mudsdale", "sleep"))
)
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(disableY = true),
bedrock("mudsdale", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
transformTicks = 10,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(disableY = true),
bedrock("mudsdale", "ground_walk")
)
)
}
// override fun getFaintAnimation(
// pokemonEntity: PokemonEntity,
// state: PosableState<PokemonEntity>
// ) = if (state.isPosedIn(standing, walk)) bedrockStateful("mudsdale", "faint") else null
}
@@ -0,0 +1,69 @@
/*
* 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.animation.BimanualSwingAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.animation.BipedWalkAnimation
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
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.CobblemonPose
import com.cobblemon.mod.common.entity.PoseType
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.world.phys.Vec3
class SneaslerModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
override val rootPart = root.registerChildWithAllChildren("sneasler")
override val head = getPart("head")
override val leftArm = getPart("arm_left")
override val rightArm = getPart("arm_right")
override val leftLeg = getPart("leg_left")
override val rightLeg = getPart("leg_right")
override var portraitScale = 2.03F
override var portraitTranslation = Vec3(-0.44, 2.41, 0.0)
override var profileScale = 0.52F
override var profileTranslation = Vec3(0.0, 0.94, 0.0)
lateinit var standing: CobblemonPose
lateinit var walk: CobblemonPose
override val cryAnimation = CryProvider { bedrockStateful("sneasler", "cry") }
override fun registerPoses() {
val blink = quirk { bedrockStateful("sneasler", "blink") }
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("sneasler", "ground_idle")
)
)
walk = registerPose(
poseName = "walk",
poseTypes = PoseType.MOVING_POSES,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
bedrock("sneasler", "ground_idle"),
BipedWalkAnimation(this, periodMultiplier = 0.6F, amplitudeMultiplier = 0.9F),
BimanualSwingAnimation(this, swingPeriodMultiplier = 0.6F, amplitudeMultiplier = 0.9F)
//bedrock("sneasler", "ground_walk")
)
)
}
}
@@ -404,6 +404,9 @@ object VaryingModelRepository {
inbuilt("klinklang", :: KlinklangModel)
inbuilt("morelull", :: MorelullModel)
inbuilt("shiinotic", :: ShiinoticModel)
inbuilt("treecko", :: TreeckoModel)
inbuilt("grovyle", :: GrovyleModel)
inbuilt("sceptile", :: SceptileModel)
inbuilt("honedge", :: HonedgeModel)
inbuilt("spiritomb", :: SpiritombModel)
inbuilt("chespin", :: ChespinModel)
@@ -481,6 +484,7 @@ object VaryingModelRepository {
inbuilt("taillow", ::TaillowModel)
inbuilt("swellow", ::SwellowModel)
inbuilt("mudbray", ::MudbrayModel)
inbuilt("mudsdale", ::MudsdaleModel)
inbuilt("comfey", ::ComfeyModel)
inbuilt("tandemaus", ::TandemausModel)
inbuilt("maushold", ::MausholdModel)
@@ -638,6 +642,7 @@ object VaryingModelRepository {
inbuilt("gallade", ::GalladeModel)
inbuilt("beldum", ::BeldumModel)
inbuilt("metang", ::MetangModel)
inbuilt("metagross", ::MetagrossModel)
inbuilt("ursaluna", ::UrsalunaModel)
inbuilt("lechonk", ::LechonkModel)
inbuilt("oinkologne_male", ::OinkologneMaleModel)
@@ -697,6 +702,7 @@ object VaryingModelRepository {
inbuilt("qwilfish_hisuian", ::QwilfishHisuianModel)
inbuilt("overqwil", ::OverqwilModel)
inbuilt("sneasel_hisuian", ::SneaselHisuianModel)
inbuilt("sneasler", ::SneaslerModel)
inbuilt("petilil", ::PetililModel)
inbuilt("lilligant", ::LilligantModel)
inbuilt("petilil_hisui_bias", ::PetililHisuiBiasModel)
@@ -20,6 +20,7 @@ import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.entity.EntityRendererProvider.Context
import net.minecraft.client.renderer.entity.LivingEntityRenderer
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.phys.Vec3
import kotlin.math.min
class NPCRenderer(context: Context) : LivingEntityRenderer<NPCEntity, PosableEntityModel<NPCEntity>>(context, PosableNPCModel(), 0.5f) {
@@ -59,17 +60,17 @@ class NPCRenderer(context: Context) : LivingEntityRenderer<NPCEntity, PosableEnt
model.blue = 1F
model.resetLayerContext()
if (entity.deathTime < 1) {
if (entity.deathTime < 1){
//Render Held Item
heldItemRenderer.renderOnModel(
heldItemRenderer.renderOnEntity(
entity,
entity.mainHandItem,
model,
clientDelegate,
poseMatrix,
buffer,
packedLight,
false,
entity
Vec3(-90.0,0.0,0.0)
)
}
@@ -11,17 +11,17 @@ package com.cobblemon.mod.common.client.render.player
import com.bedrockk.molang.runtime.value.DoubleValue
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.riding.Rideable
import com.cobblemon.mod.common.client.MountedPokemonAnimationRenderController
import com.cobblemon.mod.common.client.Test
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.models.blockbench.bedrock.animation.BedrockAnimationRepository
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.Minecraft
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.client.player.AbstractClientPlayer
import net.minecraft.util.Mth
import net.minecraft.world.phys.Vec3
import org.joml.AxisAngle4f
import org.joml.Matrix4f
import org.joml.Vector3f
@@ -42,7 +42,12 @@ object MountedPlayerRenderer {
//Positions player
if (locator != null) {
MountedPokemonAnimationRenderController.setup(entity, partialTicks)
val locatorOffset = locator.matrix.getTranslation(Vector3f())
val center = Vector3f(0f, entity.bbHeight/2, 0f)
val locatorOffsetToCenter = locatorOffset.sub(center, Vector3f())
val offset = locatorOffsetToCenter.add(center, Vector3f()).sub(Vector3f(0f, player.bbHeight / 2, 0f))
matrix.translate(offset)
//Undo seat position
val playerPos = Vec3(
@@ -58,16 +63,20 @@ object MountedPlayerRenderer {
)
matrix.translate(playerPos.subtract(entityPos).toVector3f().negate())
matrix.translate(locator.matrix.getTranslation(Vector3f()))
val offset = Vector3f(0f, player.bbHeight / 2, 0f).mul(-1f)
matrix.rotate(locator.matrix.getRotation(AxisAngle4f()))
matrix.rotate(Axis.YP.rotationDegrees(180 + yBodyRot))
matrix.translate(offset)
matrix.translate(Vector3f(0f, 0.35f, 0f))
}
//Rotates player
if (player is OrientationControllable && player.orientationController.active && !disableRollableRenderDebug) {
val center = Vector3f(0f, player.bbHeight / 2, 0f)
val transformationMatrix = Matrix4f()
transformationMatrix.translate(center)
transformationMatrix.rotate(player.orientationController.getRenderOrientation(partialTicks))
transformationMatrix.translate(center.negate(Vector3f()))
//Pre-Undo Yaw
transformationMatrix.rotate(Axis.YP.rotationDegrees(yBodyRot+180f))
matrix.mul(transformationMatrix)
}
matrix.translate(0f, 0.25f, 0f)
}
fun animate(
@@ -159,15 +159,15 @@ class PokemonRenderer(
// Minecraft.getInstance().bufferBuilders.entityVertexConsumers.draw()
//Render Held Item
heldItemRenderer.renderOnModel(
heldItemRenderer.renderOnEntity(
entity,
entity.shownItem,
modelNow,
model.posableModel,
clientDelegate,
poseMatrix,
buffer,
packedLight,
false,
entity
Vec3(0.0,-90.0,90.0)
)
}
@@ -280,9 +280,6 @@ class CobblemonConfig {
@CobblemonConfigField(Category.Debug, lang = "enable_debug_keys")
var enableDebugKeys = false
@CobblemonConfigField(Category.Pokemon, lang="pokemon_dance_distance")
var pokemonDanceDistance = 3.0
fun clone(): CobblemonConfig {
val newConfig = CobblemonConfig()
CobblemonConfig::class.memberProperties.forEach { property ->
@@ -9,9 +9,8 @@
package com.cobblemon.mod.common.entity
import com.cobblemon.mod.common.util.cobblemonResource
import java.util.*
import net.minecraft.resources.ResourceLocation
import java.util.EnumSet
import java.util.Locale
/**
* The type of a pose. Used for normalizing pose swapping for all models.
@@ -28,7 +27,6 @@ enum class PoseType {
FLOAT,
SWIM,
GLIDE,
DANCE,
/** A pose for rendering on the left shoulder. Pose animations are given the player head yaw, pitch, and ageInTicks. */
SHOULDER_LEFT,
/** A pose for rendering on the right shoulder. Pose animations are given the player head yaw, pitch, and ageInTicks. */
@@ -49,7 +49,6 @@ import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviours
import com.cobblemon.mod.common.api.riding.events.SelectDriverEvent
import com.cobblemon.mod.common.api.riding.stats.RidingStat
import com.cobblemon.mod.common.api.riding.util.RidingAnimationData
import com.cobblemon.mod.common.api.scheduling.Schedulable
import com.cobblemon.mod.common.api.scheduling.SchedulingTracker
import com.cobblemon.mod.common.api.scheduling.afterOnServer
@@ -252,7 +251,6 @@ open class PokemonEntity(
var enablePoseTypeRecalculation = true
val ridingAnimationData: RidingAnimationData = RidingAnimationData()
var previousRidingState: RidingBehaviourState? = null
var ridingState: RidingBehaviourState? = null
@@ -285,9 +283,9 @@ open class PokemonEntity(
ridingBehaviourSettings = null
if (pokemon.riding.behaviour == null) return
riding = RidingBehaviours.get(pokemon.riding.behaviour!!.key)
riding = RidingBehaviours.get(pokemon.riding.behaviour!!.key) as RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState>?
ridingState = riding!!.createDefaultState()
ridingBehaviourSettings = pokemon.riding.behaviour!!
ridingState = riding!!.createDefaultState(ridingBehaviourSettings!!)
}
/**
@@ -356,11 +354,10 @@ open class PokemonEntity(
}
var flyDistO = 0F
var isPokemonWalking = false
var isPokemonFlying = false
var tickSpawned = 0
init {
delegate.initialize(this)
delegate.changePokemon(pokemon)
@@ -485,11 +482,6 @@ open class PokemonEntity(
entityData.get(MOVING)
super.tick()
if (passengers.isNotEmpty()) {
ridingAnimationData.update(this)
}
flyDistO = flyDist
if (isBattling) {
@@ -1019,15 +1011,12 @@ open class PokemonEntity(
itemStack
)
if (player.isShiftKeyDown) {
val canRide = ifRidingAvailableSupply(false) { behaviour, settings, state ->
this.canRide(player) && seats.isNotEmpty() && behaviour.isActive(settings, state, this)
}
InteractPokemonUIPacket(
this.getUUID(),
canSitOnShoulder() && pokemon in player.party(),
!(pokemon.heldItemNoCopy().isEmpty && itemStack.isEmpty),
(!pokemon.cosmeticItem.isEmpty && itemStack.isEmpty) || cosmeticItemDefinition != null,
canRide
this.canRide(player) && pokemon.riding.canRide
).sendToPlayer(player)
} else {
// TODO #105
@@ -1247,7 +1236,6 @@ open class PokemonEntity(
else -> lang("held_item.replace", returned.displayName, this.pokemon.getDisplayName(), giving.displayName)
}
player.giveOrDropItemStack(returned, false)
player.sendSystemMessage(text)
this.level().playSoundServer(
position = this.position(),
@@ -1572,8 +1560,6 @@ open class PokemonEntity(
inp.z * g.toDouble() + inp.x * f.toDouble()
)
val diff = v.subtract(this.deltaMovement)
val inertia = ifRidingAvailableSupply(fallback = 0.5) { behaviour, settings, state ->
@@ -1933,7 +1919,7 @@ open class PokemonEntity(
// }
override fun onPassengerTurned(entityToUpdate: Entity) {
if (entityToUpdate !is LivingEntity) return
if (entityToUpdate !is LivingEntity) return
ifRidingAvailable { behaviour, settings, state ->
behaviour.clampPassengerRotation(settings, state, this, entityToUpdate)
}
@@ -1951,22 +1937,6 @@ open class PokemonEntity(
}
}
// When riding mimic RemotePlayers logic for rendering players at farther
// distances than usual. Otherwise the player may render when the pokemon
// entity is not, causing a floating player.
override fun shouldRenderAtSqrDistance(distance: Double): Boolean {
if (!passengers.isEmpty()) {
var d = (boundingBox.getSize() * 10.0)
if (d.isNaN()) {
d = 1.0
}
val scale = 64.0 * getViewScale()
return distance < d * scale * scale
}
return super.shouldRenderAtSqrDistance(distance)
}
override fun getControllingPassenger(): LivingEntity? {
val riders = this.passengers.filterIsInstance<LivingEntity>()
if (riders.isEmpty()) {
@@ -2130,4 +2100,4 @@ open class PokemonEntity(
override fun resolveEntityScan(): LivingEntity {
return this
}
}
}
@@ -8,15 +8,10 @@
package com.cobblemon.mod.common.entity.pokemon
import com.bedrockk.molang.runtime.struct.QueryStruct
import com.bedrockk.molang.runtime.value.DoubleValue
import com.bedrockk.molang.runtime.value.MoValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.OrientationControllable
import com.cobblemon.mod.common.api.entity.PokemonSender
import com.cobblemon.mod.common.api.entity.PokemonSideDelegate
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.stats.Stats
import com.cobblemon.mod.common.api.pokemon.status.Statuses
@@ -26,14 +21,11 @@ import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.activestate.ActivePokemonState
import com.cobblemon.mod.common.pokemon.activestate.SentOutState
import com.cobblemon.mod.common.util.asUUID
import com.cobblemon.mod.common.util.getIsSubmerged
import com.cobblemon.mod.common.util.math.geometry.toRadians
import com.cobblemon.mod.common.util.playSoundServer
import com.cobblemon.mod.common.util.toVec3d
import com.cobblemon.mod.common.util.update
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
import net.minecraft.core.BlockPos
import net.minecraft.network.chat.Component
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.server.level.ServerLevel
@@ -42,20 +34,16 @@ import net.minecraft.world.damagesource.DamageSource
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.ai.attributes.Attributes
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.entity.JukeboxBlockEntity
import net.minecraft.world.level.pathfinder.PathType
import org.joml.Matrix3f
import org.joml.Vector3f
import java.util.Optional
import java.util.*
/** Handles purely server logic for a Pokémon */
class PokemonServerDelegate : PokemonSideDelegate {
lateinit var entity: PokemonEntity
var acknowledgedHPStat = -1
var dancing: Boolean = false
var jukeboxPos: BlockPos? = null
/** Mocked properties exposed to the client [PokemonEntity]. */
private val mock: PokemonProperties?
get() = entity.effects.mockEffect?.mock
@@ -114,32 +102,6 @@ class PokemonServerDelegate : PokemonSideDelegate {
updateTrackedValues()
}
override fun addToStruct(struct: QueryStruct) {
super.addToStruct(struct)
if (entity.pokemon.isWild()) {
struct
.addFunction("attempt_wild_battle") { params ->
val opponentValue = params.get<MoValue>(0)
val opponent = if (opponentValue is ObjectValue<*>) {
opponentValue.obj as ServerPlayer
} else {
val paramString = opponentValue.asString()
val playerUUID = paramString.asUUID
if (playerUUID != null) {
entity.server!!.playerList.getPlayer(playerUUID) ?: return@addFunction DoubleValue.ZERO
} else {
entity.server!!.playerList.getPlayerByName(paramString) ?: return@addFunction DoubleValue.ZERO
}
}
// Need to wait to ensure any entity info gets grabbed properly before battle attempt.
return@addFunction entity.after(0.01F) {
DoubleValue(entity.forceBattle(opponent))
}
}
}
}
fun getBattle() = entity.battleId?.let(BattleRegistry::getBattle)
fun updateTrackedValues() {
@@ -272,15 +234,6 @@ class PokemonServerDelegate : PokemonSideDelegate {
val isPassenger = entity.isPassenger
val isUnderwater = entity.getIsSubmerged()
val isFlying = entity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)
var isDancing = false
if (jukeboxPos != null) {
val level = entity.level()
val jukeboxBlockEntity = if (level.isLoaded(jukeboxPos!!)) level.getBlockEntity(jukeboxPos) as? JukeboxBlockEntity
else null
val distanceToJukebox = jukeboxPos?.toVec3d()?.distanceTo(entity.position())
isDancing = jukeboxBlockEntity?.songPlayer?.isPlaying == true && (distanceToJukebox ?: 100.0) < Cobblemon.config.pokemonDanceDistance
}
val poseType = when {
isPassenger -> PoseType.STAND
@@ -290,7 +243,6 @@ class PokemonServerDelegate : PokemonSideDelegate {
isMoving && isFlying -> PoseType.FLY
isFlying -> PoseType.HOVER
isMoving -> PoseType.WALK
isDancing -> PoseType.DANCE
else -> PoseType.STAND
}
@@ -1,25 +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.item
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.EquipmentSlot
import net.minecraft.world.item.Equipable
class WearableItem(val name: String): CobblemonItem(Properties()), Equipable {
companion object {
const val MODEL_PATH = "item/wearable"
}
fun getModel3d(): ResourceLocation = cobblemonResource("${MODEL_PATH}/${this.name}")
fun getModel2d(): ResourceLocation = cobblemonResource(this.name)
override fun getEquipmentSlot(): EquipmentSlot { return EquipmentSlot.HEAD }
}
@@ -10,8 +10,10 @@ package com.cobblemon.mod.common.net.messages.client.pokemon.update
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
import com.cobblemon.mod.common.net.messages.server.pokemon.update.ServerboundUpdateRidingStatePacket
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.network.FriendlyByteBuf
import com.cobblemon.mod.common.util.server
import net.minecraft.client.Minecraft
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
@@ -19,7 +21,7 @@ class ClientboundUpdateRidingStatePacket(
val entity: Int,
val behaviour: ResourceLocation,
val state: RidingBehaviourState? = null,
val data: FriendlyByteBuf? = null
val data: RegistryFriendlyByteBuf? = null
) : NetworkPacket<ClientboundUpdateRidingStatePacket> {
override val id = ID
@@ -35,7 +37,7 @@ class ClientboundUpdateRidingStatePacket(
fun decode(buffer: RegistryFriendlyByteBuf): ClientboundUpdateRidingStatePacket {
val entity = buffer.readInt()
val behaviour = buffer.readResourceLocation()
val state = FriendlyByteBuf(buffer.readBytes(buffer.readableBytes()))
val state = RegistryFriendlyByteBuf(buffer.readBytes(buffer.readableBytes()), Minecraft.getInstance().player!!.registryAccess())
return ClientboundUpdateRidingStatePacket(
entity = entity,
behaviour = behaviour,
@@ -48,7 +48,6 @@ class SpawnPokemonPacket(
var friendship: Int,
var freezeFrame: Float,
var passengers: IntArray,
var tickSpawned: Int,
vanillaSpawnPacket: ClientboundAddEntityPacket,
) : SpawnExtraDataEntityPacket<SpawnPokemonPacket, PokemonEntity>(vanillaSpawnPacket) {
@@ -77,7 +76,6 @@ class SpawnPokemonPacket(
entity.entityData.get(PokemonEntity.FRIENDSHIP),
entity.entityData.get(PokemonEntity.FREEZE_FRAME),
entity.passengers.map { it.id }.toIntArray(),
entity.tickCount,
vanillaSpawnPacket
)
@@ -104,7 +102,6 @@ class SpawnPokemonPacket(
buffer.writeInt(this.friendship)
buffer.writeFloat(this.freezeFrame)
buffer.writeVarIntArray(this.passengers)
buffer.writeInt(this.tickSpawned)
}
override fun applyData(entity: PokemonEntity, level: ClientLevel) {
@@ -139,8 +136,6 @@ class SpawnPokemonPacket(
val passenger = level.getEntity(it) ?: return@forEach
passenger.startRiding(entity)
}
entity.tickSpawned = this.tickSpawned
entity.delegate.updateAge(this.tickSpawned)
}
override fun checkType(entity: Entity): Boolean = entity is PokemonEntity
@@ -170,10 +165,9 @@ class SpawnPokemonPacket(
val friendship = buffer.readInt()
val freezeFrame = buffer.readFloat()
val passengers = buffer.readVarIntArray()
val tickSpawned = buffer.readInt()
val vanillaPacket = decodeVanillaPacket(buffer)
return SpawnPokemonPacket(ownerId, scaleModifier, speciesId, gender, shiny, formName, aspects, battleId, phasingTargetId, beamModeEmitter, platform, nickname, mark, labelLevel, poseType, unbattlable, hideLabel, caughtBall, spawnAngle, friendship, freezeFrame, passengers, tickSpawned, vanillaPacket)
return SpawnPokemonPacket(ownerId, scaleModifier, speciesId, gender, shiny, formName, aspects, battleId, phasingTargetId, beamModeEmitter, platform, nickname, mark, labelLevel, poseType, unbattlable, hideLabel, caughtBall, spawnAngle, friendship, freezeFrame, passengers, vanillaPacket)
}
}
@@ -16,7 +16,6 @@ import com.google.gson.JsonObject
import com.mojang.serialization.JsonOps
import net.minecraft.core.component.DataComponentMap
import java.lang.reflect.Type
import kotlin.jvm.optionals.getOrNull
/**
* A JSON deserializer for [PossibleHeldItem].
@@ -33,7 +32,9 @@ object PossibleHeldItemAdapter : JsonDeserializer<PossibleHeldItem> {
)
} else {
json as JsonObject
val componentMap = JsonOps.INSTANCE.withDecoder(DataComponentMap.CODEC).apply(json.get("nbt")).result().getOrNull()?.first
val componentMap = JsonOps.INSTANCE.withDecoder(DataComponentMap.CODEC).apply(json.get("nbt")).getOrThrow {
return@getOrThrow IllegalStateException("Cant serialize components for held item")
}.first
val item = json.get("item").asString
val percentage = json.get("percentage")?.asDouble ?: 100.0
return PossibleHeldItem(
@@ -10,12 +10,6 @@ package com.cobblemon.mod.common.util.adapters
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.*
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies.FallCompositeSettings
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies.FallStrategy
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies.JumpStrategy
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.strategies.RunStrategy
import com.cobblemon.mod.common.util.asIdentifierDefaultingNamespace
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
@@ -29,42 +23,26 @@ import java.lang.reflect.Type
* @author landonjw
*/
object RidingBehaviourSettingsAdapter : JsonDeserializer<RidingBehaviourSettings> {
val types: MutableMap<ResourceLocation, Class<out RidingBehaviourSettings>> = mutableMapOf(BirdAirBehaviour.KEY to BirdAirSettings::class.java,
val types: MutableMap<ResourceLocation, Class<out RidingBehaviourSettings>> = mutableMapOf(
BirdAirBehaviour.KEY to BirdAirSettings::class.java,
DolphinBehaviour.KEY to DolphinSettings::class.java,
FallToGlideCompositeBehaviour.KEY to FallToGlideCompositeSettings::class.java,
GenericLandBehaviour.KEY to GenericLandSettings::class.java,
GenericSwimBehaviour.KEY to GenericSwimSettings::class.java,
GliderAirBehaviour.KEY to GliderAirSettings::class.java,
HelicopterBehaviour.KEY to HelicopterSettings::class.java,
JetAirBehaviour.KEY to JetAirSettings::class.java,
JumpToFlightCompositeBehaviour.KEY to JumpToFlightCompositeSettings::class.java,
RunToJetCompositeBehaviour.KEY to RunToJetCompositeSettings::class.java,
SwimDashBehaviour.KEY to SwimDashSettings::class.java,
VehicleLandBehaviour.KEY to VehicleLandSettings::class.java,
HoverBehaviour.KEY to HoverSettings::class.java,
CompositeBehaviour.KEY to CompositeSettings::class.java,
/*
Strategy registration. if you do not register a strategy here, it will not be deserialized.
Register to CompositeSettings if you do not need to define a subclass.
*/
FallStrategy.key to FallCompositeSettings::class.java,
JumpStrategy.key to CompositeSettings::class.java,
RunStrategy.key to CompositeSettings::class.java,
VehicleLandBehaviour.KEY to VehicleLandSettings::class.java
)
override fun deserialize(element: JsonElement, type: Type, context: JsonDeserializationContext): RidingBehaviourSettings {
val root = element.asJsonObject
val key = root.get("key").asString
val keyIdentifier = key.asIdentifierDefaultingNamespace()
if (keyIdentifier == CompositeBehaviour.KEY) {
val strategy = root.get("transitionStrategy").asString
val strategyIdentifier = strategy.asIdentifierDefaultingNamespace()
val behaviourType = types[strategyIdentifier] ?: throw IllegalArgumentException("Unknown strategy for composite behaviour: $strategy")
val settings: RidingBehaviourSettings = context.deserialize(root, behaviourType)
return settings
}
else {
val behaviourType = types[keyIdentifier] ?: throw IllegalArgumentException("Unknown behaviour: $key")
val settings: RidingBehaviourSettings = context.deserialize(element, behaviourType)
return settings
}
val behaviourType = types[key.asIdentifierDefaultingNamespace()] ?: throw IllegalArgumentException("Unknown controller: $key")
val settings: RidingBehaviourSettings = context.deserialize(element, behaviourType)
return settings
}
}
@@ -1,28 +0,0 @@
{
"format_version": "1.8.0",
"animations": {
"animation.ride_test.sitting": {
"loop": true,
"bones": {
"body": {
"position": [0, -9, 0]
},
"torso": {
"rotation": [25, 0, 0]
},
"arm_right": {
"rotation": [0, 0, 22.5]
},
"arm_left": {
"rotation": [0, 0, -27.5]
},
"leg_right": {
"rotation": [-90, 20, 0]
},
"leg_left": {
"rotation": [-90, -20, 0]
}
}
}
}
}
@@ -2272,59 +2272,23 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"0.5833": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.375": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"3.0": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"5.875": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.4167": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"0.5833": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.0417": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.375": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"3.0": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"5.875": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"0.5833": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.0417": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.375": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"3.0": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"5.875": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.4167": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"0.5833": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.0417": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.375": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"3.0": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"5.875": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
}
}
}
@@ -2589,27 +2553,15 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"1.25": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"3.6667": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
"1.25": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"3.6667": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"1.25": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"3.6667": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
"1.25": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"3.6667": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"jaw": {
@@ -8811,43 +8763,19 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"0.5": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.25": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.4583": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.25": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"0.5": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.25": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.4583": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"0.5": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.25": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.4583": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.25": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"0.5": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.25": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.4583": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
}
}
}
@@ -11293,59 +11221,23 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"0.4167": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"0.8333": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"1.125": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5417": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.6667": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.25": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"0.4167": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"0.8333": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"1.125": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5417": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.6667": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"0.4167": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"0.8333": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"1.125": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5417": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.6667": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.25": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"0.4167": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"0.8333": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"1.125": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5417": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.6667": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"locator_target": {
@@ -13637,43 +13529,19 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"1.2083": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5417": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.7083": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.3333": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"1.2083": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5417": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.7083": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"1.2083": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5417": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.7083": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.3333": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"1.2083": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5417": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.7083": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"locator_mouth": {
@@ -13872,20 +13740,14 @@
"position": {
"0.0": [-0.1, 0.1, 0],
"0.125": [-0.1, 0.1, 0],
"0.1667": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0.1, 0.1, 0],
"0.125": [0.1, 0.1, 0],
"0.1667": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"jaw": {
@@ -14681,7 +14543,7 @@
"rotation": [0, -6, -15]
},
"wing_right_elbow": {
"rotation": [0, "-6+", -15],
"rotation": [0, "-6", -15],
"position": [0.45, 0.1, 0]
},
"wing_right_membrane": {
@@ -16174,7 +16036,7 @@
"animation_length": 4,
"bones": {
"body": {
"rotation": ["22.5 + q.riding.pitch(0)*-90", 0, "math.sin(q.anim_time*90*1-90)*-0.5"],
"rotation": [22.5, 0, "math.sin(q.anim_time*90*1-90)*-0.5"],
"position": ["math.cos(q.anim_time*90*1-60)*1", "12+math.cos((q.anim_time*90*2-60)+math.sin(q.anim_time*90*2)*20)*3", 0]
},
"torso": {
@@ -17495,14 +17357,6 @@
"locator_top": {
"position": [0, 13, 0]
}
},
"sound_effects": {
"1.125": {
"effect": "animation.leather.wing_flap.medium"
},
"3.1667": {
"effect": "animation.leather.wing_flap.medium"
}
}
},
"animation.charizard.air_fly": {
@@ -18779,17 +18633,6 @@
},
"locator_top": {
"position": [0, -1, 0]
},
"locator_seat_1": {
"rotation": [-60, 0, 0]
}
},
"sound_effects": {
"1.0833": {
"effect": "animation.leather.wing_flap.medium"
},
"3.0833": {
"effect": "animation.leather.wing_flap.medium"
}
}
},
@@ -19055,9 +18898,6 @@
},
"locator_top": {
"position": [0, -6, 0]
},
"locator_seat_1": {
"rotation": [-60, 0, 0]
}
}
},
@@ -19257,59 +19097,23 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"0.5833": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.5833": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"3.9167": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"4.0833": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.4167": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"0.5833": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.4167": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.5833": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"3.9167": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"4.0833": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"0.5833": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.5833": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"3.9167": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"4.0833": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.4167": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"0.5833": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.4167": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.5833": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"3.9167": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"4.0833": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
}
}
}
@@ -22654,10 +22458,7 @@
},
"0.5": [0.78, -10.13, 0.45],
"0.5417": [-0.45, -8.03, 0.45],
"0.5833": {
"pre": [-0.45, -8.03, 0.45],
"post": [-0.45, "-7.79+360", 0.45]
},
"0.5833": {"pre": [-0.45, -8.03, 0.45], "post": [-0.45, "-7.79+360", 0.45]},
"0.625": [-2.7, 355.37, 0.45],
"1.0": {
"pre": [-9.46, "10.71+360", 0.5],
@@ -26328,59 +26129,23 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.0833": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"0.3333": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"1.625": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"1.8333": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.625": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.0833": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"0.3333": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"1.625": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"1.8333": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.625": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.0833": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"0.3333": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"1.625": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"1.8333": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.625": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.0833": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"0.3333": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"1.625": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"1.8333": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.625": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"locator_root": {
@@ -29620,15 +29385,9 @@
"brow": {
"position": {
"0.9583": [0, 0, 0],
"1.1667": {
"pre": [0, 0, 0],
"post": [0, 0, -0.3]
},
"1.1667": {"pre": [0, 0, 0], "post": [0, 0, -0.3]},
"2.2917": [0, 0, -0.3],
"2.5417": {
"pre": [0, 0, -0.3],
"post": [0, 0, 0]
}
"2.5417": {"pre": [0, 0, -0.3], "post": [0, 0, 0]}
}
},
"jaw": {
@@ -29963,43 +29722,19 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"1.2083": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.375": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.6667": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.3333": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"1.2083": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.375": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.6667": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"1.2083": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.375": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.6667": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.3333": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"1.2083": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.375": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.6667": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"locator_root": {
@@ -30018,106 +29753,6 @@
}
}
},
"animation.charizard.ride_air_look": {
"loop": true,
"bones": {
"body": {
"rotation": ["q.riding.pitch_change(0)*-0", "q.riding.yaw_change(0)*-15", "q.riding.roll_change(0)*15"]
},
"neck": {
"rotation": ["math.clamp(q.riding.pitch_change(0),-0.5,1.0)*-20", 0, "q.riding.yaw_change(0)*7"]
},
"neck2": {
"rotation": ["math.clamp(q.riding.pitch_change(0),-0.5,1.0)*-12", 0, "q.riding.yaw_change(0)*12"]
},
"neck3": {
"rotation": ["q.riding.pitch_change(0)*-7", 0, "q.riding.yaw_change(0)*7"]
},
"neck4": {
"rotation": ["q.riding.pitch_change(0)*-7", 0, "q.riding.yaw_change(0)*7"]
},
"head_angle": {
"rotation": ["q.riding.pitch_change(0)*-7", 0, "q.riding.yaw_change(0)*7"]
},
"shoulder_right": {
"rotation": [0, "-12.5*q.riding.pitch_change(0)", "27.5*q.riding.yaw_change(0)"]
},
"arm_right": {
"rotation": [0, "15*q.riding.yaw_change(0)", 0]
},
"forearm_right": {
"rotation": [0, "15*q.riding.yaw_change(0)", "-12.5*q.riding.pitch_change(0)"]
},
"shoulder_left": {
"rotation": [0, "12.5*q.riding.pitch_change(0)", "27.5*q.riding.yaw_change(0)"]
},
"arm_left": {
"rotation": [0, "15*q.riding.yaw_change(0)", 0]
},
"forearm_left": {
"rotation": [0, "15*q.riding.yaw_change(0)", "12.5*q.riding.pitch_change(0)"]
},
"wing_right_base": {
"rotation": ["-5*q.riding.pitch_change(0)", 0, 0]
},
"wing_right_bend": {
"rotation": ["10*q.riding.yaw_change(0)", "7.5*q.riding.pitch_change(0)", "10*q.riding.yaw_change(0)"]
},
"wing_right_mid": {
"rotation": ["-5*q.riding.pitch_change(0)", 0, 0]
},
"wing_right_elbow": {
"rotation": ["-2.5*q.riding.pitch_change(0)", "5*q.riding.pitch_change(0)", 0]
},
"wing_left_base": {
"rotation": ["-5*q.riding.pitch_change(0)", 0, 0]
},
"wing_left_bend": {
"rotation": ["-10*q.riding.yaw_change(0)", "-7.5*q.riding.pitch_change(0)", "-10*q.riding.yaw_change(0)"]
},
"wing_left_mid": {
"rotation": ["-5*q.riding.pitch_change(0)", 0, 0]
},
"wing_left_elbow": {
"rotation": ["-2.5*q.riding.pitch_change(0)", "-(5*q.riding.pitch_change(0))", 0]
},
"tail": {
"rotation": ["q.riding.pitch_change(0)*7", 0, "q.riding.yaw_change(0)*-10"]
},
"tail2": {
"rotation": ["q.riding.pitch_change(0)*7", "q.riding.yaw_change(0)*15", 0]
},
"tail3": {
"rotation": ["q.riding.pitch_change(0)*7", "q.riding.yaw_change(0)*20", 0]
},
"tail4": {
"rotation": ["q.riding.pitch_change(0)*7", "q.riding.yaw_change(0)*20", 0]
},
"tail5": {
"rotation": ["q.riding.pitch_change(0)*8", "q.riding.yaw_change(0)*20", 0]
},
"leg_right": {
"rotation": ["-12.5*q.riding.pitch_change(0)", "q.riding.yaw_change(0)*20", 0],
"position": ["-1.5*q.riding.yaw_change(0)", 0, 0]
},
"knee_right": {
"rotation": ["-12.5*q.riding.pitch_change(0)", 0, 0]
},
"foot_right": {
"rotation": ["-12.5*q.riding.pitch_change(0)", 0, 0]
},
"leg_left": {
"rotation": ["-12.5*q.riding.pitch_change(0)", "q.riding.yaw_change(0)*20", 0],
"position": ["-1.5*q.riding.yaw_change(0)", 0, 0]
},
"knee_left": {
"rotation": ["-12.5*q.riding.pitch_change(0)", 0, 0]
},
"foot_left": {
"rotation": ["-12.5*q.riding.pitch_change(0)", 0, 0]
}
}
},
"animation.charizard.air_status": {
"animation_length": 3,
"bones": {
@@ -33359,43 +32994,19 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"1.2083": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.2083": {
"pre": [0, 0, 0],
"post": [-0.1, 0.1, 0]
},
"2.4583": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.3333": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"1.2083": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]},
"2.2083": {"pre": [0, 0, 0], "post": [-0.1, 0.1, 0]},
"2.4583": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.3333": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"1.2083": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
},
"2.2083": {
"pre": [0, 0, 0],
"post": [0.1, 0.1, 0]
},
"2.4583": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.3333": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"1.2083": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]},
"2.2083": {"pre": [0, 0, 0], "post": [0.1, 0.1, 0]},
"2.4583": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"locator_root": {
@@ -34821,20 +34432,14 @@
"position": {
"0.0": [-0.1, 0.1, 0],
"0.125": [-0.1, 0.1, 0],
"0.1667": {
"pre": [-0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [-0.1, 0.1, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0.1, 0.1, 0],
"0.125": [0.1, 0.1, 0],
"0.1667": {
"pre": [0.1, 0.1, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0.1, 0.1, 0], "post": [0, 0, 0]}
}
}
}
@@ -535,11 +535,6 @@
}
}
}
},
"sound_effects": {
"0.5": {
"effect": "animation.plumage.wing_flap.medium"
}
}
},
"animation.pidgeot.air_fly": {
@@ -715,9 +710,6 @@
},
"wing_open_right4": {
"rotation": [0, 0, "7.5+math.sin(q.anim_time*90*0.8-240)*-10+math.sin(q.anim_time*90*12-120)*0.4"]
},
"locator_seat1": {
"position": [0, 1.5, -4]
}
}
},
@@ -1574,11 +1566,6 @@
}
}
}
},
"sound_effects": {
"1.375": {
"effect": "animation.plumage.wing_flap.medium"
}
}
},
"animation.pidgeot.air_fly_quirk2": {
@@ -2734,14 +2721,6 @@
}
}
}
},
"sound_effects": {
"1.4583": {
"effect": "animation.plumage.wing_flap.medium"
},
"3.0833": {
"effect": "animation.plumage.wing_flap.medium"
}
}
},
"animation.pidgeot.blink": {
@@ -182,14 +182,6 @@
"rotation": [0, 0, 0]
}
}
},
"animation.eevee.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.eevee.cry"
}
}
}
}
}
@@ -225,14 +225,6 @@
"rotation": [-59.83045, -1.29256, -14.94548]
}
}
},
"animation.vaporeon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.vaporeon.cry"
}
}
}
}
}
@@ -150,14 +150,6 @@
"rotation": [37.5, 37.5, 0]
}
}
},
"animation.jolteon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.jolteon.cry"
}
}
}
}
}
@@ -266,14 +266,6 @@
"rotation": [37.5, 27.5, 0]
}
}
},
"animation.flareon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.flareon.cry"
}
}
}
}
}
@@ -467,7 +467,6 @@
},
"animation.aerodactyl.air_idle": {
"loop": true,
"animation_length": 1.33333,
"bones": {
"aerodactyl": {
"position": [0, 3, 0]
@@ -643,16 +642,10 @@
"right_wing_membrane": {
"rotation": [0, "0+math.sin(q.anim_time*90*3+90)*3", "0+math.sin(q.anim_time*90*3+90)*1.5"]
}
},
"sound_effects": {
"1.0833": {
"effect": "animation.leather.wing_flap.medium"
}
}
},
"animation.aerodactyl.air_fly": {
"loop": true,
"animation_length": 1.33333,
"bones": {
"aerodactyl": {
"position": [0, 3, 0]
@@ -834,11 +827,6 @@
"right_horn": {
"rotation": ["math.sin(q.anim_time*90*12-160)*2", 0, 0]
}
},
"sound_effects": {
"0.9583": {
"effect": "animation.leather.wing_flap.medium"
}
}
},
"animation.aerodactyl.sleep": {
@@ -1237,20 +1237,6 @@
"rotation": ["-math.sin(q.anim_time*90*2-120)*4", 0, 0],
"position": [0, "7.8+math.sin(q.anim_time*90*2)*2", -5.6]
}
},
"sound_effects": {
"1.5": {
"effect": "animation.leather.wing_flap.medium"
},
"3.5": {
"effect": "animation.leather.wing_flap.medium"
},
"5.5": {
"effect": "animation.leather.wing_flap.medium"
},
"7.5": {
"effect": "animation.leather.wing_flap.medium"
}
}
},
"animation.dragonite.water_idle": {
@@ -2067,89 +2053,6 @@
"effect": "pokemon.dragonite.cry"
}
}
},
"animation.dragonite.shock": {
"loop": true,
"bones": {
"pupil_left": {
"scale": [0.7, 0.7, 1]
},
"eye_shine_left": {
"position": [0, -0.5, 0]
},
"pupil_right": {
"scale": [0.7, 0.7, 1]
},
"eye_shine_right": {
"position": [0, -0.5, 0]
},
"jaw": {
"rotation": [27.5, 0, 0]
},
"eye_left": {
"position": [0, 0, 0],
"scale": 1
},
"eye_shocked_left": {
"position": [0.25, 0, -0.26]
},
"eye_shocked_right": {
"position": [-0.125, 0, -0.18]
}
}
},
"animation.dragonite.angry": {
"loop": true,
"bones": {
"eye_angry_left": {
"position": [0.1, 0, -0.1]
},
"eye_shine_left": {
"position": [0, -1, 0]
},
"eye_shine_right": {
"position": [0, -1, 0]
},
"eye_angry_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.dragonite.sad": {
"loop": true,
"bones": {
"eye_sad_left": {
"position": [0.1, 0, -0.1]
},
"eye_sad_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.dragonite.happy": {
"loop": true,
"bones": {
"eyelid_happy_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_happy_right": {
"position": [-0.1, 0, -0.1]
},
"jaw": {
"rotation": [27.5, 0, 0]
}
}
},
"animation.dragonite.hurt": {
"loop": true,
"bones": {
"eyelid_recoil_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_recoil_right": {
"position": [-0.1, 0, -0.1]
}
}
}
}
}
@@ -188,14 +188,6 @@
"rotation": [12.5, 0, 0]
}
}
},
"animation.espeon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.espeon.cry"
}
}
}
}
}
@@ -233,14 +233,6 @@
"rotation": [-20, 0, 0]
}
}
},
"animation.umbreon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.umbreon.cry"
}
}
}
}
}
@@ -2,102 +2,257 @@
"format_version": "1.8.0",
"animations": {
"animation.treecko.test": {
"loop": true,
"animation_length": 1.2,
"bones": {
"head": {
"rotation": [-10, 0, 0],
"position": [0, 0.1, -0.3]
"rotation": [-2.5, 0, 0]
},
"jaw": {
"rotation": [32.5, 0, 0]
"rotation": [42.5, 0, 0]
},
"tail": {
"rotation": [-45, 0, 0],
"position": [0, -0.5, 0]
},
"tail_left": {
"left_tail": {
"rotation": [10, 0, 2.5]
},
"tail_left2": {
"left_tail2": {
"rotation": [17.5, 0, 0]
},
"tail_right": {
"right_tail": {
"rotation": [10, 0, -2.5]
},
"tail_right2": {
"right_tail2": {
"rotation": [15, 0, 0]
},
"arm_left": {
"left_upper_arm": {
"rotation": [0, 0, -5]
},
"hand_left": {
"left_hand": {
"rotation": [0, 0, -57.5]
},
"finger_front_left": {
"left_index_finger": {
"rotation": [0, 0, 20]
},
"finger_front_left2": {
"left_index_finger2": {
"rotation": [0, 0, 45]
},
"finger_back_left": {
"left_pinky_finger": {
"rotation": [0, 0, 20]
},
"finger_back_left2": {
"left_pinky_finger2": {
"rotation": [0, 0, 45]
},
"finger_middle_left": {
"left_middle_finger": {
"rotation": [0, 0, 20]
},
"finger_middle_left2": {
"left_middle_finger2": {
"rotation": [0, 0, 45]
},
"arm_right": {
"right_upper_arm": {
"rotation": [0, 0, 5]
},
"torso": {
"rotation": [7.5, 0, 0]
},
"torso2": {
"upper_torso": {
"rotation": [-5, 0, 0]
},
"neck": {
"rotation": [-5, 0, 0]
},
"hand_right": {
"right_hand": {
"rotation": [0, 0, 57.5]
},
"finger_front_right": {
"right_index_finger": {
"rotation": [0, 0, -20]
},
"finger_front_right2": {
"right_index_finger2": {
"rotation": [0, 0, -45]
},
"finger_back_right": {
"right_pinky_finger": {
"rotation": [0, 0, -20]
},
"finger_back_right2": {
"right_pinky_finger2": {
"rotation": [0, 0, -45]
},
"finger_middle_right": {
"right_middle_finger": {
"rotation": [0, 0, -20]
},
"finger_middle_right2": {
"right_middle_finger2": {
"rotation": [0, 0, -45]
},
"leg_left": {
"left_upper_leg": {
"rotation": [1.18155, -9.91358, -2.38565]
},
"foot_left": {
"left_foot": {
"rotation": [-0.4165, -7.26605, 3.29302]
},
"leg_right": {
"right_upper_leg": {
"rotation": [1.18155, 9.91358, 2.38565]
},
"foot_right": {
"right_foot": {
"rotation": [-0.4165, 7.26605, -3.29302]
}
}
},
"animation.treecko.test2": {
"loop": true,
"bones": {
"torso": {
"rotation": [-4.73298, 2.77592, 27.09295]
},
"tail": {
"rotation": [-6.80313, 33.64286, -11.17316],
"position": [0.25, 0, 0]
},
"left_tail": {
"rotation": [15.32536, 9.84392, 1.79183]
},
"left_tail2": {
"rotation": [15.64835, 14.47267, 4.00563]
},
"right_tail": {
"rotation": [20.05865, 9.84795, 1.74036]
},
"right_tail2": {
"rotation": [17.62876, 9.658, 2.59914]
},
"upper_torso": {
"rotation": [12.06953, 5.56451, -12.40436]
},
"neck": {
"rotation": [3.59647, 22.86202, -3.90796]
},
"head": {
"rotation": [8.6876, -10.06991, 4.69965],
"position": [0, 0, -0.5]
},
"right_pupil": {
"position": [0, 0, -0.5]
},
"left_upper_arm": {
"rotation": [0, 22.5, -25],
"position": [0, 0, 0.25]
},
"left_lower_arm": {
"rotation": [0, 5, 0]
},
"left_hand": {
"rotation": [-17.87814, -19.86103, -49.99202],
"position": [-0.15, 0.05, 0]
},
"left_index_finger": {
"rotation": [0, 5, 20]
},
"left_index_finger2": {
"rotation": [0, 0, 45]
},
"left_pinky_finger": {
"rotation": [0, -5, 20]
},
"left_pinky_finger2": {
"rotation": [0, 0, 45]
},
"left_middle_finger": {
"rotation": [0, 0, 20]
},
"left_middle_finger2": {
"rotation": [0, 0, 45]
},
"right_upper_arm": {
"rotation": [27.9096, 1.08115, 23.32938]
},
"right_lower_arm": {
"rotation": [0, -10, 0]
},
"right_hand": {
"rotation": [8.98458, -4.04496, 42.82624],
"position": [0.15, 0.05, 0]
},
"right_index_finger": {
"rotation": [0, -15, -20]
},
"right_index_finger2": {
"rotation": [0, 0, -45]
},
"right_pinky_finger": {
"rotation": [0, 15, -20]
},
"right_pinky_finger2": {
"rotation": [0, 0, -45]
},
"right_middle_finger": {
"rotation": [0, 0, -20]
},
"right_middle_finger2": {
"rotation": [0, 0, -45]
},
"right_upper_leg": {
"rotation": [-118.81845, 9.91358, 2.38565],
"position": [0, 0.75, -1.25]
},
"right_foot": {
"rotation": [-11.96634, 26.73797, -15.04829]
},
"left_upper_leg": {
"rotation": [-2.91472, -22.08853, 21.08653]
},
"left_foot": {
"rotation": [65.81573, -6.16374, -15.44323]
},
"body": {
"position": [0, 0.75, 0]
},
"right_tail3": {
"rotation": [0, 0, 0]
},
"jaw": {
"rotation": [50, 0, 0]
},
"right_lower_leg": {
"rotation": [70.02991, 6.8466, -10.45577]
},
"right_foot2": {
"rotation": [12.5, 0, 0],
"position": [0, 0, 0.25]
},
"right_toes": {
"rotation": [17.5, 0, 0]
},
"left_lower_leg": {
"rotation": [16.93839, -4.46375, 14.33501]
},
"left_foot2": {
"rotation": [-40.67815, -9.54385, 8.11019]
},
"left_toes": {
"rotation": [-24.91643, -2.11089, -4.53359]
},
"left_pupil": {
"position": [0, 0, 0.5]
},
"right_inner_toe": {
"rotation": [25, -20, 0]
},
"right_outer_toe": {
"rotation": [22.5, 20, 0]
},
"right_middle_toe": {
"rotation": [15, 0, 0]
},
"left_inner_toe": {
"rotation": [-32.5, 0, 0]
},
"left_outer_toe": {
"rotation": [-25, 0, 0]
},
"left_middle_toe": {
"rotation": [-25, 0, 0]
}
}
},
"animation.treecko.ground_idle": {
"loop": true,
"bones": {
@@ -107,19 +262,19 @@
"tail": {
"rotation": [-45, 0, 0]
},
"tail_left": {
"left_tail": {
"rotation": [10, 0, 0]
},
"tail_left2": {
"left_tail2": {
"rotation": [15, 0, 0]
},
"tail_right": {
"right_tail": {
"rotation": [10, 0, 0]
},
"tail_right2": {
"right_tail2": {
"rotation": [15, 0, 0]
},
"torso2": {
"upper_torso": {
"rotation": [-5, 0, 0]
},
"neck": {
@@ -128,106 +283,95 @@
"head": {
"rotation": [2.5, 0, 0]
},
"pupil_right": {
"right_pupil": {
"position": [0, 0, 0]
},
"arm_left": {
"left_upper_arm": {
"rotation": [10.08453, -7.38542, 48.69038]
},
"arm_left2": {
"left_lower_arm": {
"rotation": [0, 42.5, 0]
},
"hand_left": {
"left_hand": {
"rotation": [0, 0, 22.5],
"position": [-0.15, 0.05, 0]
},
"finger_front_left": {
"left_index_finger": {
"rotation": [6.94363, 7.64256, 14.02881]
},
"finger_front_left2": {
"left_index_finger2": {
"rotation": [0, 0, 22.5]
},
"finger_back_left": {
"left_pinky_finger": {
"rotation": [-4.01743, -1.75217, 14.46202]
},
"finger_back_left2": {
"left_pinky_finger2": {
"rotation": [0, 0, 30]
},
"finger_middle_left": {
"left_middle_finger": {
"rotation": [0, 0, 12.5]
},
"finger_middle_left2": {
"left_middle_finger2": {
"rotation": [0, 0, 20]
},
"arm_right": {
"right_upper_arm": {
"rotation": [10.08453, 7.38542, -48.69038]
},
"arm_right2": {
"right_lower_arm": {
"rotation": [0, -42.5, 0]
},
"hand_right": {
"right_hand": {
"rotation": [0, 0, -22.5],
"position": [0.15, 0.05, 0]
},
"finger_front_right": {
"right_index_finger": {
"rotation": [6.94363, -7.64256, -14.02881]
},
"finger_front_right2": {
"right_index_finger2": {
"rotation": [0, 0, -22.5]
},
"finger_back_right": {
"right_pinky_finger": {
"rotation": [-4.01743, 1.75217, -14.46202]
},
"finger_back_right2": {
"right_pinky_finger2": {
"rotation": [0, 0, -30]
},
"finger_middle_right": {
"right_middle_finger": {
"rotation": [0, 0, -12.5]
},
"finger_middle_right2": {
"right_middle_finger2": {
"rotation": [0, 0, -20]
},
"leg_right": {
"right_upper_leg": {
"rotation": [1.18155, 9.91358, 2.38565]
},
"foot_right": {
"right_foot": {
"rotation": [-0.4165, 7.26605, -3.29302]
},
"leg_left": {
"left_upper_leg": {
"rotation": [1.18155, -9.91358, -2.38565]
},
"foot_left": {
"left_foot": {
"rotation": [-0.4165, -7.26605, 3.29302]
},
"stick": {
"rotation": [30, 45, 0],
"scale": 0.7
}
}
},
"animation.treecko.blink": {
"animation_length": 0.1667,
"animation_length": 0.16667,
"bones": {
"eyelid_left": {
"left_eyelid": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": [0.1, 0, 0],
"0.125": {"pre": [0.1, 0, 0], "post": [0.1, 0, 0]},
"0.1667": {"pre": [0.1, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"right_eyelid": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": [-0.1, 0, 0],
"0.125": {"pre": [-0.1, 0, 0], "post": [-0.1, 0, 0]},
"0.1667": {"pre": [-0.1, 0, 0], "post": [0, 0, 0]}
}
},
"eye_right": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": [0.1, 0, 0],
"0.1667": {"pre": [0.1, 0, 0], "post": [0, 0, 0]}
}
}
}
},
@@ -278,25 +422,25 @@
"tail": {
"rotation": ["-42.5+math.sin(q.anim_time*90*8+0)*3", "math.sin(q.anim_time*90*4+60)*10", 0]
},
"tail_left": {
"left_tail": {
"rotation": ["10+math.sin(q.anim_time*90*8-25)*2", "0+math.sin(q.anim_time*90*4+30)*8", 0]
},
"tail_left2": {
"left_tail2": {
"rotation": ["15+math.sin(q.anim_time*90*8-55)*2", "0+math.sin(q.anim_time*90*4+0)*6", 0]
},
"tail_left3": {
"left_tail3": {
"rotation": ["0+math.sin(q.anim_time*90*8-85)*2", "0+math.sin(q.anim_time*90*4-30)*4", 0]
},
"tail_right": {
"right_tail": {
"rotation": ["10+math.sin(q.anim_time*90*8-35)*2", "0+math.sin(q.anim_time*90*4+30)*8", 0]
},
"tail_right2": {
"right_tail2": {
"rotation": ["15+math.sin(q.anim_time*90*8-65)*2", "0+math.sin(q.anim_time*90*4+0)*6", 0]
},
"tail_right3": {
"right_tail3": {
"rotation": ["0+math.sin(q.anim_time*90*8-95)*2", "0+math.sin(q.anim_time*90*4-30)*4", 0]
},
"torso2": {
"upper_torso": {
"rotation": ["-5+math.sin(q.anim_time*90*8+0)*1", "0+math.sin(q.anim_time*90*4+60+180)*5", "0+math.sin(q.anim_time*90*4+60)*3"]
},
"neck": {
@@ -305,66 +449,66 @@
"head": {
"rotation": ["2.5+math.sin(q.anim_time*90*8-60)*1.5", "0+math.sin(q.anim_time*90*4+0)*5", "0+math.sin(q.anim_time*90*4+0+180)*3"]
},
"pupil_right": {
"right_pupil": {
"position": [0, 0, 0]
},
"arm_left": {
"left_upper_arm": {
"rotation": [10.08453, "-7.3854+math.sin(q.anim_time*90*4-90)*25", "48.6904+math.sin(q.anim_time*90*4+0)*2.5"]
},
"arm_left2": {
"left_lower_arm": {
"rotation": [0, "42.5+math.sin(q.anim_time*90*4-120)*20", 0]
},
"hand_left": {
"left_hand": {
"rotation": [0, "0+math.sin(q.anim_time*90*4-150)*2.5", "22.5+math.sin(q.anim_time*90*4-150)*5"],
"position": [-0.15, 0.05, 0]
},
"finger_front_left": {
"left_index_finger": {
"rotation": [6.94363, 7.64256, 14.02881]
},
"finger_front_left2": {
"left_index_finger2": {
"rotation": [0, 0, 22.5]
},
"finger_back_left": {
"left_pinky_finger": {
"rotation": [-4.01743, -1.75217, 14.46202]
},
"finger_back_left2": {
"left_pinky_finger2": {
"rotation": [0, 0, 30]
},
"finger_middle_left": {
"left_middle_finger": {
"rotation": [0, 0, 12.5]
},
"finger_middle_left2": {
"left_middle_finger2": {
"rotation": [0, 0, 20]
},
"arm_right": {
"right_upper_arm": {
"rotation": [10.08453, "7.3854+math.sin(q.anim_time*90*4-90)*25", "-48.6904+math.sin(q.anim_time*90*4+0)*2.5"]
},
"arm_right2": {
"right_lower_arm": {
"rotation": [0, "-42.5+math.sin(q.anim_time*90*4-120)*20", 0]
},
"hand_right": {
"right_hand": {
"rotation": [0, "0+math.sin(q.anim_time*90*4-150)*2.5", "-22.5+math.sin(q.anim_time*90*4-150)*5"],
"position": [0.15, 0.05, 0]
},
"finger_front_right": {
"right_index_finger": {
"rotation": [6.94363, -7.64256, -14.02881]
},
"finger_front_right2": {
"right_index_finger2": {
"rotation": [0, 0, -22.5]
},
"finger_back_right": {
"right_pinky_finger": {
"rotation": [-4.01743, 1.75217, -14.46202]
},
"finger_back_right2": {
"right_pinky_finger2": {
"rotation": [0, 0, -30]
},
"finger_middle_right": {
"right_middle_finger": {
"rotation": [0, 0, -12.5]
},
"finger_middle_right2": {
"right_middle_finger2": {
"rotation": [0, 0, -20]
},
"leg_right": {
"right_upper_leg": {
"rotation": {
"0.0": {
"post": [36.50677, 8.43184, 4.42536],
@@ -414,7 +558,7 @@
}
}
},
"leg_right2": {
"right_lower_leg": {
"rotation": {
"0.0": {
"post": [15, 0, 0],
@@ -442,7 +586,7 @@
}
}
},
"foot_right": {
"right_foot": {
"rotation": {
"0.0": {
"post": [24.37394, 0.4385, -6.40588],
@@ -470,7 +614,7 @@
}
}
},
"foot_right2": {
"right_foot2": {
"rotation": {
"0.0": {
"post": [-30, 0, 0],
@@ -508,7 +652,7 @@
}
}
},
"toes_right": {
"right_toes": {
"rotation": {
"0.0": {
"post": [-42.5, 0, 0],
@@ -546,7 +690,7 @@
}
}
},
"leg_left": {
"left_upper_leg": {
"rotation": {
"0.0": {
"post": [-61.31845, -9.91358, -2.38565],
@@ -596,7 +740,7 @@
}
}
},
"leg_left2": {
"left_lower_leg": {
"rotation": {
"0.0": {
"post": [47.5, 0, 0],
@@ -624,7 +768,7 @@
}
}
},
"foot_left": {
"left_foot": {
"rotation": {
"0.0": {
"post": [-30.4165, -7.26605, 3.29302],
@@ -652,7 +796,7 @@
}
}
},
"foot_left2": {
"left_foot2": {
"rotation": {
"0.0": {
"post": [12.5, 0, 0],
@@ -690,7 +834,7 @@
}
}
},
"toes_right2": {
"left_toes": {
"rotation": {
"0.0": {
"post": [15, 0, 0],
@@ -738,265 +882,6 @@
}
}
},
"animation.treecko.test2": {
"loop": true,
"bones": {
"torso": {
"rotation": [-4.73298, 2.77592, 27.09295]
},
"tail": {
"rotation": [-5.82738, 13.76109, -8.78252],
"position": [0.25, 0, 0]
},
"tail_left": {
"rotation": [17.07306, 24.25643, 6.31117]
},
"tail_left2": {
"rotation": [24.53554, -3.67372, -4.51152]
},
"tail_right": {
"rotation": [20.05865, 9.84795, 1.74036]
},
"tail_right2": {
"rotation": [25.12876, 9.658, 2.59914]
},
"torso2": {
"rotation": [7.06953, 5.56451, -12.40436],
"position": [0, 0, 0.5]
},
"neck": {
"rotation": [0.41092, 23.12473, -12.05132],
"position": [0, 0.5, 0]
},
"head": {
"rotation": [12.80178, -8.52421, -5.3105],
"position": [0, 0.5, -1]
},
"pupil_right": {
"position": [0, 0, -0.5]
},
"arm_left": {
"rotation": [9.29398, -6.81225, -20.04345],
"position": [0, 0.25, 1]
},
"arm_left2": {
"rotation": [0.65426, 4.95712, 7.52832]
},
"hand_left": {
"rotation": [-17.87814, -19.86103, -49.99202],
"position": [-0.15, 0.05, 0]
},
"finger_front_left": {
"rotation": [0, 5, 20]
},
"finger_front_left2": {
"rotation": [0, 0, 45]
},
"finger_back_left": {
"rotation": [0, -5, 20]
},
"finger_back_left2": {
"rotation": [0, 0, 45]
},
"finger_middle_left": {
"rotation": [0, 0, 20]
},
"finger_middle_left2": {
"rotation": [0, 0, 45]
},
"arm_right": {
"rotation": [28.39833, -11.25395, 25.21731],
"position": [0, 3, -3.25]
},
"arm_right2": {
"rotation": [0, -27.5, 0]
},
"hand_right": {
"rotation": [8.98458, -4.04496, 42.82624],
"position": [0.15, 0.05, 0]
},
"finger_front_right": {
"rotation": [24.55654, -22.88323, -18.35198]
},
"finger_front_right2": {
"rotation": [0, 0, -45]
},
"finger_back_right": {
"rotation": [24.23178, 6.06465, 25.68919]
},
"finger_back_right2": {
"rotation": [0, 0, -45]
},
"finger_middle_right": {
"rotation": [0, 0, 15]
},
"finger_middle_right2": {
"rotation": [0, 0, -45]
},
"leg_right": {
"rotation": [-156.31845, 9.91358, 2.38565],
"position": [0, 0.75, -2.25]
},
"foot_right": {
"rotation": [0.53366, 26.73797, -15.04829]
},
"leg_left": {
"rotation": [-2.91472, -22.08853, 21.08653],
"position": [0, -1, 0]
},
"foot_left": {
"rotation": [65.81573, -6.16374, -15.44323]
},
"body": {
"rotation": [0, 32.5, 0],
"position": [0, 1.75, 0]
},
"tail_right3": {
"rotation": [0, 0, 0]
},
"jaw": {
"rotation": [40, 0, 0]
},
"leg_right2": {
"rotation": [77.54738, -0.6465, -10.13344]
},
"foot_right2": {
"rotation": [12.5, 0, 0],
"position": [0, 0, 0.25]
},
"toes_right": {
"rotation": [17.5, 0, 0]
},
"leg_left2": {
"rotation": [16.93839, -4.46375, 14.33501]
},
"foot_left2": {
"rotation": [-35.67815, -9.54385, 8.11019]
},
"toes_right2": {
"rotation": [-24.91643, -2.11089, -4.53359]
},
"toe_inner_right": {
"rotation": [26.9673, -26.74473, -3.82626]
},
"toe_outer_right": {
"rotation": [22.5, 20, 0]
},
"toe_middle_right": {
"rotation": [15, 0, 0]
},
"toe_inner_left": {
"rotation": [-32.5, 0, 0]
},
"toe_outer_left": {
"rotation": [-25, 0, 0]
},
"toe_middle_left": {
"rotation": [-25, 0, 0]
},
"pupil_left": {
"position": [0, 0, 0.5]
},
"eye_shine_left": {
"position": [0, 0, 0.5]
}
}
},
"animation.treecko.eye_wide": {
"loop": true,
"bones": {
"eye_emote_right2": {
"scale": [1, 1.5, 1]
},
"eye_emote_left2": {
"scale": [1, 1.5, 1]
}
}
},
"animation.treecko.happy": {
"loop": true,
"bones": {
"jaw": {
"rotation": [20, 0, 0]
},
"eye_right": {
"position": [0.1, 0, 0]
},
"eye_left": {
"position": [-0.1, 0, 0]
},
"eyelid_happy_left": {
"position": [0.1, 0, 0]
},
"eyelid_happy_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.treecko.angry": {
"loop": true,
"bones": {
"eye_emote_right2": {
"position": [0.1, 0, 0]
},
"pupil_emote_right": {
"position": [0.1, 0, 0]
},
"eye_emote_left2": {
"position": [-0.1, 0, 0]
},
"pupil_emote_left": {
"position": [-0.1, 0, 0]
}
}
},
"animation.treecko.sad": {
"loop": true,
"bones": {
"eye_emote_right": {
"position": [0.1, 0, 0]
},
"eye_emote_left": {
"position": [-0.1, 0, 0]
}
}
},
"animation.treecko.shocked": {
"loop": true,
"bones": {
"jaw": {
"rotation": [20, 0, 0]
},
"pupil_right": {
"position": [0, 0, -0.2],
"scale": [1, 0.5, 0.7]
},
"pupil_left": {
"position": [0, 0, -0.2],
"scale": [1, 0.5, 0.7]
}
}
},
"animation.treecko.hurt": {
"loop": true,
"bones": {
"jaw": {
"rotation": [20, 0, 0]
},
"eye_right": {
"position": [0.1, 0, 0]
},
"eye_left": {
"position": [-0.1, 0, 0]
},
"eyelid_hurt_left": {
"position": [0.1, 0, 0]
},
"eyelid_hurt_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.treecko.cry": {
"animation_length": 1.2,
"sound_effects": {
@@ -7,7 +7,7 @@
"torso": {
"rotation": [10, 0, 0]
},
"torso2": {
"upper_torso": {
"rotation": [5, 0, 0]
},
"neck": {
@@ -17,122 +17,100 @@
"rotation": [2.5, 0, 0]
},
"leaf7": {
"rotation": [-5, 0, 0]
"rotation": [12.5, 0, 0]
},
"jaw": {
"rotation": [0, 0, 0]
},
"arm_left": {
"left_upper_arm": {
"rotation": [2.5, 7.5, 40]
},
"arm_left2": {
"left_lower_arm": {
"rotation": [0, 52.5, 0]
},
"hand_left": {
"left_hand": {
"rotation": [2.5, 0, 32.5]
},
"arm_leaves_left": {
"left_arm_leaves": {
"rotation": [-25.08377, -4.53051, 2.11751]
},
"finger_front_left": {
"left_index_finger": {
"rotation": [0, 0, 10]
},
"finger_back_left": {
"left_pinky_finger": {
"rotation": [0, 0, 27.5]
},
"tail_left": {
"left_tail": {
"rotation": [-10, 12.5, -2.5]
},
"tail_left2": {
"left_tail2": {
"rotation": [-15, 0, 0]
},
"leg_left": {
"left_upper_leg": {
"rotation": [0, -22.5, 0]
},
"leg_left2": {
"left_lower_leg": {
"rotation": [0, 0, 0]
},
"foot_left": {
"left_foot": {
"rotation": [0, 0, 0]
},
"toe_inner_left": {
"left_inner_toe": {
"rotation": [0, 10, 0]
},
"toe_outer_left": {
"left_outer_toe": {
"rotation": [0, -10, 0]
},
"tail_right": {
"right_tail": {
"rotation": [-10, -12.5, 2.5]
},
"leg_right": {
"right_upper_leg": {
"rotation": [0, 22.5, 0]
},
"leg_right2": {
"right_lower_leg": {
"rotation": [0, 0, 0]
},
"foot_right": {
"right_foot": {
"rotation": [0, 0, 0]
},
"toe_inner_right": {
"right_inner_toe": {
"rotation": [0, -10, 0]
},
"toe_outer_right": {
"right_outer_toe": {
"rotation": [0, 10, 0]
},
"arm_right": {
"right_upper_arm": {
"rotation": [2.5, -7.5, -40]
},
"arm_right2": {
"right_lower_arm": {
"rotation": [0, -52.5, 0]
},
"hand_right": {
"right_hand": {
"rotation": [2.5, 0, -32.5]
},
"finger_front_right": {
"right_index_finger": {
"rotation": [0, 0, -10]
},
"finger_back_right": {
"right_pinky_finger": {
"rotation": [0, 0, -27.5]
},
"arm_leaves_right": {
"right_arm_leaves": {
"rotation": [-25.08377, 4.53051, -2.11751]
},
"tail_right2": {
"right_tail2": {
"rotation": [-15, 0, 0]
},
"finger_front_left2": {
"left_index_finger2": {
"rotation": [0, 0, 17.5]
},
"finger_back_left2": {
"left_pinky_finger2": {
"rotation": [0, 0, 22.5]
},
"finger_front_right2": {
"right_index_finger2": {
"rotation": [0, 0, -17.5]
},
"finger_back_right2": {
"right_pinky_finger2": {
"rotation": [0, 0, -22.5]
},
"leaf": {
"rotation": [-50, 0, 0]
},
"leaf2": {
"rotation": [-35, 0, 0]
},
"leaf3": {
"rotation": [-22.5, 0, 0]
},
"leaf4": {
"rotation": [-25, 0, 0]
},
"leaf5": {
"rotation": [-25, 0, 0]
},
"leaf6": {
"rotation": [-7.5, 0, 0]
},
"stick": {
"rotation": [30, 40, 0],
"scale": 0.7
}
}
},
@@ -142,7 +120,7 @@
"torso": {
"rotation": [-5, 0, 0]
},
"torso2": {
"upper_torso": {
"rotation": [2.5, 0, 0]
},
"neck": {
@@ -157,94 +135,94 @@
"jaw": {
"rotation": [0, 0, 0]
},
"arm_left": {
"left_upper_arm": {
"rotation": [-52.5, 5, 27.5]
},
"arm_left2": {
"left_lower_arm": {
"rotation": [0, 65, 0]
},
"hand_left": {
"left_hand": {
"rotation": [2.38443, -0.75155, 49.98436]
},
"arm_leaves_left": {
"left_arm_leaves": {
"rotation": [-10, -17.5, 0]
},
"finger_front_left": {
"left_index_finger": {
"rotation": [0, 0, 2.5]
},
"finger_back_left": {
"left_pinky_finger": {
"rotation": [0, 0, 5]
},
"tail_left": {
"left_tail": {
"rotation": [-15, 12.5, -2.5]
},
"tail_left2": {
"left_tail2": {
"rotation": [7.5, 0, 0]
},
"leg_left": {
"left_upper_leg": {
"rotation": [0, -22.5, 0]
},
"leg_left2": {
"left_lower_leg": {
"rotation": [0, 0, 0]
},
"foot_left": {
"left_foot": {
"rotation": [0, 0, 0]
},
"toe_inner_left": {
"left_inner_toe": {
"rotation": [0, 10, 0]
},
"toe_outer_left": {
"left_outer_toe": {
"rotation": [0, -10, 0]
},
"tail_right": {
"right_tail": {
"rotation": [-15, -12.5, 2.5]
},
"leg_right": {
"right_upper_leg": {
"rotation": [0, 22.5, 0]
},
"leg_right2": {
"right_lower_leg": {
"rotation": [0, 0, 0]
},
"foot_right": {
"right_foot": {
"rotation": [0, 0, 0]
},
"toe_inner_right": {
"right_inner_toe": {
"rotation": [0, -10, 0]
},
"toe_outer_right": {
"right_outer_toe": {
"rotation": [0, 10, 0]
},
"arm_right": {
"right_upper_arm": {
"rotation": [-52.5, -5, -27.5]
},
"arm_right2": {
"right_lower_arm": {
"rotation": [0, -65, 0]
},
"hand_right": {
"right_hand": {
"rotation": [2.38443, 0.75155, -49.98436]
},
"finger_front_right": {
"right_index_finger": {
"rotation": [0, 0, -2.5]
},
"finger_back_right": {
"right_pinky_finger": {
"rotation": [0, 0, -5]
},
"arm_leaves_right": {
"right_arm_leaves": {
"rotation": [-10, 17.5, 0]
},
"tail_right2": {
"right_tail2": {
"rotation": [7.5, 0, 0]
},
"finger_front_left2": {
"left_index_finger2": {
"rotation": [0, 0, 65]
},
"finger_back_left2": {
"left_pinky_finger2": {
"rotation": [0, 0, 87.5]
},
"finger_front_right2": {
"right_index_finger2": {
"rotation": [0, 0, -65]
},
"finger_back_right2": {
"right_pinky_finger2": {
"rotation": [0, 0, -87.5]
}
}
@@ -255,7 +233,7 @@
"torso": {
"rotation": [45.38165, -3.51814, -7.08167]
},
"torso2": {
"upper_torso": {
"rotation": [-9.97857, 3.32943, 4.4913]
},
"neck": {
@@ -270,86 +248,86 @@
"jaw": {
"rotation": [42.5, 0, 0]
},
"arm_left": {
"left_upper_arm": {
"rotation": [-12.58328, 9.94037, 39.45082]
},
"arm_left2": {
"left_lower_arm": {
"rotation": [0, 82.5, 0]
},
"hand_left": {
"left_hand": {
"rotation": [7.5, 0, 32.5]
},
"arm_leaves_left": {
"left_arm_leaves": {
"rotation": [-21.78282, -11.4487, 11.10461]
},
"finger_front_left": {
"left_index_finger": {
"rotation": [0, 0, 10]
},
"finger_back_left": {
"left_pinky_finger": {
"rotation": [0, 0, 22.5]
},
"tail_left": {
"left_tail": {
"rotation": [-17.99085, 11.53327, -4.85721]
},
"tail_left2": {
"left_tail2": {
"rotation": [-15, 0, 0]
},
"leg_left": {
"left_upper_leg": {
"rotation": [-37.5, -22.5, 0],
"position": [0.5, 0.5, -1]
},
"leg_left2": {
"left_lower_leg": {
"rotation": [5, 0, 0]
},
"foot_left": {
"left_foot": {
"rotation": [0, 0, 0]
},
"toe_inner_left": {
"left_inner_toe": {
"rotation": [10, 10, 0]
},
"toe_outer_left": {
"left_outer_toe": {
"rotation": [20, -10, 0]
},
"tail_right": {
"right_tail": {
"rotation": [-28.32455, -16.15901, -4.25872]
},
"leg_right": {
"right_upper_leg": {
"rotation": [38, 7.5, 2.5],
"position": [0, -0.5, -0.5]
},
"leg_right2": {
"right_lower_leg": {
"rotation": [5, 0, 0]
},
"foot_right": {
"right_foot": {
"rotation": [27.5, 0, 0]
},
"toe_inner_right": {
"right_inner_toe": {
"rotation": [-24.71447, -5.46269, -2.12052],
"position": [0, -0.1, 0.6]
},
"toe_outer_right": {
"right_outer_toe": {
"rotation": [-24.71447, 5.46269, 2.12052],
"position": [0, -0.1, 0.6]
},
"arm_right": {
"right_upper_arm": {
"rotation": [-14.26018, -29.40676, -34.54418]
},
"arm_right2": {
"right_lower_arm": {
"rotation": [0, -70, 0]
},
"hand_right": {
"right_hand": {
"rotation": [7.5, 0, -32.5]
},
"finger_front_right": {
"right_index_finger": {
"rotation": [0, 0, -10]
},
"finger_back_right": {
"right_pinky_finger": {
"rotation": [0, 0, -22.5]
},
"arm_leaves_right": {
"right_arm_leaves": {
"rotation": [-26.39218, 18.05776, -8.74472]
},
"tail_right2": {
"right_tail2": {
"rotation": [-15, 0, 0]
},
"body": {
@@ -367,191 +345,76 @@
"leaf6": {
"rotation": [5, 0, 0]
},
"toe_back_left": {
"left_back_toe": {
"rotation": [-5, 0, 0]
},
"toe_back_right": {
"right_back_toe": {
"rotation": [-10, 0, 0]
},
"toe_outer_left2": {
"left_outer_toe2": {
"rotation": [10, 0, 0]
},
"toe_inner_left2": {
"left_inner_toe2": {
"rotation": [10, 0, 0]
},
"toe_inner_right2": {
"right_inner_toe2": {
"rotation": [-45, 0, 0],
"position": [0, -0.55, 1.4]
},
"toe_outer_right2": {
"right_outer_toe2": {
"rotation": [-45, 0, 0],
"position": [0, -0.55, 1.4]
},
"arm_leaf_middle_left": {
"left_leaf1": {
"rotation": [15, 0, 0]
},
"arm_leaf_inner_left": {
"left_leaf2": {
"rotation": [5.76917, -1.99557, 14.05033]
},
"arm_leaf_outer_left": {
"left_leaf3": {
"rotation": [10, 0, 0]
},
"arm_leaf_middle_right": {
"right_leaf1": {
"rotation": [5, 0, 0]
},
"arm_leaf_inner_right": {
"right_leaf2": {
"rotation": [2.5, 0, 0]
},
"finger_front_left2": {
"left_index_finger2": {
"rotation": [0, 0, 22.5]
},
"finger_back_left2": {
"left_pinky_finger2": {
"rotation": [0, 0, 30]
},
"finger_front_right2": {
"right_index_finger2": {
"rotation": [0, 0, -22.5]
},
"finger_back_right2": {
"right_pinky_finger2": {
"rotation": [0, 0, -30]
}
}
},
"animation.grovyle.blink": {
"animation_length": 0.1667,
"animation_length": 0.16667,
"bones": {
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": [-0.1, 0, 0],
"0.1667": {"pre": [-0.1, 0, 0], "post": [0, 0, 0]}
"0.1667": [0, 0, 0]
}
},
"eyelid_left": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": [0.1, 0, 0],
"0.1667": {"pre": [0.1, 0, 0], "post": [0, 0, 0]}
"0.1667": [0, 0, 0]
}
},
"eye_left": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": [-0.1, 0, 0],
"0.1667": {"pre": [-0.1, 0, 0], "post": [0, 0, 0]}
}
},
"eye_right": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": [0.1, 0, 0],
"0.1667": {"pre": [0.1, 0, 0], "post": [0, 0, 0]}
}
}
}
},
"animation.grovyle.happy": {
"loop": true,
"bones": {
"eye_left": {
"position": [-0.1, 0, 0]
},
"eye_right": {
"position": [0.1, 0, 0]
},
"eyelid_happy_left": {
"position": [0.1, 0, 0]
},
"eyelid_happy_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.grovyle.angry": {
"loop": true,
"bones": {
"eye_emote_right": {
"scale": [1, 1.5, 1]
},
"eye_brow_right": {
"position": [0, -0.3, 0]
},
"eye_brow_right2": {
"position": [0, 0.5, 0]
},
"eye_brow_left": {
"position": [0, -0.3, 0]
},
"eye_brow_left2": {
"position": [0, 0.5, 0]
},
"eye_emote_left": {
"scale": [1, 1.5, 1]
}
}
},
"animation.grovyle.sad": {
"loop": true,
"bones": {
"eye_brow_right": {
"position": [0, 0.5, 0]
},
"eye_brow_right2": {
"position": [0, -0.5, 0]
},
"eye_brow_left": {
"position": [0, 0.5, 0]
},
"eye_brow_left2": {
"position": [0, -0.5, 0]
}
}
},
"animation.grovyle.shocked": {
"loop": true,
"bones": {
"pupil_left": {
"position": [0, 0, -0.1],
"scale": [1, 0.5, 0.5]
},
"pupil_right": {
"position": [0, 0, -0.1],
"scale": [1, 0.5, 0.5]
},
"eye_emote_right": {
"position": [0, -0.5, 0],
"scale": [1, 2, 1]
},
"eye_brow_right": {
"position": [0, 0.3, 0]
},
"eye_brow_left": {
"position": [0, 0.3, 0]
},
"eye_emote_left": {
"position": [0, -0.5, 0],
"scale": [1, 2, 1]
}
}
},
"animation.grovyle.hurt": {
"loop": true,
"bones": {
"eye_left": {
"position": [-0.1, 0, 0]
},
"eye_right": {
"position": [0.1, 0, 0]
},
"eyelid_hurt_left": {
"position": [0.1, 0, 0]
},
"eyelid_hurt_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.grovyle.cry": {
"animation_length": 1.2,
"animation_length": 1.33333,
"sound_effects": {
"0.04": {
"effect": "pokemon.grovyle.cry"
@@ -7,7 +7,7 @@
"torso": {
"rotation": [17.5, 0, 0]
},
"torso2": {
"upper_torso": {
"rotation": [-7.5, 0, 0]
},
"neck": {
@@ -16,34 +16,37 @@
"head": {
"rotation": [5, 0, 0]
},
"arm_right": {
"jaw": {
"rotation": [0, 0, 0]
},
"right_upper_arm": {
"rotation": [0, 5, 0]
},
"arm_right2": {
"right_lower_arm": {
"rotation": [0, -50, 0]
},
"hand_right": {
"right_hand": {
"rotation": [0, 0, -27.5]
},
"finger_front_right": {
"right_index_finger": {
"rotation": [0, 0, -20]
},
"finger_middle_right": {
"right_middle_finger": {
"rotation": [0, 0, -15]
},
"finger_back_right": {
"right_pinky_finger": {
"rotation": [0, 0, -25]
},
"finger_back_right2": {
"right_pinky_finger2": {
"rotation": [0, 0, -47.5]
},
"finger_front_right2": {
"right_index_finger2": {
"rotation": [0, 0, -50]
},
"finger_middle_right2": {
"right_middle_finger2": {
"rotation": [0, 0, -40]
},
"leg_right": {
"right_upper_leg": {
"rotation": [0, 15, 0]
},
"tail": {
@@ -61,81 +64,77 @@
"tail5": {
"rotation": [7.5, 0, 0]
},
"shoulder_right": {
"right_shoulder": {
"rotation": [0, 0, -45]
},
"leg_left": {
"left_upper_leg": {
"rotation": [0, -15, 0]
},
"shoulder_left": {
"left_shoulder": {
"rotation": [0, 0, 45]
},
"arm_left": {
"left_upper_arm": {
"rotation": [0, -5, 0]
},
"arm_left2": {
"left_lower_arm": {
"rotation": [0, 50, 0]
},
"hand_left": {
"left_hand": {
"rotation": [0, 0, 27.5]
},
"finger_front_left": {
"left_index_finger": {
"rotation": [0, 0, 20]
},
"finger_front_left2": {
"left_index_finger2": {
"rotation": [0, 0, 50]
},
"finger_middle_left": {
"left_middle_finger": {
"rotation": [0, 0, 15]
},
"finger_middle_left2": {
"left_middle_finger2": {
"rotation": [0, 0, 40]
},
"finger_back_left": {
"left_pinky_finger": {
"rotation": [0, 0, 25]
},
"finger_back_left2": {
"left_pinky_finger2": {
"rotation": [0, 0, 47.5]
},
"arm_leaf_front_blade_right": {
"right_arm_leaf_front_blade": {
"scale": [1, 0, 1]
},
"arm_leaf_back_blade_right": {
"right_arm_leaf_back_blade": {
"scale": [1, 0, 1]
},
"arm_leaf_front_blade_left": {
"left_arm_leaf_front_blade": {
"scale": [1, 0, 1]
},
"arm_leaf_back_blade_left": {
"left_arm_leaf_back_blade": {
"scale": [1, 0, 1]
},
"tail_leaves_top_left": {
"left_top_leaves": {
"rotation": [2.5, 0, 0]
},
"tail_leaves_bottom_left": {
"left_bottom_leaves": {
"rotation": [0, -2.5, 0]
},
"tail_leaves_top_left3": {
"left_top_leaves3": {
"rotation": [-5, 0, 0]
},
"tail_leaves_bottom_left3": {
"left_bottom_leaves3": {
"rotation": [0, 5, 0]
},
"tail_leaves_top_right": {
"right_top_leaves": {
"rotation": [2.5, 0, 0]
},
"tail_leaves_bottom_right": {
"right_bottom_leaves": {
"rotation": [0, 2.5, 0]
},
"tail_leaves_top_right3": {
"right_top_leaves3": {
"rotation": [-5, 0, 0]
},
"tail_leaves_bottom_right3": {
"right_bottom_leaves3": {
"rotation": [0, -5, 0]
},
"stick": {
"rotation": [16, 40, 0],
"scale": 0.7
}
}
},
@@ -145,7 +144,7 @@
"torso": {
"rotation": [32.40109, 2.68407, -4.22005]
},
"torso2": {
"upper_torso": {
"rotation": [4.98107, -0.43523, 4.98107]
},
"neck": {
@@ -157,34 +156,34 @@
"jaw": {
"rotation": [45, 0, 0]
},
"arm_right": {
"right_upper_arm": {
"rotation": [-7.5, 2.5, 0]
},
"arm_right2": {
"right_lower_arm": {
"rotation": [0, -72.5, 0]
},
"hand_right": {
"right_hand": {
"rotation": [0, 0, -50]
},
"finger_front_right": {
"right_index_finger": {
"rotation": [0, 0, -20]
},
"finger_middle_right": {
"right_middle_finger": {
"rotation": [0, 0, -15]
},
"finger_back_right": {
"right_pinky_finger": {
"rotation": [0, 0, -25]
},
"finger_back_right2": {
"right_pinky_finger2": {
"rotation": [0, 0, -47.5]
},
"finger_front_right2": {
"right_index_finger2": {
"rotation": [0, 0, -50]
},
"finger_middle_right2": {
"right_middle_finger2": {
"rotation": [0, 0, -40]
},
"leg_right": {
"right_upper_leg": {
"rotation": [22.5, 15, 0],
"position": [0, 0.5, 0.5]
},
@@ -203,92 +202,92 @@
"tail5": {
"rotation": [12.79362, 12.19908, 2.74715]
},
"shoulder_right": {
"right_shoulder": {
"rotation": [-10.01754, 2.34914, -25.85553]
},
"leg_left": {
"left_upper_leg": {
"rotation": [-17.5, -15, 0],
"position": [0, 0, -0.5]
},
"shoulder_left": {
"left_shoulder": {
"rotation": [-11.9857, 23.12519, 20.20473]
},
"arm_left": {
"left_upper_arm": {
"rotation": [-5, 10, 0]
},
"arm_left2": {
"left_lower_arm": {
"rotation": [0, 47.5, 0]
},
"hand_left": {
"left_hand": {
"rotation": [0, 0, 22.5]
},
"finger_front_left": {
"left_index_finger": {
"rotation": [0, 0, 20]
},
"finger_front_left2": {
"left_index_finger2": {
"rotation": [0, 0, 50]
},
"finger_middle_left": {
"left_middle_finger": {
"rotation": [0, 0, 15]
},
"finger_middle_left2": {
"left_middle_finger2": {
"rotation": [0, 0, 40]
},
"finger_back_left": {
"left_pinky_finger": {
"rotation": [0, 0, 25]
},
"finger_back_left2": {
"left_pinky_finger2": {
"rotation": [0, 0, 47.5]
},
"leg_right2": {
"right_lower_leg": {
"rotation": [10, 0, 0]
},
"leg_right3": {
"right_ankle": {
"rotation": [0, 0, 0]
},
"foot_right": {
"right_foot": {
"rotation": [10, 0, 0]
},
"toe_middle_right": {
"right_middle_toe": {
"rotation": [-42.5, 0, 0],
"position": [0, -0.5, 0.6]
},
"toe_inner_right": {
"right_inner_toe": {
"rotation": [-43.11609, 4.07933, 4.44372],
"position": [0, -0.5, 0.6]
},
"toe_outer_right": {
"right_outer_toe": {
"rotation": [-43.11609, -4.07933, -4.44372],
"position": [0, -0.5, 0.6]
},
"leg_left2": {
"left_lower_leg": {
"rotation": [-5, 0, 0]
},
"leg_left3": {
"left_ankle": {
"rotation": [0, 0, 0]
},
"foot_left": {
"left_foot": {
"rotation": [22.5, 0, 0]
},
"arm_leaf_front_blade_right": {
"right_arm_leaf_front_blade": {
"scale": [1, 0, 1]
},
"arm_leaf_back_blade_right": {
"right_arm_leaf_back_blade": {
"scale": [1, 0, 1]
},
"arm_leaf_front_blade_left": {
"left_arm_leaf_front_blade": {
"scale": [1, 0, 1]
},
"arm_leaf_back_blade_left": {
"left_arm_leaf_back_blade": {
"scale": [1, 0, 1]
},
"tail_leaves_top_left": {
"left_top_leaves": {
"rotation": [10, 0, 0]
},
"tail_leaves_top_left2": {
"left_top_leaves2": {
"rotation": [2.5, 0, 0]
},
"tail_leaves_top_left3": {
"left_top_leaves3": {
"rotation": [-7.5, 0, 0]
}
}
@@ -302,7 +301,7 @@
"torso": {
"rotation": [49.75757, -7.34759, 2.92368]
},
"torso2": {
"upper_torso": {
"rotation": [14.94548, 1.29256, -4.83045]
},
"neck": {
@@ -311,68 +310,68 @@
"head": {
"rotation": [-55.48448, 3.48051, -3.55608]
},
"shoulder_right": {
"right_shoulder": {
"rotation": [-58.62702, 15.46973, -8.28342],
"position": [0, -0.5, 0]
},
"arm_right": {
"right_upper_arm": {
"rotation": [-7.5, -1, -7.5]
},
"arm_right2": {
"right_lower_arm": {
"rotation": [0, -30, 0]
},
"hand_right": {
"right_hand": {
"rotation": [0, 0, -15]
},
"finger_front_right": {
"right_index_finger": {
"rotation": [0, 0, -12.5]
},
"finger_front_right2": {
"right_index_finger2": {
"rotation": [0, 0, -45]
},
"finger_middle_right": {
"right_middle_finger": {
"rotation": [0, 0, 22.5],
"position": [0.5, 0, 0]
},
"finger_middle_right2": {
"right_middle_finger2": {
"rotation": [0, 0, -35]
},
"finger_back_right": {
"right_pinky_finger": {
"rotation": [0, 0, -37.5]
},
"finger_back_right2": {
"right_pinky_finger2": {
"rotation": [0, 0, -42.5]
},
"shoulder_left": {
"left_shoulder": {
"rotation": [-59.92127, -18.02575, 12.77165],
"position": [0, -0.5, 0]
},
"arm_left": {
"left_upper_arm": {
"rotation": [-7.5, 1, 7.5]
},
"arm_left2": {
"left_lower_arm": {
"rotation": [0, 42.5, 0]
},
"hand_left": {
"left_hand": {
"rotation": [0, 0, 15]
},
"finger_front_left": {
"left_index_finger": {
"rotation": [0, 0, 12.5]
},
"finger_front_left2": {
"left_index_finger2": {
"rotation": [0, 0, 45]
},
"finger_middle_left": {
"left_middle_finger": {
"rotation": [0, 0, -22.5],
"position": [-0.5, 0, 0]
},
"finger_middle_left2": {
"left_middle_finger2": {
"rotation": [0, 0, 35]
},
"finger_back_left": {
"left_pinky_finger": {
"rotation": [0, 0, 37.5]
},
"finger_back_left2": {
"left_pinky_finger2": {
"rotation": [0, 0, 42.5]
},
"tail": {
@@ -391,170 +390,97 @@
"tail5": {
"rotation": [10.08453, -7.38542, -1.30962]
},
"leg_right": {
"right_upper_leg": {
"rotation": [-25.44458, 0.21572, -4.69162],
"position": [0, 0, -1]
},
"leg_right2": {
"right_lower_leg": {
"rotation": [-5, -2.5, 0]
},
"leg_right3": {
"right_ankle": {
"rotation": [35, 0, 0],
"position": [0, 0, 0.6]
},
"foot_right": {
"right_foot": {
"rotation": [7.74222, 4.81281, 5.7589]
},
"toe_middle_right": {
"right_middle_toe": {
"rotation": [-12.5, 0, 0]
},
"toe_inner_right": {
"right_inner_toe": {
"rotation": [-12.5, 0, 0]
},
"toe_outer_right": {
"right_outer_toe": {
"rotation": [-12.5, 0, 0]
},
"leg_left": {
"left_upper_leg": {
"rotation": [32.71776, -4.77227, -5.22233],
"position": [0, 0, 1]
},
"leg_left2": {
"left_lower_leg": {
"rotation": [4.96271, -0.86717, 4.92442]
},
"leg_left3": {
"left_ankle": {
"rotation": [42.5, 0, 0],
"position": [0, 0, 1]
},
"foot_left": {
"left_foot": {
"rotation": [85, 0, 0],
"position": [0, 0.35, 1.2]
},
"toe_middle_left": {
"left_middle_toe": {
"rotation": [5, 0, 0]
},
"toe_inner_left": {
"left_inner_toe": {
"rotation": [10, 0, 0]
},
"toe_outer_left": {
"left_outer_toe": {
"rotation": [15, 0, 0]
},
"tail_leaves_bottom_left": {
"left_bottom_leaves": {
"rotation": [0, -5, 0]
},
"tail_leaves_bottom_left3": {
"left_bottom_leaves3": {
"rotation": [0, 5, 0]
},
"toe_middle_left2": {
"left_middle_toe2": {
"rotation": [17.5, 0, 0]
},
"toe_inner_left2": {
"left_inner_toe2": {
"rotation": [22.5, 0, 0]
},
"toe_outer_left2": {
"left_outer_toe2": {
"rotation": [15, 0, 0]
},
"tail_leaves_top_right": {
"right_top_leaves": {
"rotation": [2.5, 0, 0]
},
"tail_leaves_top_right3": {
"right_top_leaves3": {
"rotation": [-5, 0, 0]
}
}
},
"animation.sceptile.blink": {
"animation_length": 0.1667,
"animation_length": 0.16667,
"bones": {
"eyelid_right": {
"right_eyelid": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": [-0.1, 0, 0],
"0.125": {"pre": [-0.1, 0, 0], "post": [-0.1, 0, 0]},
"0.1667": {"pre": [-0.1, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"left_eyelid": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": [0.1, 0, 0],
"0.125": {"pre": [0.1, 0, 0], "post": [0.1, 0, 0]},
"0.1667": {"pre": [0.1, 0, 0], "post": [0, 0, 0]}
}
}
}
},
"animation.sceptile.hurt_or_happy": {
"loop": true,
"bones": {
"eyelid_hurt_right": {
"position": [-0.1, 0, 0]
},
"eyelid_hurt_left": {
"position": [0.1, 0, 0]
}
}
},
"animation.sceptile.angry": {
"loop": true,
"bones": {
"eye_brow_right": {
"position": [0, -0.4, 0]
},
"eye_brow_left": {
"position": [0, -0.4, 0]
},
"eye_brow_left2": {
"position": [0, 0.4, 0]
},
"eye_brow_right2": {
"position": [0, 0.4, 0]
}
}
},
"animation.sceptile.sad": {
"loop": true,
"bones": {
"pupil_right": {
"position": [0, 0.1, 0]
},
"pupil_left": {
"position": [0, 0.1, 0]
},
"eye_brow_right": {
"position": [0, 0.3, 0]
},
"eye_brow_left": {
"position": [0, 0.3, 0]
},
"eye_brow_left2": {
"position": [0, -0.4, 0]
},
"eye_brow_right2": {
"position": [0, -0.4, 0]
}
}
},
"animation.sceptile.shocked": {
"loop": true,
"bones": {
"jaw": {
"rotation": [35, 0, 0]
},
"pupil_right": {
"position": [0, 0.1, 0],
"scale": [1, 0.5, 0.5]
},
"pupil_left": {
"position": [0, 0.1, 0],
"scale": [1, 0.5, 0.5]
},
"eye_brow_right": {
"position": [0, 0.3, 0]
},
"eye_brow_left": {
"position": [0, 0.3, 0]
}
}
},
"animation.sceptile.cry": {
"animation_length": 1.2,
"animation_length": 1.33333,
"sound_effects": {
"0.04": {
"effect": "pokemon.sceptile.cry"
@@ -788,30 +788,34 @@
}
},
"animation.metagross.blink": {
"animation_length": 0.1667,
"animation_length": 0.16667,
"bones": {
"eye_open_left": {
"position": {
"0.0": [0, 0, 0.1],
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
"0.125": [0, 0, 0.1],
"0.1667": [0, 0, 0]
}
},
"eye_closed_left": {
"position": {
"0.0": [0, 0, -0.1],
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"eye_open_right": {
"position": {
"0.0": [0, 0, 0.1],
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
"0.125": [0, 0, 0.1],
"0.1667": [0, 0, 0]
}
},
"eye_closed_right": {
"position": {
"0.0": [0, 0, -0.1],
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
}
}
}
@@ -968,6 +972,12 @@
"eye_closed_left": {
"position": [0, 0, -0.1]
},
"eye_open_right": {
"position": [0, 0, 0.1]
},
"eye_closed_right": {
"position": [0, 0, -0.1]
},
"leg_front_left": {
"rotation": [-20.94102, 8.42106, -69.05898]
},
@@ -1003,12 +1013,6 @@
},
"hand_back_right": {
"rotation": [0, 0, -15]
},
"eye_open_right": {
"position": [0, 0, 0.1]
},
"eye_closed_right": {
"position": [0, 0, -0.1]
}
}
},
@@ -1019,87 +1023,6 @@
"position": [0, 0, "-q.anim_time*90*0.2"]
}
}
},
"animation.metagross.shock": {
"loop": true,
"bones": {
"pupil_left": {
"scale": [0.7, 0.7, 1]
},
"eye_shine_left": {
"position": [0, 0, 0.1]
},
"mouth": {
"position": [0, 0, -0.2]
},
"pupil_right": {
"scale": [0.7, 0.7, 1]
},
"eye_shine_right": {
"position": [0, 0, 0.1]
}
}
},
"animation.metagross.angry": {
"loop": true,
"bones": {
"eye_angry_left": {
"position": [0, 0, -0.1]
},
"eye_angry_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.metagross.sad": {
"loop": true,
"bones": {
"eye_sad_left": {
"position": [0, 0, -0.1]
},
"eye_sad_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.metagross.happy": {
"loop": true,
"bones": {
"mouth": {
"position": [0, 0, -0.2]
},
"eye_open_left": {
"position": [0, 0, 0.1]
},
"eye_happy_left": {
"position": [0, 0, -0.1]
},
"eye_open_right": {
"position": [0, 0, 0.1]
},
"eye_happy_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.metagross.hurt": {
"loop": true,
"bones": {
"eye_open_left": {
"position": [0, 0, 0.1]
},
"eye_closed_left": {
"rotation": [0, 0, -20],
"position": [0, 0, -0.1]
},
"eye_open_right": {
"position": [0, 0, 0.1]
},
"eye_closed_right": {
"rotation": [0, 0, 20],
"position": [0, 0, -0.1]
}
}
}
}
}
@@ -5,11 +5,7 @@
"loop": true,
"bones": {
"body": {
"rotation": [
"45*q.riding.velocity_forward(0)",
"0 - Math.Sin(((q.anim_time + 0.1) * 180 * 0.5) * 1) * 5",
"Math.Sin(((q.anim_time + 0.4) * 180 * 0.5) * 1) * 5 + 45*q.riding.velocity_right(0)"
],
"rotation": [0, "0 - Math.Sin(((q.anim_time + 0.1) * 180 * 0.5) * 1) * 5", "Math.Sin(((q.anim_time + 0.4) * 180 * 0.5) * 1) * 5"],
"position": ["Math.Sin((q.anim_time * 180 * 0.5) * 1) * 1.5", "7+Math.Sin((q.anim_time * 90 * 0.5) * 1) * 1.5", 0]
},
"magnet_back_rotation": {
@@ -49,11 +45,7 @@
"loop": true,
"bones": {
"body": {
"rotation": [
"2.5 + 45*q.riding.velocity_forward(0)",
"- Math.Sin(((q.anim_time + 0.1) * 180 * 0.5) * 1) * 5",
"Math.Sin(((q.anim_time + 0.4) * 180 * 0.5) * 1) * 5 - 45*q.riding.velocity_right(0)"
],
"rotation": [15, "0 - Math.Sin(((q.anim_time + 0.1) * 180 * 0.5) * 1) * 5", "Math.Sin(((q.anim_time + 0.4) * 180 * 0.5) * 1) * 5"],
"position": ["Math.Sin((q.anim_time * 180 * 0.5) * 1) * 1.5", "7+Math.Sin((q.anim_time * 90 * 0.5) * 1) * 1.5", 0]
},
"magnet_back_rotation": {
@@ -274,117 +266,45 @@
"pupil_left": {
"position": {
"0.0": [0, 0, 0],
"0.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"0.5417": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"1.75": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0.1]
},
"1.7917": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"2.0833": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"2.125": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
}
"0.5": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.5417": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"1.75": {"pre": [0, 0, 0.1], "post": [0, 0, 0.1]},
"1.7917": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
"2.0833": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"2.125": {"pre": [0, 0, 0], "post": [0, 0, 0.1]}
}
},
"pupil_closed_left": {
"position": {
"0.0": [0, 0, 0],
"0.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"0.5417": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"1.75": {
"pre": [0, 0, -0.1],
"post": [0, 0, -0.1]
},
"1.7917": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"2.0833": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"2.125": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
}
"0.5": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.5417": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"1.75": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
"1.7917": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
"2.0833": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"2.125": {"pre": [0, 0, 0], "post": [0, 0, -0.1]}
}
},
"pupil_right": {
"position": {
"0.0": [0, 0, 0],
"0.2083": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
},
"0.5": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0.1]
},
"0.5417": {
"pre": [0, 0, 0.1],
"post": [0, 0, 0]
},
"1.9583": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"2.0": {
"pre": [0, 0, 0],
"post": [0, 0, 0.1]
}
"0.2083": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.25": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
"0.5": {"pre": [0, 0, 0.1], "post": [0, 0, 0.1]},
"0.5417": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
"1.9583": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"2.0": {"pre": [0, 0, 0], "post": [0, 0, 0.1]}
}
},
"pupil_closed_right": {
"position": {
"0.0": [0, 0, 0],
"0.2083": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
},
"0.5": {
"pre": [0, 0, -0.1],
"post": [0, 0, -0.1]
},
"0.5417": {
"pre": [0, 0, -0.1],
"post": [0, 0, 0]
},
"1.9583": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
},
"2.0": {
"pre": [0, 0, 0],
"post": [0, 0, -0.1]
}
"0.2083": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.25": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
"0.5": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
"0.5417": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
"1.9583": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"2.0": {"pre": [0, 0, 0], "post": [0, 0, -0.1]}
}
}
},
@@ -550,65 +470,6 @@
}
}
},
"animation.magnezone.active": {
"loop": true,
"bones": {
"magnet_lights_left": {
"position": [0, 0, -0.1]
},
"magnet_lights_right": {
"position": [0, 0, -0.1]
},
"magnet_lights_back": {
"position": [0, 0, 0.1]
}
}
},
"animation.magnezone.shock": {
"loop": true,
"bones": {
"pupil_left": {
"scale": [0.7, 0.7, 1]
},
"pupil_right": {
"scale": [0.7, 0.7, 1]
}
}
},
"animation.magnezone.happy": {
"loop": true,
"bones": {
"pupil_left": {
"position": [0, 0, 0.1]
},
"pupil_right": {
"position": [0, 0, 0.1]
},
"pupil_happy_left": {
"position": [0, 0, -0.1]
},
"pupil_happy_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.magnezone.hurt": {
"loop": true,
"bones": {
"pupil_left": {
"position": [0, 0, 0.1]
},
"pupil_right": {
"position": [0, 0, 0.1]
},
"pupil_recoil_left": {
"position": [0, 0, -0.1]
},
"pupil_recoil_right": {
"position": [0, 0, -0.1]
}
}
},
"animation.magnezone.cry": {
"animation_length": 1.2,
"sound_effects": {
@@ -159,14 +159,6 @@
"rotation": [-9.99762, -0.10901, 10.00238]
}
}
},
"animation.leafeon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.leafeon.cry"
}
}
}
}
}
@@ -177,14 +177,6 @@
"rotation": [0, 0, -7.5]
}
}
},
"animation.glaceon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.glaceon.cry"
}
}
}
}
}
@@ -1,427 +0,0 @@
{
"format_version": "1.8.0",
"animations": {
"animation.druddigon.ground_idle": {
"loop": true,
"bones": {
"arm_right1": {
"rotation": [-19.84214, -10.30464, -25.48972]
},
"arm_right2": {
"rotation": [7.5, 0, -22.5]
},
"arm_right3": {
"rotation": [0, -40, 0]
},
"hand_right": {
"rotation": [0, -7.5, -12.5]
},
"finger_right1": {
"rotation": [0, 0, -10]
},
"claw_right1": {
"rotation": [0, 0, -22.5]
},
"jaw": {
"rotation": [0, 0, 0],
"position": [0, -0.27716, -0.11481]
},
"torso": {
"rotation": [-7.5, 0, 0]
},
"tail_1": {
"rotation": [10, 0, 0]
},
"chest": {
"rotation": [-7.5, 0, 0]
},
"leg_left1": {
"rotation": [-6.23088, -21.01584, -15.72279],
"position": [0, -0.5, 0]
},
"leg_left2": {
"rotation": [32.5, 0, 0]
},
"foot_left": {
"rotation": [-43.40659, -12.60837, 8.19252]
},
"toe_left2": {
"rotation": [0, 0, 10]
},
"toe_left3": {
"rotation": [0, 0, -10]
},
"leg_right1": {
"rotation": [-6.23088, 21.01584, 15.72279],
"position": [0, -0.5, 0]
},
"leg_right2": {
"rotation": [32.5, 0, 0]
},
"foot_right": {
"rotation": [-43.40659, 12.60837, -8.19252]
},
"toe_right2": {
"rotation": [0, 0, -10]
},
"toe_right3": {
"rotation": [0, 0, 10]
},
"finger_right2": {
"rotation": [10, 37.5, 0]
},
"claw_right2": {
"rotation": [22.5, 0, 0]
},
"finger_right3": {
"rotation": [-5, -37.5, 0]
},
"claw_right3": {
"rotation": [-22.5, 0, 0]
},
"arm_left1": {
"rotation": [-19.84214, 10.30464, 25.48972]
},
"arm_left2": {
"rotation": [7.5, 0, 22.5]
},
"arm_left3": {
"rotation": [0, 40, 0]
},
"hand_left": {
"rotation": [0, 7.5, 12.5]
},
"finger_left1": {
"rotation": [0, 0, 10]
},
"claw_left1": {
"rotation": [0, 0, 22.5]
},
"finger_left2": {
"rotation": [10, -37.5, 0]
},
"claw_left2": {
"rotation": [22.5, 0, 0]
},
"finger_left3": {
"rotation": [-5, 37.5, 0]
},
"claw_left3": {
"rotation": [-22.5, 0, 0]
}
}
},
"animation.druddigon.battle_idle": {
"loop": true,
"bones": {
"arm_right1": {
"rotation": [-35.0999, -18.72795, -13.41336]
},
"arm_right2": {
"rotation": [1.0804, -5.1849, -12.8416]
},
"arm_right3": {
"rotation": [-29.5083, -47.382, -4.0162]
},
"hand_right": {
"rotation": [0, -7.5, -12.5]
},
"finger_right1": {
"rotation": [0, 0, -10]
},
"claw_right1": {
"rotation": [0, 0, -22.5]
},
"finger_right2": {
"rotation": [15, 40, 0]
},
"claw_right2": {
"rotation": [22.5, 0, 0]
},
"body": {
"rotation": [0, -12.5, 0],
"position": [0, 2, -0.6]
},
"torso": {
"rotation": [9.9863, 0.22463, 0.3039],
"position": [0, -1, 1]
},
"chest": {
"rotation": [-10.08226, 3.37738, -3.68895]
},
"wing_left": {
"rotation": [-7.5, 0, 0]
},
"neck": {
"rotation": [12.48609, 1.84353, -1.68884],
"position": [0, 0, -0.2]
},
"neck_mouth_closed": {
"scale": 0
},
"head": {
"rotation": [-22.54365, 1.71046, -4.69895]
},
"jaw": {
"rotation": [20, 0, 0],
"position": [0, -0.47716, -0.11481]
},
"leg_left1": {
"rotation": [1.06967, -28.21899, -16.6831]
},
"leg_left2": {
"rotation": [35, 0, 0]
},
"foot_left": {
"rotation": [-8.00865, -10.6666, 5.52624]
},
"toe_left1": {
"rotation": [-42.60882, -3.68425, 3.38262]
},
"toe_left3": {
"rotation": [-30.96089, -12.57966, -9.31627]
},
"toe_left2": {
"rotation": [-37.82102, 5.54652, 13.22471]
},
"toe_claw_left2": {
"rotation": [-5, 0, 0]
},
"toe_claw_left3": {
"rotation": [-10, 0, 0]
},
"leg_right1": {
"rotation": [-1.23088, 21.01584, 15.72279]
},
"leg_right2": {
"rotation": [35, 0, 0]
},
"foot_right": {
"rotation": [-8.00865, 10.6666, -5.52624]
},
"toe_right1": {
"rotation": [-42.60882, 3.68425, -3.38262]
},
"toe_right2": {
"rotation": [-37.82102, -5.54652, -13.22471]
},
"toe_claw_right2": {
"rotation": [-5, 0, 0]
},
"toe_right3": {
"rotation": [-30.96089, 12.57966, 9.31627]
},
"toe_claw_right3": {
"rotation": [-10, 0, 0]
},
"head_hidden": {
"scale": 0
},
"wing_right": {
"rotation": [-6.76783, 4.83809, -1.4594]
},
"tail_3": {
"rotation": [2.5, 0, 0]
},
"tail_4": {
"rotation": [10, 0, 0]
},
"wing_left2": {
"rotation": [0, 7.5, 0]
},
"finger_right3": {
"rotation": [-7.5, -40, 0]
},
"claw_right3": {
"rotation": [-22.5, 0, 0]
},
"arm_left1": {
"rotation": [-9.21772, 22.54829, 25.90265]
},
"arm_left2": {
"rotation": [1.0804, 5.1849, 12.8416]
},
"arm_left3": {
"rotation": [-40.89335, 59.21695, -14.63464]
},
"hand_left": {
"rotation": [0, 7.5, 12.5]
},
"finger_left1": {
"rotation": [0, 0, 25]
},
"claw_left1": {
"rotation": [0, 0, 97.5],
"position": [0, -1.8, 0]
},
"finger_left2": {
"rotation": [10.07885, -31.4612, 2.60512]
},
"claw_left2": {
"rotation": [100, 0, 0],
"position": [0, -1.8, 0]
},
"finger_left3": {
"rotation": [-20.94706, 24.49001, 0.53086]
},
"claw_left3": {
"rotation": [-90, 0, 0],
"position": [0, -2, 0]
}
}
},
"animation.druddigon.mouth_test": {
"loop": true,
"bones": {
"jaw": {
"rotation": [22.5, 0, 0],
"position": [0, -1, -0.5]
},
"neck_mouth_closed": {
"scale": 0
}
}
},
"animation.druddigon.new": {
"loop": true,
"bones": {
"head": {
"rotation": [-12.5, 0, 0]
},
"jaw": {
"rotation": [27.5, 0, 0]
},
"head_hidden": {
"scale": 0
}
}
},
"animation.druddigon.angry": {
"loop": true
},
"animation.druddigon.sad": {
"loop": true,
"bones": {
"eyelid_angry_left": {
"position": [-0.1, 0, 0.1]
},
"eyelid_sad_left": {
"position": [0.1, 0, 0]
},
"eyelid_angry_right": {
"position": [0.1, 0, 0.1]
},
"eyelid_sad_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.druddigon.unamused": {
"loop": true,
"bones": {
"eyelid_angry_left": {
"position": [-0.1, 0, 0.1]
},
"eyelid_unamused_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_angry_right": {
"position": [0.1, 0, 0.1]
},
"eyelid_unamused_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.druddigon.happy": {
"loop": true,
"bones": {
"eyelid_angry_left": {
"position": [-0.1, 0, 0.1]
},
"eyelid_happy_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_angry_right": {
"position": [0.1, 0, 0.1]
},
"eyelid_happy_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.druddigon.surpised": {
"loop": true,
"bones": {
"neck_mouth_closed": {
"scale": 0
},
"pupil_left": {
"scale": [1, 0.7, 0.7]
},
"head_hidden": {
"scale": 0
},
"jaw": {
"rotation": [27.5, 0, 0]
},
"eyelid_angry_left": {
"position": [-0.1, 0, 0.1]
},
"pupil_right": {
"scale": [1, 0.7, 0.7]
},
"eyelid_angry_right": {
"position": [0.1, 0, 0.1]
}
}
},
"animation.druddigon.rage": {
"loop": true,
"bones": {
"neck_mouth_closed": {
"scale": 0
},
"pupil_left": {
"scale": [1, 0.7, 0.7]
},
"head_hidden": {
"scale": 0
},
"jaw": {
"rotation": [27.5, 0, 0]
},
"eyelid_angry_left": {
"position": [0, 0.4, 0]
},
"pupil_right": {
"scale": [1, 0.7, 0.7]
},
"eyelid_angry_right": {
"position": [0, 0.4, 0]
}
}
},
"animation.druddigon.hold_item": {
"loop": true,
"bones": {
"claw_right1": {
"rotation": [0, 0, -67.5],
"position": [0, -2, 0]
},
"finger_right2": {
"rotation": [20.11852, -67.56738, 9.02949],
"position": [0.6, -0.3, 1.1]
},
"claw_right2": {
"rotation": [82.5, 0, 0],
"position": [0, -2, 0]
},
"claw_right3": {
"rotation": [-70, 0, 0],
"position": [0, -2, 0]
}
}
}
}
}
@@ -4,36 +4,112 @@
"animation.braixen.ground_idle": {
"loop": true,
"bones": {
"torso": {
"rotation": [2.5, 0, 0]
"torso_bottom": {
"rotation": ["-math.sin(q.anim_time*90*2.5-45)*0.75", 0, 0]
},
"neck": {
"rotation": ["10-math.sin(q.anim_time*90*2.5)*2", 0, 0]
},
"head": {
"rotation": ["2.5+math.sin(q.anim_time*90*2.5+45)*2", 0, 0]
},
"ear_ruff_right": {
"rotation": [0, 5, "-1-math.sin(q.anim_time*90*2.5+45)*1"]
},
"ear_ruff_right2": {
"rotation": [0, 10, "-math.sin(q.anim_time*90*2.5)*1"]
},
"ear_ruff_right3": {
"rotation": [0, 10, "-math.sin(q.anim_time*90*2.5-45)*1"]
},
"ear_ruff_left": {
"rotation": [0, -2.5, "1+math.sin(q.anim_time*90*2.5+45)*1"]
},
"ear_ruff_left2": {
"rotation": [0, -10, "math.sin(q.anim_time*90*2.5)*1"]
},
"ear_ruff_left3": {
"rotation": [0, -10, "math.sin(q.anim_time*90*2.5-45)*1"]
},
"arm_right": {
"rotation": [-1.56101, "12.3977-math.sin(q.anim_time*90*2.5+45)", -55.15982]
},
"arm_right2": {
"rotation": [-3.88714, -27.24513, 8.44236]
},
"arm_left": {
"rotation": [-1.465, "-12.404+math.sin(q.anim_time*90*2.5+45)*2", 55.14094]
},
"arm_left2": {
"rotation": [-6.31274, 31.94715, -11.80868]
},
"tail": {
"rotation": ["5+math.sin(q.anim_time*90*2.5)*2", "math.sin(q.anim_time*90*1.25-90)*4", "math.sin(q.anim_time*90*1.25-90)*2"],
"position": [0, 0, 0.5]
},
"stick_tail": {
"rotation": [0, 0, "-math.sin(q.anim_time*90*1.25-45)*4"]
},
"tail2": {
"rotation": [0, 0, "math.sin(q.anim_time*90*1.25-45)*4"]
},
"tail3": {
"rotation": ["math.sin(q.anim_time*90*2.5-90)*2", 0, 0]
},
"tail4": {
"rotation": ["math.sin(q.anim_time*90*2.5-135)*2", 0, 0]
},
"finger_index_right": {
"rotation": [0, 0, -15]
},
"finger_middle_right": {
"rotation": [0, 0, -10]
},
"finger_ring_right": {
"rotation": [0, 0, -5]
},
"finger_index_left": {
"rotation": [0, 0, 15]
},
"finger_middle_left": {
"rotation": [0, 0, 10]
},
"finger_ring_left": {
"rotation": [0, 0, 5]
},
"waist": {
"rotation": [-5, 0, 0]
},
"chest": {
"rotation": [2.5, 0, 0]
},
"arm_left": {
"rotation": [0, 7.5, 70]
},
"arm_left2": {
"rotation": [-5, 37.5, -2.5]
},
"hand_left": {
"rotation": [57.5, -10, 7.5]
"rotation": [0, 0, -7.5]
},
"neck": {
"rotation": [-5, 0, 0]
"finger_front_left": {
"rotation": [0, 0, 25]
},
"head": {
"rotation": [12.5, 0, 0]
"finger_back_left": {
"rotation": [0, 0, 22.5]
},
"tail": {
"hand_right": {
"rotation": [0, 0, 7.5]
},
"finger_front_right": {
"rotation": [0, 0, -25]
},
"finger_back_right": {
"rotation": [0, 0, -22.5]
},
"stick_hand": {
"scale": 0
},
"ear_ruff_shock_left": {
"scale": 0
},
"ear_ruff_shock_right": {
"scale": 0
},
"skirt_front2": {
"rotation": [5, 0, 0]
},
"stick_tail": {
"rotation": [-5, 0, 0]
},
"leg_left": {
"rotation": [0.88045, -9.96156, -5.07673]
},
@@ -49,78 +125,8 @@
"leg_right3": {
"rotation": [0.00039, 5.00185, -5.99069]
},
"finger_front_left": {
"rotation": [9.99527, 9.84653, 30.20756]
},
"finger_back_left": {
"rotation": [-4.26175, -9.05478, 25.33761]
},
"finger_middle_left": {
"rotation": [0, 0, 27.5]
},
"arm_right": {
"rotation": [65, 22.5, -45],
"position": [0, 0, 0.5]
},
"arm_right2": {
"rotation": [-15, -82.5, 15]
},
"hand_right": {
"rotation": [-10, -22.5, 70]
},
"finger_front_right": {
"rotation": [9.99527, -9.84653, -30.20756]
},
"finger_middle_right": {
"rotation": [0, 0, -27.5]
},
"finger_back_right": {
"rotation": [-4.26175, 9.05478, -25.33761]
},
"ear_ruff_left2": {
"rotation": [0, -7.5, 0]
},
"ear_ruff_left3": {
"rotation": [0, -7.5, 0]
},
"ear_ruff_left4": {
"rotation": [0, -7.5, 0]
},
"skirt_front2": {
"rotation": [-2.5, 0, 0]
},
"foot_right": {
"rotation": [1, 0, 0]
},
"ear_ruff_left": {
"rotation": [0, -7.5, 0]
},
"ear_ruff_right": {
"rotation": [0, 7.5, 0]
},
"ear_ruff_right2": {
"rotation": [0, 7.5, 0]
},
"ear_ruff_right3": {
"rotation": [0, 7.5, 0]
},
"ear_ruff_right4": {
"rotation": [0, 7.5, 0]
},
"skirt_front_left": {
"rotation": [0, 0, 10]
},
"skirt_front_right": {
"rotation": [0, 0, -10]
},
"ear_ruff_shock_left": {
"scale": 0
},
"ear_ruff_shock_right": {
"scale": 0
},
"wand": {
"scale": 0
}
}
},
@@ -128,14 +134,13 @@
"loop": true,
"bones": {
"body": {
"rotation": [0, -52.5, 0],
"position": [-0.5, -2.05, 0]
},
"torso": {
"rotation": [15, -10, 0]
},
"waist": {
"rotation": [-2.5, -2.5, 0]
"rotation": [5, 0, 0]
},
"chest": {
"rotation": [-5, 2.5, 0]
@@ -162,10 +167,10 @@
"rotation": [0, -10, 0]
},
"arm_right": {
"rotation": [-60.09473, -14.92923, -20.56425]
"rotation": [-35.09473, -47.42923, -40.56425]
},
"arm_right2": {
"rotation": [0, -45, 0]
"rotation": [0, -40, 0]
},
"hand_right": {
"rotation": [0, 27.5, 15]
@@ -180,10 +185,10 @@
"rotation": [0, 0, -77.5]
},
"neck": {
"rotation": [0, 32.5, -7.5]
"rotation": [0, 5, 0]
},
"head": {
"rotation": [-7.5, 20, -5]
"rotation": [-10, 0, 0]
},
"ear_ruff_left2": {
"rotation": [0, -12.5, 0]
@@ -216,32 +221,28 @@
"scale": 0
},
"leg_left": {
"rotation": [-0.5, -35, -26],
"position": [1, 0, 0]
"rotation": [5.38152, -19.291, -15.91527]
},
"leg_left2": {
"rotation": [10, 0, 0]
"rotation": [25, 0, 0]
},
"leg_left3": {
"rotation": [-22.5, 0, 0]
"rotation": [-16.28567, 14.26008, -10.25103]
},
"foot_left": {
"rotation": [29.78634, -18.01295, 11.28749],
"position": [0, -0.5, 0]
"rotation": [-12.32417, 1.61888, 12.39638]
},
"leg_right": {
"rotation": [-7.80674, 36.44232, 19.22515],
"position": [-1, -0.75, -0.75]
"rotation": [-27.5, 0, 0]
},
"leg_right2": {
"rotation": [29.75489, -5.05904, 8.04401]
"rotation": [27.25489, -5.05904, 5.54401]
},
"leg_right3": {
"rotation": [-30.5, -2, -1]
"rotation": [-25, 0, 0]
},
"foot_right": {
"rotation": [22.5, 20, -10],
"position": [0, -0.5, 0]
"rotation": [24.78729, 3.74196, -6.50446]
},
"ear_ruff_right2": {
"rotation": [0, 12.5, 0]
@@ -252,111 +253,24 @@
"ear_ruff_right4": {
"rotation": [0, 17.5, 0]
},
"stick_hand": {
"rotation": [90, 10, 0],
"position": [6.5, -1, -0.5]
},
"skirt_front_left": {
"rotation": [0, 0, 7.5]
},
"skirt_front_right": {
"rotation": [0, 0, -2.5]
},
"fire": {
"rotation": [-7.15656, 2.24944, 17.35932]
},
"ear_ruff_shock_left": {
"scale": 0
},
"ear_ruff_shock_right": {
"scale": 0
},
"skirt": {
"rotation": [-5, 0, 0]
},
"body_wand": {
"rotation": [0, -52.5, 0],
"position": [-0.5, -2.05, 0]
},
"torso_wand": {
"rotation": [15, -10, 0]
},
"waist_wand": {
"rotation": [-2.5, -2.5, 0]
},
"chest_wand": {
"rotation": [-5, 2.5, 0]
},
"arm_wand": {
"rotation": [-60.09473, -14.92923, -20.56425]
},
"arm2_wand": {
"rotation": [0, -45, 0]
},
"hand_wand": {
"rotation": [0, 27.5, 15]
},
"wand": {
"rotation": [90, 10, 0],
"position": [6.5, -1, -0.5]
}
}
},
"animation.braixen.blink": {
"animation_length": 0.1667,
"bones": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, -0.1],
"0.125": {"pre": [0.1, 0, -0.1], "post": [0.1, 0, -0.1]},
"0.1667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, -0.1],
"0.125": {"pre": [-0.1, 0, -0.1], "post": [-0.1, 0, -0.1]},
"0.1667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
}
}
}
},
"animation.braixen.cry": {
"animation_length": 1,
"bones": {
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [-2.05, 0, 0],
"0.0833": [-2.7, 0, 0],
"0.1667": [4, 0, 0],
"0.2083": [3.72, 0, 0],
"0.375": [-2.38, 0, 0],
"0.4167": [-2.7, 0, 0],
"0.5": [-2.4, 0, 0],
"0.6667": [-0.3, 0, 0],
"0.75": [0, 0, 0]
}
},
"jaw": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [27.2, 0, 0],
"0.0833": [30, 0, 0],
"0.1667": [19, 0, 0],
"0.2083": [17.65, 0, 0],
"0.3333": [57.56, 0, 0],
"0.375": [60, 0, 0],
"0.4167": [56.99, 0, 0],
"0.7083": [4.23, 0, 0],
"0.7917": [0, 0, 0]
}
},
"fangs": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, -0.5, 0],
"0.625": [0, -0.5, 0],
"0.6667": [0, 0, 0]
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.braixen.cry"
}
}
},
@@ -478,7 +392,7 @@
"finger_back_right": {
"rotation": [0, 0, -22.5]
},
"wand": {
"stick_hand": {
"scale": 0
},
"ear_ruff_shock_left": {
@@ -494,6 +408,198 @@
"rotation": [0, -12.5, 0]
}
}
},
"animation.braixen.blink": {
"animation_length": 0.1667,
"bones": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, -0.1],
"0.125": [0.1, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, -0.1],
"0.125": [-0.1, 0, -0.1],
"0.1667": [0, 0, 0]
}
}
}
},
"animation.braixen.cry": {
"animation_length": 1,
"bones": {
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [-2.05, 0, 0],
"0.0833": [-2.7, 0, 0],
"0.1667": [4, 0, 0],
"0.2083": [3.72, 0, 0],
"0.375": [-2.38, 0, 0],
"0.4167": [-2.7, 0, 0],
"0.5": [-2.4, 0, 0],
"0.6667": [-0.3, 0, 0],
"0.75": [0, 0, 0]
}
},
"jaw": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": [27.2, 0, 0],
"0.0833": [30, 0, 0],
"0.1667": [19, 0, 0],
"0.2083": [17.65, 0, 0],
"0.3333": [57.56, 0, 0],
"0.375": [60, 0, 0],
"0.4167": [56.99, 0, 0],
"0.7083": [4.23, 0, 0],
"0.7917": [0, 0, 0]
}
},
"fangs": {
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, -0.5, 0],
"0.625": [0, -0.5, 0],
"0.6667": [0, 0, 0]
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.braixen.cry"
}
}
},
"animation.braixen.surprise_hair": {
"loop": true,
"bones": {
"ear_ruff_left": {
"rotation": [0, 0, -10]
},
"ear_ruff_left2": {
"rotation": [0, 0, 10]
},
"ear_ruff_side_left": {
"rotation": [3.57152, 21.79524, -14.03271]
},
"ear_ruff_left3": {
"rotation": [0, 0, -2.5]
},
"ear_ruff_left4": {
"rotation": [0, 0, -12.5]
},
"ear_ruff_right": {
"rotation": [0, 0, 10]
},
"ear_ruff_right2": {
"rotation": [0, 0, -10]
},
"ear_ruff_side_right": {
"rotation": [3.57152, -21.79524, 14.03271]
},
"ear_ruff_right3": {
"rotation": [0, 0, 2.5]
},
"ear_ruff_right4": {
"rotation": [0, 0, 12.5]
},
"ear_ruff_shock_left": {
"rotation": [0, 0, 2.5]
},
"ear_ruff_shock_left2": {
"rotation": [0, 0, -12.5]
},
"ear_ruff_shock_right": {
"rotation": [0, 0, -2.5]
},
"ear_ruff_shock_right2": {
"rotation": [0, 0, 12.5]
}
}
},
"animation.braixen.shock": {
"loop": true,
"bones": {
"jaw": {
"rotation": [47.5, 0, 0]
},
"pupil_left": {
"position": [-0.1, 0, 0],
"scale": [0.6, 0.6, 1]
},
"pupil_right": {
"position": [0.1, 0, 0],
"scale": [0.6, 0.6, 1]
}
}
},
"animation.braixen.angry": {
"loop": true,
"bones": {
"eye_angry_left": {
"position": [0.1, 0, -0.1]
},
"eye_angry_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.braixen.sad": {
"loop": true,
"bones": {
"eye_sad_left": {
"position": [0.1, 0, -0.1]
},
"eye_sad_right": {
"position": [-0.1, 0, -0.1]
},
"pupil_left": {
"position": [0.09, 0, 0]
},
"pupil_right": {
"position": [-0.09, 0, 0]
}
}
},
"animation.braixen.happy": {
"loop": true,
"bones": {
"eyelid_happy_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_happy_right": {
"position": [-0.1, 0, -0.1]
},
"jaw": {
"rotation": [47.5, 0, 0]
}
}
},
"animation.braixen.blush": {
"loop": true,
"bones": {
"blush_left": {
"position": [0.1, 0, 0]
},
"blush_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.braixen.hurt": {
"loop": true,
"bones": {
"eyelid_recoil_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_recoil_right": {
"position": [-0.1, 0, -0.1]
}
}
}
}
}
@@ -3,443 +3,295 @@
"animations": {
"animation.delphox.ground_idle": {
"loop": true,
"animation_length": 8,
"bones": {
"arm_left": {
"rotation": [0, -5, 60]
},
"arm_left2": {
"rotation": [0, 12.5, 0]
},
"hand_left": {
"rotation": [0, 0, 15]
},
"finger_front_left": {
"rotation": [0, 0, 17.5]
},
"finger_middle_left": {
"rotation": [0, 0, 12.5]
},
"finger_back_left": {
"rotation": [0, 0, 30]
},
"arm_right": {
"rotation": [0, 5, -60]
},
"arm_right2": {
"rotation": [0, -12.5, 0]
},
"hand_right": {
"rotation": [0, 0, -15]
},
"finger_front_right": {
"rotation": [0, 0, -17.5]
},
"finger_back_right": {
"rotation": [0, 0, -30]
},
"head": {
"rotation": ["5+math.sin(q.anim_time*90*1)*-1", 0, 0]
},
"ear_left_ruff_main": {
"rotation": [0.18349, -15.01207, 0.11941]
},
"ear_ruff_top_left": {
"rotation": [0, -5, 0]
},
"ear_ruff_middle_left": {
"rotation": [-5, 10, 0]
},
"ear_right_ruff_main": {
"rotation": [0.18349, 15.01207, -0.11941]
"rotation": ["10+math.sin(q.anim_time*90*1-15)*2", 0, 0]
},
"ear_ruff_top_right": {
"rotation": [0, 5, 0]
"rotation": [0, 7.5, -10],
"position": [-0.3, 0, 0.5]
},
"ear_ruff_top_right2": {
"rotation": [0, 15, "-math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_top_right3": {
"rotation": [0, 7.5, "10-math.sin(q.anim_time*90*1-215)*3"]
},
"ear_ruff_middle_right": {
"rotation": [-5, -10, 0]
"rotation": [0, -2.5, -12.5]
},
"leg_left": {
"rotation": [-10.50431, -1.61684, -2.5578],
"position": [0, 0, -0.5]
"ear_ruff_middle_right2": {
"rotation": [0, 20, "5-math.sin(q.anim_time*90*1-180)*3"]
},
"leg_left3": {
"rotation": [1.5, 0, 0]
},
"foot_left": {
"rotation": [4.48529, -0.57217, 2.94498]
},
"leg_right": {
"rotation": [1.10693, 12.45167, 5.12076]
},
"leg_right3": {
"rotation": [0, 0, -2.5]
},
"foot_right": {
"rotation": [0, 0, -3]
},
"torso": {
"rotation": ["2.5+math.sin(q.anim_time*90*1)*1", 0, 0],
"position": [0, "math.cos(q.anim_time*90*1)*0.2", 0]
},
"waist": {
"rotation": ["-1+math.sin(q.anim_time*90*1-30)*1", 0, 0]
},
"tail": {
"rotation": [-23, 0, 0]
},
"robe_left": {
"rotation": [0, 2.5, 0]
},
"robe_left_outer2": {
"rotation": [0, -2.5, 0]
},
"tail2": {
"rotation": [-12.5, 0, 0]
},
"tail3": {
"rotation": [-20, 0, 0]
},
"tail4": {
"rotation": [5, 0, 0]
},
"tail5": {
"rotation": [25, 0, 0]
},
"tail6": {
"rotation": [17.5, 0, 0]
},
"tail7": {
"rotation": [-7.5, 0, 0]
},
"ear_ruff_shock_left": {
"rotation": [0, -5, 0],
"scale": 0
},
"ear_ruff_shock_right": {
"rotation": [0, 5, 0],
"scale": 0
},
"body": {
"position": [0, -0.2, 0]
},
"torso_cloak": {
"rotation": [-1, 0, 0]
},
"finger_middle_right": {
"rotation": [0, 0, -12.5]
},
"neck": {
"rotation": ["-2.5+math.sin(q.anim_time*90*1-30)*-2", 0, 0]
},
"ear_ruff_bottom_left": {
"rotation": [0, -2.5, 15]
"ear_ruff_middle_right3": {
"rotation": [0, 15, "7.5-math.sin(q.anim_time*90*1-215)*3"]
},
"ear_ruff_bottom_right": {
"rotation": [0, 2.5, -15]
"rotation": [0, 10, -17.5],
"position": [-0.1, 0, 0.25]
},
"leg_left2": {
"rotation": [5, 0, 0]
"ear_ruff_bottom_right2": {
"rotation": [0, 10, "12.5-math.sin(q.anim_time*90*1-180)*3"]
},
"leg_right2": {
"rotation": [2.5, 0, 0]
"ear_ruff_bottom_right3": {
"rotation": [0, 17.5, "12.5-math.sin(q.anim_time*90*1-215)*3"]
},
"robe_left_outer": {
"rotation": [0, 2.5, 0]
"ear_ruff_top_left": {
"rotation": [0, -7.5, 10],
"position": [0.3, 0, 0.5]
},
"robe_left_outer3": {
"rotation": [0, -2.5, 0]
"ear_ruff_top_left2": {
"rotation": [0, -15, "math.sin(q.anim_time*90*1-180)*3"]
},
"chest": {
"rotation": ["math.sin(q.anim_time*90*1)*-1", 0, 0]
"ear_ruff_top_left3": {
"rotation": [0, -7.5, "-10+math.sin(q.anim_time*90*1-215)*3"]
},
"ear_right": {
"rotation": [0, 0, "math.sin(q.anim_time*90*1-60)*2"]
"ear_ruff_middle_left": {
"rotation": [0, 2.5, 12.5]
},
"ear_right_main": {
"rotation": [0, 0, "math.sin(q.anim_time*90*1-30)*1"]
"ear_ruff_middle_left2": {
"rotation": [0, -20, "-5+math.sin(q.anim_time*90*1-180)*3"]
},
"robe_right": {
"rotation": [0, 2.5, 0]
"ear_ruff_middle_left3": {
"rotation": [0, -15, "-7.5+math.sin(q.anim_time*90*1-215)*3"]
},
"robe_right_outer": {
"rotation": [0, 2.5, 0]
"ear_ruff_bottom_left": {
"rotation": [0, -10, 17.5],
"position": [0.1, 0, 0.25]
},
"robe_right_outer2": {
"rotation": [0, -2.5, 0]
"ear_ruff_bottom_left2": {
"rotation": [0, -10, "-12.5+math.sin(q.anim_time*90*1-180)*3"]
},
"robe_right_outer3": {
"rotation": [0, -2.5, 0]
},
"wand": {
"scale": 0
}
}
},
"animation.delphox.battle_idle": {
"loop": true,
"animation_length": 8,
"bones": {
"body": {
"rotation": [0, -10, 0],
"position": [0, -3, 0]
},
"torso": {
"rotation": ["30+math.sin(q.anim_time*90*1.5)*1", -17.5, -2.5],
"position": [0.25, "0.25+math.cos(q.anim_time*90*1.5)*-0.2", -0.5]
},
"waist": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1.5-30)*1", -2.5, 5]
},
"chest": {
"rotation": ["-7.5+math.sin(q.anim_time*90*1.5-75)*1", -5, -2.5]
},
"arm_left": {
"rotation": [-10, -27.5, 25],
"position": [1, -0.35, 1]
},
"arm_left2": {
"rotation": [-7.5, 75, -7.5]
},
"finger_front_left": {
"rotation": [0, 0, 47.5]
},
"finger_middle_left": {
"rotation": [0, 0, 62.5]
},
"finger_back_left": {
"rotation": [0, 0, 75]
"ear_ruff_bottom_left3": {
"rotation": [0, -17.5, "-12.5+math.sin(q.anim_time*90*1-215)*3"]
},
"arm_right": {
"rotation": [-57.5, -30, -25],
"position": [-1, -0.75, 0.25]
"rotation": [0, "-12.5+math.sin(q.anim_time*90*1+30)*2", -52.5]
},
"arm_right2": {
"rotation": [7.5, -55, -17.5]
},
"arm_right_ruff": {
"rotation": [-15, 15, -7.5]
"rotation": [3.31914, "-14.6364+math.sin(q.anim_time*90*1+90)*2", -12.92638]
},
"hand_right": {
"rotation": [0, 22.5, 0],
"position": [-0.25, 0, 0]
"rotation": [0, 0, -12.5]
},
"finger_front_right": {
"finger_index_right": {
"rotation": [0, 0, -50]
},
"finger_middle_right": {
"rotation": [0, 0, -55]
"rotation": [0, 0, -52.5]
},
"finger_back_right": {
"rotation": [0, 0, -65]
"finger_ring_right": {
"rotation": [0, 0, -60]
},
"ear_left_ruff_main": {
"rotation": [0.18349, -15.01207, 0.11941]
"arm_left": {
"rotation": [1.36797, "-32.4703+math.sin(q.anim_time*90*1-15)*2", "57.0477+math.sin(q.anim_time*90*1-60)*3"]
},
"ear_ruff_top_left": {
"rotation": [0, -5, 0]
},
"ear_ruff_middle_left": {
"rotation": [-5, 10, 0]
},
"ear_ruff_bottom_left": {
"rotation": [0, -2.5, 15]
},
"ear_right_ruff_main": {
"rotation": [0.18349, 15.01207, -0.11941]
},
"ear_ruff_top_right": {
"rotation": [0, 5, 0]
},
"ear_ruff_middle_right": {
"rotation": [-5, -10, 0]
},
"ear_ruff_bottom_right": {
"rotation": [0, 2.5, -15]
},
"leg_left": {
"rotation": [7.5, -10, -15],
"position": [0.25, -0.25, 1]
},
"leg_left2": {
"rotation": [22.5, 0, -7.5]
},
"leg_left3": {
"rotation": [-2.5, 0, 0]
},
"foot_left": {
"rotation": [-21.5, 0, 20],
"position": [-0.5, -1.5, -0.75]
},
"leg_right": {
"rotation": [-27.5, 0, 7.5],
"position": [0, 0, -1]
},
"leg_right2": {
"rotation": [17.5, 0, 0]
},
"leg_right3": {
"rotation": [-7.5, 7.5, 10]
},
"foot_right": {
"rotation": [17.5, 17.5, -12.5],
"position": [0.25, -0.25, 0]
},
"wand": {
"rotation": [0, 0, 77.5],
"position": [1, 0, 0]
},
"ear_ruff_shock_left": {
"rotation": [0, -5, 0],
"scale": 0
},
"ear_ruff_shock_right": {
"rotation": [0, 5, 0],
"scale": 0
},
"body_wand": {
"rotation": [0, -10, 0],
"position": [0, -3, 0]
},
"torso_wand": {
"rotation": ["30+math.sin(q.anim_time*90*1.5)*1", -17.5, -2.5],
"position": [0.25, "0.25+math.cos(q.anim_time*90*1.5)*-0.2", -0.5]
},
"waist_wand": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1.5-30)*1", -2.5, 5]
},
"chest_wand": {
"rotation": ["-7.5+math.sin(q.anim_time*90*1.5-75)*1", -5, -2.5]
},
"arm_wand": {
"rotation": [-57.5, -30, -25],
"position": [-1, -0.75, 0.25]
},
"arm2_wand": {
"rotation": [7.5, -55, -17.5]
},
"hand_wand": {
"rotation": [0, 22.5, 0],
"position": [-0.25, 0, 0]
"arm_left2": {
"rotation": [-0.82097, "60.3299+math.sin(q.anim_time*90*1-95)*4", "3.238+math.sin(q.anim_time*90*1-180)*4"]
},
"hand_left": {
"rotation": [-12.5, 32.5, -15]
"rotation": [0, 0, 20]
},
"shoulder_right_ruff": {
"rotation": [0, 10, 0]
"finger_index_left": {
"rotation": [0, 0, 15]
},
"finger_middle_left": {
"rotation": [0, 0, 10]
},
"finger_ring_left": {
"rotation": [0, 0, 5]
},
"tail": {
"rotation": ["-12.5+math.sin(q.anim_time*90*2)*4", "math.sin(q.anim_time*90*1-90)*8", "math.sin(q.anim_time*90*1-90)*2"]
},
"tail2": {
"rotation": [-15, "math.sin(q.anim_time*90*1-90-45)*8", 0]
},
"tail3": {
"rotation": [-12.5, "math.sin(q.anim_time*90*1-90-90)*8", 0]
},
"tail4": {
"rotation": [15, "math.sin(q.anim_time*90*1-90-135)*8", 0]
},
"tail5": {
"rotation": [12.5, "math.sin(q.anim_time*90*1-90-180)*8", 0]
},
"leg_right": {
"rotation": [0, 15, 0]
},
"leg_left": {
"rotation": [0, -17.5, 0]
},
"body": {
"rotation": [0, -12.5, 0]
},
"torso": {
"rotation": ["math.sin(q.anim_time*90*1-135)*1", 3.5, 0],
"position": [0, 0, 0]
},
"chest": {
"rotation": ["-2.5+math.sin(q.anim_time*90*1-90)*2", 8, 0]
},
"neck": {
"rotation": [0, 0, 0],
"position": [0, 0, -0.25]
},
"head_ruff_right": {
"rotation": [0, "7.5+math.sin(q.anim_time*90*1-90)*2", 0]
},
"head_ruff_left": {
"rotation": [0, "-7.5-math.sin(q.anim_time*90*1-90)*2", 0]
},
"ear_right_main": {
"rotation": ["-10+math.sin(q.anim_time*90*1-150)*3", 0, 0]
},
"ear_right": {
"rotation": [0, 0, "2.55+math.sin(q.anim_time*90*1-150)*1"]
},
"ear_right_ruff_main": {
"rotation": [0, "2.5+math.sin(q.anim_time*90*1-45)*3", "4-math.sin(q.anim_time*90*1-135)*1.5"],
"position": [-0.2, 0, 0]
},
"ear_left_main": {
"rotation": ["-10+math.sin(q.anim_time*90*1-150)*3", 0, 0]
},
"ear_left": {
"rotation": [0, 0, "-2.55-math.sin(q.anim_time*90*1-150)*1"]
},
"ear_left_ruff_main": {
"rotation": [0, "-2.5-math.sin(q.anim_time*90*1-45)*3", "-4+math.sin(q.anim_time*90*1-135)*1.5"],
"position": [0.2, 0, 0]
},
"hand_stick": {
"position": [4.9, -1, 0]
},
"finger_index_right2": {
"rotation": [0, 0, -60]
},
"finger_middle_right2": {
"rotation": [0, 0, -57.5]
},
"finger_ring_right2": {
"rotation": [0, 0, -42.5]
},
"arm_left_ruff": {
"rotation": ["-15+math.sin(q.anim_time*90*1+45)*10", 0, 0]
},
"chest_ruff_top_right": {
"rotation": [0, 0, -40]
},
"chest_ruff_top_left": {
"rotation": [0, 0, 40]
},
"chest_ruff_right_top": {
"rotation": [0, 0, "7.5+math.sin(q.anim_time*90*1)*2"]
},
"chest_ruff_right_bottom": {
"rotation": [0, 0, "-2.5+math.sin(q.anim_time*90*1-45)*2"]
},
"chest_ruff_right_bottom2": {
"rotation": [0, 0, "-20+math.sin(q.anim_time*90*1-90)*2"]
},
"chest_ruff_left_top": {
"rotation": [0, 0, "-12.5-math.sin(q.anim_time*90*1)*2"]
},
"chest_ruff_left_bottom": {
"rotation": [0, 0, "5-math.sin(q.anim_time*90*1-45)*2"]
},
"chest_ruff_left_bottom2": {
"rotation": [0, 0, "15-math.sin(q.anim_time*90*1-90)*2"]
},
"leg_right_outer2": {
"rotation": [0, 0, "-0.35+math.sin(q.anim_time*90*1-45)*0.5"]
},
"leg_right_outer4": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*1-90)*2"]
},
"leg_right_outer5": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*1-135)*2"]
},
"leg_right_outer6": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*1-180)*2"]
},
"leg_right_outer7": {
"rotation": [0, 0, "0+math.sin(q.anim_time*90*1-215)*2"]
},
"leg_left_outer": {
"rotation": [0, 0, 0]
},
"leg_left_outer2": {
"rotation": [0, 0, "0.35-math.sin(q.anim_time*90*1-45)*0.5"]
},
"leg_left_outer4": {
"rotation": [0, 0, "0-math.sin(q.anim_time*90*1-90)*2"]
},
"leg_left_outer5": {
"rotation": [0, 0, "0-math.sin(q.anim_time*90*1-135)*2"]
},
"leg_left_outer6": {
"rotation": [0, 0, "0-math.sin(q.anim_time*90*1-180)*2"]
},
"leg_left_outer7": {
"rotation": [0, 0, "0-math.sin(q.anim_time*90*1-215)*2"]
},
"flame": {
"rotation": [
"-40+3*(math.sin(q.anim_time*90*3*2-90)*1-1)+6*(math.sin(q.anim_time*90*3/2-90)*1-1)",
"-35+5*(math.sin(q.anim_time*90*3-150)*1-1)+6*(math.sin(q.anim_time*90*3/2-90)*1-1)",
35
]
},
"torso_cloak": {
"rotation": [-27.5, 0, 0]
"rotation": [-5, 0, 0]
},
"shoulder_left_ruff": {
"rotation": [-12.5, 0, 0]
},
"arm_left_ruff": {
"rotation": [-35, 0, 0]
},
"arm_left_ruff2": {
"rotation": [-15, 0, 0]
},
"neck": {
"rotation": ["17.5+math.sin(q.anim_time*90*1.5-110)*-2", 20, 5],
"position": [0, -1, 0]
},
"head": {
"rotation": ["-20+math.sin(q.anim_time*90*1.5-90)*3", "15+math.sin(q.anim_time*90*1.5-90)*-2", -15]
},
"eye_angry_left": {
"position": [0.1, 0, -0.1]
},
"eye_angry_right": {
"position": [-0.1, 0, -0.1]
},
"head_ruff_right": {
"rotation": [-1.64071, -0.82614, -1.75664]
},
"shoulder_fur_left": {
"rotation": [0, 0, -35]
},
"shoulder_fur_right": {
"rotation": [0, 0, 35]
},
"tail": {
"rotation": ["-8+math.sin(q.anim_time*90*1.5-90)*10", "math.sin(q.anim_time*90*1-90)*20", 0],
"position": [0, 1, 0]
},
"tail2": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1.5-120)*12", "math.sin(q.anim_time*90*1-120)*25", 0]
},
"tail3": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1.5-170)*13", "math.sin(q.anim_time*90*1-170)*30", 0]
},
"tail4": {
"rotation": ["-12.5+math.sin(q.anim_time*90*1.5-210)*18", "math.sin(q.anim_time*90*1-200)*35", 0]
},
"tail5": {
"rotation": ["10+math.sin(q.anim_time*90*1.5-260)*22", "math.sin(q.anim_time*90*1-250)*35", 0]
},
"tail6": {
"rotation": ["5+math.sin(q.anim_time*90*1.5-260)*25", "math.sin(q.anim_time*90*1-290)*40", 0]
},
"tail7": {
"rotation": ["math.sin(q.anim_time*90*1.5-290)*50", "math.sin(q.anim_time*90*1-310)*45", 0]
},
"robe_left": {
"rotation": [20, -15, -15],
"position": [0, 0, 1]
},
"robe_left2_rotation": {
"rotation": [-5, 0, 2.5]
},
"robe_left3_rotation": {
"rotation": [-2.5, 0, 0]
},
"robe_left_outer": {
"rotation": [0, -2.5, 0]
},
"robe_left_outer2": {
"rotation": [0, -5, 0]
},
"robe_right": {
"rotation": [-15, -2.5, 15],
"position": [0, -0.75, -1]
},
"robe_right2_rotation": {
"rotation": [5, 0, 2.5]
},
"robe_right3_rotation": {
"rotation": [5, 0, -2.5]
},
"robe_right_outer": {
"rotation": [0, 2.5, 0]
},
"robe_right_outer2": {
"rotation": [2.5, 5, 0]
},
"robe_right_outer3": {
"rotation": [0, 5, 0]
},
"robe_front_middle": {
"rotation": [-7.5, -20, -5],
"position": [1.5, 0, -1.65]
},
"robe_front_middle2_rotation": {
"rotation": [-2.5, -7.5, -0.5],
"position": [-1, -1, 0]
},
"robe_front_middle3_rotation": {
"rotation": [5, 7.5, -5],
"position": [-1.86367, 0.85692, -0.23757]
},
"robe_middle_front_fur": {
"rotation": [-10, 0, 0]
},
"robe_front_middle3": {
"rotation": [0, -10, 7.5]
"finger_front_left": {
"rotation": [0, 0, 12.5]
},
"finger_back_left": {
"rotation": [0, 0, 35]
},
"arm_right_ruff": {
"rotation": [-5, 0, 0]
},
"arm_right_ruff2": {
"rotation": [-10, 0, 0]
},
"finger_front_right": {
"rotation": [0, 0, -40]
},
"finger_back_right": {
"rotation": [0, 0, -60]
},
"stick_hand": {
"scale": 0
},
"ear_ruff_shock_left": {
"scale": 0
},
"ear_ruff_top_left4": {
"rotation": [0, -12.5, 0]
},
"ear_ruff_middle_left4": {
"rotation": [0, -10, 0]
},
"ear_ruff_shock_right": {
"scale": 0
},
"ear_ruff_top_right4": {
"rotation": [0, 12.5, 0]
},
"ear_ruff_middle_right4": {
"rotation": [0, 10, 0]
}
}
},
"animation.delphox.battle_idle2_wip": {
"animation.delphox.battle_idle": {
"loop": true,
"bones": {
"robe_left": {
@@ -629,6 +481,20 @@
"foot_right2": {
"rotation": [0, 0, 0]
},
"robe_right": {
"rotation": [-34.35188, 12.84924, 4.16618],
"position": [0, 0, -1]
},
"robe_right2": {
"rotation": [32.62765, -10.18372, 3.05577],
"position": [0, -1, 0]
},
"robe_right2_rotation": {
"rotation": [2.41492, 0.64686, -14.98637]
},
"robe_right3_rotation": {
"rotation": [0, 0, 5]
},
"tail2": {
"rotation": [-17.56274, -4.76804, 1.50701]
},
@@ -647,7 +513,7 @@
"tail7": {
"rotation": [-27.5, 0, 0]
},
"wand": {
"stick_hand": {
"rotation": [115.18907, -6.79382, 69.31542],
"position": [7.5, -2, -2]
},
@@ -664,34 +530,6 @@
"ear_ruff_shock_right": {
"rotation": [0, 5, 0],
"scale": 0
},
"robe_right": {
"rotation": [28.44706, -2.60661, -11.92606],
"position": [1, 0, 0]
},
"robe_right2_rotation": {
"rotation": [-17.10967, 3.73172, 11.93845],
"position": [0, -1, 0]
},
"robe_right3_rotation": {
"rotation": [-7.5, 0, 0]
}
}
},
"animation.delphox.blink": {
"animation_length": 0.1667,
"bones": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, -0.1],
"0.1667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, -0.1],
"0.1667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
}
}
}
},
@@ -979,7 +817,7 @@
"finger_back_right": {
"rotation": [0, 0, -45]
},
"wand": {
"stick_hand": {
"scale": 0
},
"ear_ruff_shock_left": {
@@ -1028,6 +866,25 @@
}
}
},
"animation.delphox.blink": {
"animation_length": 0.1667,
"bones": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, -0.1],
"0.125": [0.1, 0, -0.1],
"0.1667": [0, 0, 0]
}
},
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, -0.1],
"0.125": [-0.1, 0, -0.1],
"0.1667": [0, 0, 0]
}
}
}
},
"animation.delphox.cry": {
"animation_length": 1.75,
"bones": {
@@ -1095,6 +952,170 @@
"effect": "pokemon.delphox.cry"
}
}
},
"animation.delphox.surprise_hair": {
"animation_length": 0.0417,
"bones": {
"ear_ruff_top_left": {
"rotation": [0.86996, -0.48705, -9.93723]
},
"ear_ruff_top_left2": {
"rotation": [0, 0, 0]
},
"ear_ruff_top_left3": {
"rotation": [0, 0, -10]
},
"ear_ruff_top_left4": {
"rotation": [0, 0, -25]
},
"ear_ruff_middle_left": {
"rotation": [0, 0, 7.5]
},
"ear_ruff_middle_left2": {
"rotation": [0, 0, -12.5]
},
"ear_ruff_middle_left3": {
"rotation": [-1.63786, -2.36303, 19.89762]
},
"ear_ruff_middle_left4": {
"rotation": [0, 0, -25]
},
"ear_ruff_bottom_left": {
"rotation": {
"0.0": [0.1467, 0.51916, 9.98614],
"0.0417": [0.23463, 0.48579, 19.98647]
}
},
"ear_ruff_bottom_left2": {
"rotation": [-0.08929, 0.02949, 17.49954]
},
"ear_ruff_bottom_left3": {
"rotation": [0, 0, 2.5]
},
"ear_ruff_top_right": {
"rotation": [0.86996, 0.48705, 9.93723]
},
"ear_ruff_top_right2": {
"rotation": [0, 0, 0]
},
"ear_ruff_top_right3": {
"rotation": [0, 0, 10]
},
"ear_ruff_top_right4": {
"rotation": [0, 0, 25]
},
"ear_ruff_middle_right2": {
"rotation": [0, 0, 12.5]
},
"ear_ruff_middle_right3": {
"rotation": [-1.63786, 2.36303, -19.89762]
},
"ear_ruff_middle_right4": {
"rotation": [0, 0, 25]
},
"ear_ruff_middle_right": {
"rotation": [0, 0, -7.5]
},
"ear_ruff_bottom_right": {
"rotation": [0.1467, -0.51916, -9.98614]
},
"ear_ruff_bottom_right2": {
"rotation": [-0.08929, -0.02949, -17.49954]
},
"ear_ruff_bottom_right3": {
"rotation": [0, 0, -2.5]
},
"ear_ruff_shock_left_top": {
"rotation": [0, 0, -22.5]
},
"ear_ruff_shock_left_middle": {
"rotation": [0, 0, 7.5]
},
"ear_ruff_shock_left_bottom": {
"rotation": [0, 0, 25]
},
"ear_ruff_shock_right_top": {
"rotation": [0, 0, 22.5]
},
"ear_ruff_shock_right_middle": {
"rotation": [0, 0, -7.5]
},
"ear_ruff_shock_right_bottom": {
"rotation": [0, 0, -25]
}
}
},
"animation.delphox.shock": {
"loop": true,
"bones": {
"jaw": {
"rotation": [62.5, 0, 0]
},
"pupil_left": {
"scale": [0.6, 0.6, 1]
},
"pupil_right": {
"scale": [0.6, 0.6, 1]
}
}
},
"animation.delphox.angry": {
"loop": true,
"bones": {
"eye_angry_left": {
"position": [0.1, 0, -0.1]
},
"eye_angry_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.delphox.sad": {
"loop": true,
"bones": {
"eye_sad_left": {
"position": [0.1, 0, -0.1]
},
"eye_sad_right": {
"position": [-0.1, 0, -0.1]
}
}
},
"animation.delphox.happy": {
"loop": true,
"bones": {
"eyelid_happy_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_happy_right": {
"position": [-0.1, 0, -0.1]
},
"jaw": {
"rotation": [62.5, 0, 0]
}
}
},
"animation.delphox.blush": {
"loop": true,
"bones": {
"blush_left": {
"position": [0.1, 0, 0]
},
"blush_right": {
"position": [-0.1, 0, 0]
}
}
},
"animation.delphox.hurt": {
"loop": true,
"bones": {
"eyelid_recoil_left": {
"position": [0.1, 0, -0.1]
},
"eyelid_recoil_right": {
"position": [-0.1, 0, -0.1]
}
}
}
}
}
@@ -280,14 +280,6 @@
"rotation": [-5, 10, -7.5]
}
}
},
"animation.sylveon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.sylveon.cry"
}
}
}
}
}
Loaded 100 of 219 files, more files were not shown because too many files have changed in this diff. Show more