Compare commits

...
Author SHA1 Message Date
Apion d0cbc78b31 Configurable dance distance 2025-04-26 15:29:06 -04:00
Apion f2a03e40ed Make dancing pose driven instead of a molang condition 2025-04-26 15:08:39 -04:00
Landon Wills 87071bedbe Move dance behaviour to delegates 2025-04-15 07:59:40 -04:00
Landon ebe33e200c Remove debug code 2025-04-15 11:36:50 +00:00
Landon 15f30721b4 Rename dance pose 2025-04-15 06:12:03 +00:00
Landon Wills c3c4d6685e :catJAM: 2025-04-14 23:34:38 -04:00
Landon bb6e5607f1 Merge branch 'stop-head-pitch' into 'main'
Make head moving actually stop this time.

See merge request cable-mc/cobblemon!1596
2025-04-13 04:55:00 +00:00
Landon 4603f5ac7a Merge branch 'riding-animation-01' into 'main'
Riding dynamic animation, riding fixes, and controller tweaks

See merge request cable-mc/cobblemon!1599
2025-04-12 23:59:31 +00:00
Jackson BowesandLandon c683294227 Riding dynamic animation, riding fixes, and controller tweaks 2025-04-12 23:59:31 +00:00
JPAK f29c2343e6 Merge remote-tracking branch 'origin/stop-head-pitch' into stop-head-pitch 2025-04-12 16:41:40 -05:00
JPAK 3a2da5a87d Make head moving actually stop this time. 2025-04-12 16:41:13 -05:00
Landon 1c13ab24e8 Merge branch 'even-more-riding-tweaks' into 'main'
Even more riding tweaks

See merge request cable-mc/cobblemon!1597
2025-04-12 03:07:36 +00:00
Paul 380cf0ea71 You? You're meant to be dead! 2025-04-12 12:29:44 +10:00
Paul 8ded7334bb Refactor forcedTick handling in PosableEntityModel 2025-04-12 12:23:17 +10:00
Polymeta 0ac34bf1a4 Merge branch 'locator-rotation-player-rendering' into 'main'
Lock player model to seat locator's rotation when riding

See merge request cable-mc/cobblemon!1598
2025-04-11 19:41:47 +00:00
Landon Wills 9716ea0806 Fix rotation of player when using custom camera 2025-04-11 06:13:47 -04:00
Landon Wills ffea94f3b2 Rotate player depending on seat locator's rotation 2025-04-11 03:39:49 -04:00
Landon Wills 3061ba69e2 Riding momentum is maintained when window is not active 2025-04-11 03:17:26 -04:00
Landon Wills 741e38d606 Fix issue where same-species pokemon will sync animations on multiplayer environments 2025-04-11 02:01:28 -04:00
Landon Wills 02f2c072c9 Fix issues with pre-animation logic 2025-04-11 01:29:49 -04:00
JPAK 4722defec2 Make head moving actually stop this time. 2025-04-10 13:14:32 -05:00
Polymeta c54849f415 Merge branch 'implement_pokemon' into 'main'
Few mons added for testing

See merge request cable-mc/cobblemon!1595
2025-04-10 13:46:35 +00:00
Frank The FarmerandPolymeta d44e625e9d Few mons added for testing 2025-04-10 13:46:35 +00:00
Polymeta 6a74d5982a Merge branch 'more-riding-tweaks' into 'main'
Riding tweaks / fixes

See merge request cable-mc/cobblemon!1594
2025-04-10 09:13:32 +00:00
Landon Wills 03905c77d2 Add license 2025-04-10 03:12:53 -04:00
Landon Wills da9558f5f9 Fix camera riding momentum not occurring when in chat or screens 2025-04-10 01:40:44 -04:00
Landon Wills 5c65dffac8 Improve rendering of ridden pokemon substantially on low or inconsistent FPS 2025-04-09 23:36:21 -04:00
Landon Wills b67b37c99e Fix some issues with merge 2025-04-09 22:54:23 -04:00
Landon Wills fbb7ee31c5 Merge branch 'refs/heads/main' into water-mount-behaviours 2025-04-09 22:38:45 -04:00
Polymeta d3ef26976b Merge branch 'composite-behaviour-refactor' into 'main'
Composite behaviour refactor

See merge request cable-mc/cobblemon!1584
2025-04-09 15:58:55 +00:00
Landon Wills dac01a3730 Fix issue with crashing on packet decode before player is initialized 2025-04-09 03:30:55 -04:00
Landon Wills ddb05768e4 Remove redundant riding behaviour, rename ride style option from misc to composite 2025-04-09 03:17:31 -04:00
Polymeta 5374940d24 Merge branch 'spicy-molang' into 'main'
Added `spawn_pokemon` and `attempt_wild_battle` as available MoLang functions

Closes #1237

See merge request cable-mc/cobblemon!1586
2025-04-09 07:13:00 +00:00
SpicyandPolymeta 1fd6a660dd Added spawn_pokemon and attempt_wild_battle as available MoLang functions 2025-04-09 07:13:00 +00:00
Landon Wills fd45934775 Fix issue with canRide condition, remove duplicate riding config in aerodactyl 2025-04-09 03:09:04 -04:00
Polymeta 5e0ffd8bd3 Merge branch 'josh/item-molang-fixes' into 'main'
Small fixes for molang functions related to item rendering.

See merge request cable-mc/cobblemon!1590
2025-04-08 16:02:48 +00:00
JoshandPolymeta b4b315360d Small fixes for molang functions related to item rendering. 2025-04-08 16:02:48 +00:00
Polymeta a44c70648b actually return held item to player again
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-04-08 16:07:20 +01:00
Landon Wills 1677598ec0 Merge branch 'refs/heads/main' into water-mount-behaviours
# Conflicts:
#	common/src/main/java/com/cobblemon/mod/common/mixin/client/CameraMixin.java
2025-04-08 01:36:01 -04:00
Landon Wills 57e2765f90 Clean up some method signatures in CameraMixin 2025-04-07 21:57:20 -04:00
Landon Wills 0293c0e811 Update licenses 2025-04-06 04:02:10 -04:00
Landon Wills c7223ae898 Fix some issues with the new composite system, move assets to new system 2025-04-06 01:35:46 -04:00
Landon Wills 38f5c12dce Remove some redundant casting 2025-04-05 23:59:47 -04:00
Landon Wills e6a9a27692 Forgot to remove some code I refactored 2025-04-05 23:59:21 -04:00
Landon Wills 7ff413c401 Add support for custom behaviour settings for different composite strategies 2025-04-05 23:57:30 -04:00
Landon Wills 603f99e5f3 Refactor composite behaviours 2025-04-05 04:24:19 -04:00
Landon Wills 1b53a127af Add lapras assets 2025-04-05 01:39:02 -04:00
172 changed files with 11048 additions and 4930 deletions
+17 -3
View File
@@ -13,7 +13,10 @@
- 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
@@ -66,9 +69,13 @@
### Animation updates for the following Pokémon
- Garchomp
- Tropius
- Torpius
- Nosepass
- Probopass
- Sneasler
- Braixen
- Delphox
### Model updates for the following Pokémon
- Gyarados
@@ -82,13 +89,16 @@
- Leafeon
- Glaceon
- Sylveon
- Treecko
- Grovyle
- Sceptile
- Honchkrow
- Garchomp
- Pidgeot
- Nosepass
- Probopass
- 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.
- Magnezone
- Metagross
### Changes
- Renamed `chargeGainedPerTick` config to `secondsToChargeHealingMachine`.
@@ -155,8 +165,11 @@
- 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
@@ -265,6 +278,7 @@
- Geodude
- Graveler
- Golem
- Magnezone
### Cry updates for the following Pokémon
- Sceptile
@@ -1,30 +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.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);
}
}
}
@@ -0,0 +1,53 @@
/*
* 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,6 +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.entity.PokemonClientDelegate;
import com.cobblemon.mod.common.client.render.MatrixWrapper;
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState;
@@ -60,6 +61,8 @@ public abstract class CameraMixin {
@Shadow
private BlockGetter level;
@Shadow private float partialTickTime;
@Unique private float returnTimer = 0;
@Unique private float rollAngleStart = 0;
@Unique Minecraft minecraft = Minecraft.getInstance();
@@ -67,7 +70,7 @@ public abstract class CameraMixin {
@Unique boolean disableRollableCameraDebug = false;
@Inject(method = "setRotation", at = @At("HEAD"), cancellable = true)
public void open_camera$setRotation(float f, float g, CallbackInfo ci) {
public void cobblemon$setRotation(float f, float g, CallbackInfo ci) {
if (!(this.entity instanceof OrientationControllable controllable) || disableRollableCameraDebug) return;
var controller = controllable.getOrientationController();
if (!controller.isActive() && controller.getOrientation() != null) {
@@ -85,7 +88,7 @@ public abstract class CameraMixin {
return;
}
controller.getOrientation().rotateZ((float) Math.toRadians(-rollAngleStart*(1-returnTimer)));
applyRotation();
cobblemon$applyRotation();
this.returnTimer += .05F;
ci.cancel();
} else {
@@ -95,7 +98,7 @@ public abstract class CameraMixin {
return;
}
if (controller.getOrientation() == null) return;
applyRotation();
cobblemon$applyRotation();
this.returnTimer = 0;
this.rollAngleStart = controller.getRoll();
@@ -104,9 +107,10 @@ 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 positionCamera(Camera instance, double x, double y, double z, Operation<Void> original, @Local(ordinal = 1, argsOnly = true) boolean thirdPersonReverse) {
public void cobblemon$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);
@@ -115,20 +119,20 @@ public abstract class CameraMixin {
return;
}
int seatIndex = pokemon.getPassengers().indexOf(entity);
Seat seat = pokemon.getSeats().get(seatIndex);
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemon.getDelegate();
Vec3 entityPos = new Vec3(
Mth.lerp(instance.getPartialTickTime(), pokemon.xOld, pokemon.getX()),
Mth.lerp(instance.getPartialTickTime(), pokemon.yOld, pokemon.getY()),
Mth.lerp(instance.getPartialTickTime(), pokemon.zOld, pokemon.getZ())
);
MountedPokemonAnimationRenderController.INSTANCE.setup(pokemon, partialTickTime);
int seatIndex = pokemon.getPassengers().indexOf(entity);
Seat seat = pokemon.getSeats().get(seatIndex);
OrientationControllable rollable = (OrientationControllable) entity;
OrientationController controller = rollable.getOrientationController();
if (!instance.isDetached() || Cobblemon.config.getThirdPartyViewBobbing()) {
PokemonClientDelegate delegate = (PokemonClientDelegate) pokemon.getDelegate();
MatrixWrapper locator = delegate.getLocatorStates().get(seat.getLocator());
if (locator == null) {
@@ -139,10 +143,12 @@ public abstract class CameraMixin {
Vec3 locatorOffset = new Vec3(locator.getMatrix().getTranslation(new Vector3f()));
float currEyeHeight = Mth.lerp(instance.getPartialTickTime(), eyeHeightOld, eyeHeight);
Matrix3f orientation = controller.isActive() && controller.getOrientation() != null ? controller.getOrientation() : new Matrix3f();
Vec3 rotatedEyeHeight = new Vec3(orientation.transform(new Vector3f(0f, currEyeHeight - (entity.getBbHeight() / 2), 0f)));
var rotatedEyeHeight = new Vector3f(0f, currEyeHeight - (entity.getBbHeight() / 2), 0f);
if (controller.isActive()) {
rotatedEyeHeight = controller.getRenderOrientation(partialTickTime).transform(rotatedEyeHeight);
}
Vec3 position = locatorOffset.add(entityPos).add(rotatedEyeHeight);
Vec3 position = locatorOffset.add(entityPos).add(new Vec3(rotatedEyeHeight));
setPosition(position);
} else {
Vector3f pos = entityPos.add(new Vec3(0, pokemon.getBbHeight() / 2, 0)).toVector3f();
@@ -179,7 +185,7 @@ public abstract class CameraMixin {
}
@Unique
private void applyRotation(){
private void cobblemon$applyRotation(){
if (!(this.entity instanceof OrientationControllable controllable) || controllable.getOrientationController().getOrientation() == null) return;
var controller = controllable.getOrientationController();
var newRotation = controller.getOrientation().normal(new Matrix3f()).getNormalizedRotation(new Quaternionf());
@@ -59,8 +59,21 @@ public class HumanoidModelMixin {
}
Entity vehicle = entity.getVehicle();
if (vehicle instanceof PokemonEntity && entity instanceof AbstractClientPlayer) {
MountedPlayerRenderer.INSTANCE.animate((PokemonEntity) vehicle, (AbstractClientPlayer) entity, relevantPartsByName, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
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);
}
}
}
@@ -15,6 +15,7 @@ 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;
@@ -29,9 +30,10 @@ 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 class MouseHandlerMixin {
public abstract class MouseHandlerMixin {
@Shadow private double accumulatedScrollY;
@Shadow @Final private Minecraft minecraft;
@@ -49,6 +51,14 @@ public 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(
@@ -161,16 +171,21 @@ public class MouseHandlerMixin {
return false;
}
@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) {
@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) {
if (minecraft.player == null) return;
if (!(minecraft.player instanceof OrientationControllable controllable)) return;
if (!controllable.getOrientationController().isActive()) return;
if (minecraft.isPaused()) return;
if (isMouseGrabbed()) return;
var pitch = pitchSmoother.getNewDeltaValue(0, e);
var roll = rollSmoother.getNewDeltaValue(0, e);
controllable.getOrientationController().rotate(0.0F, (float)pitch, (float)roll);
this.turnPlayer(cobblemon$timeDelta);
}
@Unique
@@ -1,38 +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.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;
}
}
@@ -20,4 +20,4 @@ interface EntitySideDelegate<T : Entity> {
fun tick(entity: T) {}
fun onSyncedDataUpdated(data: EntityDataAccessor<*>) {}
fun addToStruct(struct: QueryStruct) {}
}
}
@@ -22,4 +22,5 @@ interface PokemonSideDelegate : EntitySideDelegate<PokemonEntity> {
fun handleStatus(status: Byte) {}
fun spawnShinyParticle(player: Player) {}
fun positionRider(passenger: Entity, positionUpdater: MoveFunction)
}
fun updateAge(age: Int) {}
}
@@ -17,7 +17,11 @@ 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.*
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.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.battles.model.actor.ActorType
import com.cobblemon.mod.common.api.battles.model.actor.BattleActor
@@ -27,7 +31,13 @@ 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.*
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.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.evolution.Evolution
import com.cobblemon.mod.common.api.pokemon.stats.Stats
@@ -38,6 +48,7 @@ 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
@@ -59,7 +70,35 @@ 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.*
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.mojang.datafixers.util.Either
import net.minecraft.commands.arguments.EntityAnchorArgument
import net.minecraft.core.BlockPos
@@ -68,7 +107,11 @@ 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.*
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.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.MinecraftServer
@@ -77,7 +120,11 @@ 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.*
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.ai.behavior.BlockPosTracker
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.MemoryStatus
@@ -92,7 +139,45 @@ 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.*
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 kotlin.math.sqrt
import kotlin.random.Random
@@ -293,6 +378,27 @@ object MoLangFunctions {
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
}
}
map.put("get_entities_around") { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
@@ -810,9 +916,14 @@ 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).isEmpty) }
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
}
)
@@ -19,4 +19,4 @@ interface Decodable {
*/
fun decode(buffer: RegistryFriendlyByteBuf)
}
}
@@ -25,4 +25,4 @@ interface Encodable {
*/
fun encode(buffer: RegistryFriendlyByteBuf)
}
}
@@ -107,4 +107,22 @@ 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,9 +41,6 @@ class RidingProperties(
}
}
val canRide: Boolean
get() = seats.isNotEmpty() && behaviour != null
fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeMap(
stats,
@@ -53,7 +50,6 @@ 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,5 +18,6 @@ package com.cobblemon.mod.common.api.riding
enum class RidingStyle {
LAND,
LIQUID,
AIR
}
AIR,
COMPOSITE
}
@@ -8,6 +8,7 @@
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
@@ -27,6 +28,7 @@ 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
@@ -85,6 +87,6 @@ interface RidingBehaviour<Settings : RidingBehaviourSettings, State : RidingBeha
fun shouldRotatePlayerHead(settings: Settings, state: State, vehicle: PokemonEntity): Boolean
fun createDefaultState(): State
fun createDefaultState(settings: Settings): State
}
@@ -11,6 +11,7 @@ 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,15 +8,10 @@
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.network.RegistryFriendlyByteBuf
import kotlin.reflect.KProperty
import net.minecraft.world.phys.Vec3
/**
* Represents the state of a Pokemon when being ridden.
@@ -27,18 +22,38 @@ import kotlin.reflect.KProperty
*
* @author landonjw
*/
interface RidingBehaviourState : Encodable, Decodable {
fun reset()
fun copy(): RidingBehaviourState
fun shouldSync(previous: RidingBehaviourState): Boolean
}
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)
}
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<*, *>>()
val behaviours = mutableMapOf<ResourceLocation, RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState>>()
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<*, *>) {
fun register(key: ResourceLocation, behaviour: RidingBehaviour<out RidingBehaviourSettings, out RidingBehaviourState>) {
if (behaviours.contains(key)) error("Behaviour already registered to key $key")
behaviours[key] = RidingController(behaviour)
behaviours[key] = RidingController(behaviour) as RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState>
}
fun get(key: ResourceLocation): RidingBehaviour<*, *> {
fun get(key: ResourceLocation): RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState> {
if (!behaviours.contains(key)) error("Behaviour not registered to key $key")
return behaviours[key]!!
}
@@ -8,6 +8,7 @@
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
@@ -24,6 +25,7 @@ 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)
@@ -39,8 +41,13 @@ 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 vehicle.rotationVector
if (!isActive(settings, state, vehicle)) return driver.rotationVector
return behaviour.rotation(settings, state, vehicle, driver)
}
@@ -164,8 +171,8 @@ class RidingController<Settings : RidingBehaviourSettings, State : RidingBehavio
return behaviour.setRideBar(settings, state, vehicle, driver)
}
override fun createDefaultState(): State {
return behaviour.createDefaultState()
override fun createDefaultState(settings: Settings): State {
return behaviour.createDefaultState(settings)
}
}
@@ -12,12 +12,14 @@ 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
@@ -25,6 +27,9 @@ 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> {
@@ -33,9 +38,10 @@ 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.rideVel.get().z > 0.2 })
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVelocity.get().z > 0.2 })
override fun isActive(settings: BirdAirSettings, state: BirdAirState, vehicle: PokemonEntity): Boolean {
return true
@@ -51,7 +57,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
vehicle: PokemonEntity,
driver: Player
): Float {
return state.rideVel.get().length().toFloat()
return state.rideVelocity.get().length().toFloat()
}
override fun rotation(
@@ -83,11 +89,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.rideVel.get().z
forwardForce += cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().z
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 += cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().y
forwardForce += sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().y
upForce += cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().y
forwardForce += sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().y
}
@@ -104,7 +110,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
upForce = if (vehicle.y >= altitudeLimit && upForce > 0) 0.0 else upForce
}
val velocity = Vec3(state.rideVel.get().x , upForce, forwardForce)
val velocity = Vec3(state.rideVelocity.get().x , upForce, forwardForce)
return velocity
}
@@ -120,12 +126,12 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
var glideSpeedChange = 0.0
val currSpeed = state.rideVel.get().length()
val currSpeed = state.rideVelocity.get().length()
//Flag for determining if player is actively inputting
var activeInput = false
var newVelocity = Vec3(state.rideVel.get().x, state.rideVel.get().y, state.rideVel.get().z)
var newVelocity = Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, state.rideVelocity.get().z)
//speed up and slow down based on input
if (driver.zza != 0.0f && state.stamina.get() > 0.0) {
@@ -176,26 +182,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 -> 1.0
driver.isShiftKeyDown -> -1.0
driver.jumping && state.rideVelocity.get().length() < 0.3 -> 1.0
driver.isShiftKeyDown && state.rideVelocity.get().length() < 0.3 -> -1.0
else -> 0.0
}
@@ -222,25 +228,26 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
}
}
//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)
}
//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)
// }
//air resistance
if( abs(newVelocity.z) > 0) {
newVelocity = newVelocity.subtract(0.0, 0.0, min(0.003 * newVelocity.z.sign, newVelocity.z))
newVelocity = newVelocity.subtract(0.0, 0.0, min(0.0015 * newVelocity.z.sign, newVelocity.z))
}
state.rideVel.set(newVelocity)
state.rideVelocity.set(newVelocity)
}
override fun angRollVel(
@@ -253,10 +260,17 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
if (driver !is OrientationControllable) return Vec3.ZERO
val controller = (driver as OrientationControllable).orientationController
//TODO: Tie into handling
//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
val handling = vehicle.runtime.resolveDouble(settings.handlingExpr)
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val rotationChangeRate = 10.0
//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
var yawForce = rotationChangeRate * sin(Math.toRadians(controller.roll.toDouble()))
//for a bit of correction on the rolls limit it to a quarter the amount
@@ -266,7 +280,28 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
yawForce *= abs(cos(Math.toRadians(controller.pitch.toDouble())))
pitchForce *= abs(cos(Math.toRadians(controller.pitch.toDouble()))) * 1.5
return Vec3(yawForce, pitchForce, 0.0)
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())
}
override fun rotationOnMouseXY(
@@ -300,13 +335,14 @@ 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 * normalizeVal(state.rideVel.get().length(), 0.0, topSpeed).pow(3), rotMin)
val rotLimit = max(handling * sqrt(normalizeVal(state.rideVelocity.get().length(), 0.0, topSpeed)), 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))
}
@@ -315,10 +351,18 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
}
//Give the ability to yaw with x mouse input when at low speeds.
val yawForce = xInput * ( 1.0 - normalizeVal(state.rideVel.get().length(), 0.0, topSpeed).pow(3))
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())
//yaw, pitch, roll
return Vec3(yawForce, yInput, rollForce)
return Vec3(yawForcePitched, yInput, rollForce)
}
/*
@@ -378,7 +422,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.rideVel.get().length(), topSpeed, glideTopSpeed)
val normalizedGlideSpeed = normalizeVal(state.rideVelocity.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
@@ -433,7 +477,7 @@ class BirdAirBehaviour : RidingBehaviour<BirdAirSettings, BirdAirState> {
return false
}
override fun createDefaultState() = BirdAirState()
override fun createDefaultState(settings: BirdAirSettings) = BirdAirState()
}
@@ -457,6 +501,7 @@ class BirdAirSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(infiniteAltitude)
buffer.writeExpression(infiniteStamina)
buffer.writeExpression(glidespeedExpr)
@@ -479,47 +524,44 @@ class BirdAirSettings : RidingBehaviourSettings {
}
}
class BirdAirState : RidingBehaviourState {
var rideVel = ridingState(Vec3.ZERO, Side.CLIENT)
var stamina = ridingState(1.0f, Side.CLIENT)
class BirdAirState : RidingBehaviourState() {
var gliding = ridingState(false, Side.CLIENT)
var lastGlide = ridingState(-100L, Side.CLIENT)
var currRollCorrectionForce = ridingState(0.0, Side.CLIENT)
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeVec3(rideVel.get())
override fun encode(buffer: FriendlyByteBuf) {
super.encode(buffer)
buffer.writeFloat(stamina.get())
buffer.writeBoolean(gliding.get())
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
rideVel.set(buffer.readVec3(), forced = true)
stamina.set(buffer.readFloat(), forced = true)
override fun decode(buffer: FriendlyByteBuf) {
super.decode(buffer)
gliding.set(buffer.readBoolean(), forced = true)
}
override fun reset() {
rideVel.set(Vec3.ZERO, forced = true)
stamina.set(1.0f, forced = true)
super.reset()
gliding.set(false, forced = true)
lastGlide.set(-100L, forced = true)
currRollCorrectionForce.set(0.0, forced = true)
}
override fun toString(): String {
return "BirdAirState(rideVel=${rideVel.get()}, stamina=${stamina.get()}, gliding=${gliding.get()})"
return "BirdAirState(rideVelocity=${rideVelocity.get()}, stamina=${stamina.get()}, gliding=${gliding.get()})"
}
override fun copy() = BirdAirState().also {
it.rideVel.set(this.rideVel.get(), forced = true)
it.rideVelocity.set(this.rideVelocity.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.rideVel != rideVel) return true
if (previous.stamina != stamina) return true
if (previous.gliding != gliding) return true
return false
if (previous.gliding.get() != gliding.get()) return true
return super.shouldSync(previous)
}
}
@@ -11,6 +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.*
import com.cobblemon.mod.common.api.riding.posing.PoseOption
import com.cobblemon.mod.common.api.riding.posing.PoseProvider
@@ -18,7 +19,6 @@ 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,6 +35,7 @@ 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) })
@@ -256,7 +257,7 @@ class DolphinBehaviour : RidingBehaviour<DolphinSettings, DolphinState> {
return false
}
override fun createDefaultState() = DolphinState()
override fun createDefaultState(settings: DolphinSettings) = DolphinState()
}
@@ -282,6 +283,7 @@ class DolphinSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(canJump)
buffer.writeExpression(jumpVector[0])
buffer.writeExpression(jumpVector[1])
@@ -306,13 +308,11 @@ 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
}
@@ -1,434 +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.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,7 +9,8 @@
package com.cobblemon.mod.common.api.riding.behaviour.types
import com.bedrockk.molang.Expression
import com.bedrockk.molang.runtime.value.DoubleValue
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
@@ -17,15 +18,14 @@ 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.max
import kotlin.math.min
import kotlin.math.pow
import kotlin.math.*
class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandState> {
companion object {
@@ -33,10 +33,11 @@ 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 state.rideVel.get().z > 0.1
return@PoseOption abs(state.rideVelocity.get().z) > 0.2
})
override fun isActive(
@@ -72,18 +73,102 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
vehicle: PokemonEntity,
driver: Player
): Float {
return state.rideVel.get().length().toFloat()
return state.rideVelocity.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 {
return Vec2(driver.xRot * 0.5f, driver.yRot)
val turnAmount = calcRotAmount(settings, state, vehicle, driver)
return Vec2(vehicle.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: 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,
@@ -91,24 +176,16 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
driver: Player,
input: Vec3
): Vec3 {
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
//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 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)
}
state.rideVelocity.set(calculateRideSpaceVel(settings, state, vehicle, driver))
//This is cheap.
//Also make it stop quicker the slower it is.
@@ -118,7 +195,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.rideVel.get()
return state.rideVelocity.get()
}
private fun calculateRideSpaceVel(
@@ -127,35 +204,59 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
vehicle: PokemonEntity,
driver: Player
): Vec3 {
val topSpeed = vehicle.runtime.resolveDouble(settings.topSpeedExpr)
val accel = vehicle.runtime.resolveDouble(settings.accelExpr)
val speed = state.rideVel.get().length()
val topSpeed = vehicle.runtime.resolveDouble(settings.speedExpr)
val accel = vehicle.runtime.resolveDouble(settings.accelerationExpr)
val speed = state.rideVelocity.get().length()
val minSpeed = 0.0
//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.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)
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
}
//Decelerate currently always a constant half of max acceleration.
newVelocity =
Vec3(newVelocity.x, newVelocity.y, max(newVelocity.z - ((accel * deccelMod) / 2), minSpeed))
newVelocity = Vec3(
newVelocity.x,
newVelocity.y,
(newVelocity.z + (accel * forwardInput.toDouble())))
activeInput = true
}
//Gravity logic
if (vehicle.onGround()) {
newVelocity = Vec3(newVelocity.x, 0.0, newVelocity.z)
} else {
newVelocity = Vec3(newVelocity.x, max(newVelocity.y - 0.2, -1.0), newVelocity.z)
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)
}
//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
}
@@ -163,7 +264,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 normalizeSpeed(currSpeed: Double, minSpeed: Double, maxSpeed: Double): Double {
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)
}
@@ -215,8 +316,6 @@ 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)
}
@@ -227,10 +326,7 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
driver: Player,
jumpStrength: Int
): Vec3 {
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())
return Vec3.ZERO
}
override fun gravity(
@@ -316,30 +412,21 @@ class GenericLandBehaviour : RidingBehaviour<GenericLandSettings, GenericLandSta
return false
}
override fun createDefaultState() = GenericLandState()
override fun createDefaultState(settings: GenericLandSettings) = GenericLandState()
}
class GenericLandSettings : RidingBehaviourSettings {
override val key = GenericLandBehaviour.KEY
var driveFactor = "1.0".asExpression()
var canJump = "true".asExpression()
private set
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()
var speedExpr: 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 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())
var accelerationExpr: Expression =
"q.get_ride_stats('ACCELERATION', 'LAND', (1.0 / (20.0 * 1.5)), (1.0 / (20.0 * 5.0)))".asExpression()
private set
// Between 30 seconds and 10 seconds at the lowest when at full speed.
@@ -354,30 +441,17 @@ class GenericLandSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
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.writeResourceLocation(key)
buffer.writeExpression(speedExpr)
buffer.writeExpression(accelerationExpr)
buffer.writeExpression(staminaExpr)
buffer.writeExpression(jumpExpr)
buffer.writeExpression(handlingExpr)
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
driveFactor = buffer.readExpression()
strafeFactor = buffer.readExpression()
reverseDriveFactor = buffer.readExpression()
topSpeedExpr = buffer.readExpression()
accelExpr = buffer.readExpression()
jumpVector = listOf(
buffer.readExpression(),
buffer.readExpression(),
buffer.readExpression()
)
speedExpr = buffer.readExpression()
accelerationExpr = buffer.readExpression()
staminaExpr = buffer.readExpression()
jumpExpr = buffer.readExpression()
handlingExpr = buffer.readExpression()
@@ -385,41 +459,16 @@ class GenericLandSettings : RidingBehaviourSettings {
}
class GenericLandState : RidingBehaviourState {
var rideVel = ridingState(Vec3.ZERO, Side.CLIENT)
var stamina = ridingState(1.0f, Side.CLIENT)
class GenericLandState : RidingBehaviourState() {
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.rideVel.set(this.rideVel.get(), forced = true)
it.rideVelocity.set(this.rideVelocity.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
if (rideVel != previous.rideVel) return true
if (stamina != previous.stamina) return true
return false
return super.shouldSync(previous)
}
}
@@ -11,7 +11,8 @@ 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.behaviour.NoState
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.RidingBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.posing.PoseOption
@@ -28,17 +29,18 @@ import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.Shapes
class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, RidingBehaviourState> {
companion object {
val KEY = cobblemonResource("swim/generic")
}
override val key = KEY
override val style = RidingStyle.LIQUID
val poseProvider = PoseProvider<GenericSwimSettings, NoState>(PoseType.FLOAT)
val poseProvider = PoseProvider<GenericSwimSettings, RidingBehaviourState>(PoseType.FLOAT)
.with(PoseOption(PoseType.SWIM) { _, _, entity -> entity.isSwimming && entity.entityData.get(PokemonEntity.MOVING) })
override fun isActive(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun isActive(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return Shapes.create(vehicle.boundingBox).blockPositionsAsListRounded().any {
if (vehicle.isInWater || vehicle.isUnderWater) {
return@any true
@@ -48,17 +50,17 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
}
}
override fun pose(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): PoseType {
override fun pose(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): PoseType {
return poseProvider.select(settings, state, vehicle)
}
override fun speed(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Float {
override fun speed(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Float {
return vehicle.runtime.resolveFloat(settings.speed)
}
override fun rotation(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
@@ -67,7 +69,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun velocity(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
@@ -88,7 +90,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun angRollVel(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
@@ -98,7 +100,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun rotationOnMouseXY(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
@@ -118,7 +120,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun canJump(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
@@ -127,7 +129,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun setRideBar(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
@@ -136,7 +138,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun jumpForce(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
@@ -149,7 +151,7 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun gravity(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
@@ -158,45 +160,45 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun rideFovMultiplier(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun useAngVelSmoothing(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun useRidingAltPose(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun inertia(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Double {
override fun inertia(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Double {
return 0.5
}
override fun shouldRoll(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRoll(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun turnOffOnGround(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun turnOffOnGround(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun dismountOnShift(settings: GenericSwimSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun dismountOnShift(settings: GenericSwimSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePokemonHead(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity
): Boolean {
return false
@@ -204,13 +206,13 @@ class GenericSwimBehaviour : RidingBehaviour<GenericSwimSettings, NoState> {
override fun shouldRotatePlayerHead(
settings: GenericSwimSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun createDefaultState() = NoState
override fun createDefaultState(settings: GenericSwimSettings) = RidingBehaviourState()
}
@@ -236,6 +238,7 @@ 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.NoState
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
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,31 +29,32 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, RidingBehaviourState> {
companion object {
val KEY = cobblemonResource("air/glider")
}
override val key = KEY
override val style = RidingStyle.AIR
val poseProvider = PoseProvider<GliderAirSettings, NoState>(PoseType.HOVER)
val poseProvider = PoseProvider<GliderAirSettings, RidingBehaviourState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, _, entity -> entity.entityData.get(PokemonEntity.MOVING) })
override fun isActive(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun isActive(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return true
}
override fun pose(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): PoseType {
override fun pose(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): PoseType {
return poseProvider.select(settings, state, vehicle)
}
override fun speed(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Float {
override fun speed(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Float {
return vehicle.runtime.resolveFloat(settings.speed)
}
override fun rotation(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
@@ -62,7 +63,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun velocity(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
@@ -77,7 +78,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun angRollVel(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
@@ -87,7 +88,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun rotationOnMouseXY(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
@@ -105,13 +106,13 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
return Vec3(0.0, mouseY * invertPitch, mouseX * invertRoll)
}
override fun canJump(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Boolean {
override fun canJump(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity, driver: Player): Boolean {
return false
}
override fun setRideBar(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
@@ -120,7 +121,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun jumpForce(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
@@ -130,7 +131,7 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun gravity(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
@@ -139,51 +140,51 @@ class GliderAirBehaviour : RidingBehaviour<GliderAirSettings, NoState> {
override fun rideFovMultiplier(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun useAngVelSmoothing(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun useRidingAltPose(
settings: GliderAirSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun inertia(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Double {
override fun inertia(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Double {
return 0.5
}
override fun shouldRoll(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRoll(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun turnOffOnGround(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun turnOffOnGround(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun dismountOnShift(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun dismountOnShift(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePokemonHead(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRotatePokemonHead(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePlayerHead(settings: GliderAirSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRotatePlayerHead(settings: GliderAirSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun createDefaultState() = NoState
override fun createDefaultState(settings: GliderAirSettings) = RidingBehaviourState()
}
class GliderAirSettings : RidingBehaviourSettings {
@@ -199,6 +200,7 @@ class GliderAirSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(glideSpeed)
buffer.writeExpression(speed)
buffer.writeExpression(canStrafe)
@@ -11,7 +11,8 @@ 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.behaviour.NoState
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.RidingBehaviour
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourSettings
import com.cobblemon.mod.common.api.riding.posing.PoseOption
@@ -31,18 +32,19 @@ import kotlin.math.abs
import kotlin.math.pow
import kotlin.math.sin
class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, RidingBehaviourState> {
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, NoState>(PoseType.HOVER)
val poseProvider = PoseProvider<HelicopterSettings, RidingBehaviourState>(PoseType.HOVER)
.with(PoseOption(PoseType.FLY) { _, _, entity -> entity.entityData.get(PokemonEntity.MOVING) })
override fun isActive(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun isActive(settings: HelicopterSettings, state: RidingBehaviourState, 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
@@ -56,11 +58,11 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
}
}
override fun pose(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): PoseType {
override fun pose(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): PoseType {
return poseProvider.select(settings, state, vehicle)
}
override fun speed(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity, driver: Player): Float {
override fun speed(settings: HelicopterSettings, state: RidingBehaviourState, 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
@@ -69,7 +71,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun rotation(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: LivingEntity
): Vec2 {
@@ -78,7 +80,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun velocity(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
input: Vec3
@@ -107,7 +109,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun angRollVel(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
deltaTime: Double
@@ -162,7 +164,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun rotationOnMouseXY(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
mouseY: Double,
@@ -182,7 +184,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun canJump(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
@@ -191,7 +193,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun setRideBar(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
@@ -200,7 +202,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun jumpForce(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player,
jumpStrength: Int
@@ -210,7 +212,7 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun gravity(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
regularGravity: Double
): Double {
@@ -219,55 +221,55 @@ class HelicopterBehaviour : RidingBehaviour<HelicopterSettings, NoState> {
override fun rideFovMultiplier(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Float {
return 1.0f
}
override fun useAngVelSmoothing(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun useAngVelSmoothing(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return true
}
override fun useRidingAltPose(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity,
driver: Player
): Boolean {
return false
}
override fun inertia(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Double {
override fun inertia(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Double {
return 0.1
}
override fun shouldRoll(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRoll(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return true
}
override fun turnOffOnGround(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun turnOffOnGround(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun dismountOnShift(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun dismountOnShift(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun shouldRotatePokemonHead(
settings: HelicopterSettings,
state: NoState,
state: RidingBehaviourState,
vehicle: PokemonEntity
): Boolean {
return false
}
override fun shouldRotatePlayerHead(settings: HelicopterSettings, state: NoState, vehicle: PokemonEntity): Boolean {
override fun shouldRotatePlayerHead(settings: HelicopterSettings, state: RidingBehaviourState, vehicle: PokemonEntity): Boolean {
return false
}
override fun createDefaultState() = NoState
override fun createDefaultState(settings: HelicopterSettings) = RidingBehaviourState()
}
@@ -287,6 +289,7 @@ class HelicopterSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(gravity)
buffer.writeExpression(horizontalAcceleration)
buffer.writeExpression(verticalVelocity)
@@ -0,0 +1,479 @@
/*
* 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,12 +11,14 @@ 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
@@ -24,6 +26,7 @@ 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> {
@@ -32,12 +35,24 @@ 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.rideVel.get().z > 0.1 })
.with(PoseOption(PoseType.FLY) { _, state, _ -> state.rideVelocity.get().z > 0.1 })
override fun isActive(settings: JetAirSettings, state: JetAirState, vehicle: PokemonEntity): Boolean {
return true
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: JetAirSettings, state: JetAirState, vehicle: PokemonEntity): PoseType {
@@ -52,24 +67,26 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
//retrieve minSpeed
val minSpeed = vehicle.runtime.resolveDouble(settings.minSpeed)
//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))
//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)
// }
//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()
return state.rideVelocity.get().length().toFloat()
}
//TODO: Move these functions to a riding util class.
@@ -108,8 +125,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.rideVel.get().z
forwardForce = cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVel.get().z
upForce = -1.0 * sin(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().z
forwardForce = cos(Math.toRadians(controller.pitch.toDouble())) * state.rideVelocity.get().z
}
//If stamina has run out then initiate forced glide down.
@@ -141,7 +158,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.rideVel.get().length()
val speed = state.rideVelocity.get().length()
//Give no altitude limit if at max jump stat.
val pushingHeightLimit = if (vehicle.runtime.resolveBoolean(settings.infiniteStamina)) false
@@ -152,15 +169,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.rideVel.set(Vec3(state.rideVel.get().x, state.rideVel.get().y, min(state.rideVel.get().z + (accel * accelMod), topSpeed)))
state.rideVelocity.set(Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, min(state.rideVelocity.get().z + (accel * accelMod), topSpeed)))
} else if (driver.zza >= 0.0 && (state.stamina.get() == 0.0f || pushingHeightLimit)) {
state.rideVel.set(Vec3(state.rideVel.get().x, state.rideVel.get().y, max(state.rideVel.get().z - ((accel) / 4), minSpeed)))
state.rideVelocity.set(Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, max(state.rideVelocity.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), 0.1)
val deccelMod = max((normalizeSpeed(speed, minSpeed, topSpeed) - 1).pow(2) * 8, 0.1)
//Decelerate currently always a constant half of max acceleration.
state.rideVel.set(Vec3(state.rideVel.get().x, state.rideVel.get().y, max(state.rideVel.get().z - ((accel * deccelMod) / 2), minSpeed)))
state.rideVelocity.set(Vec3(state.rideVelocity.get().x, state.rideVelocity.get().y, max(state.rideVelocity.get().z - ((accel * deccelMod) / 2), minSpeed)))
}
}
@@ -209,8 +226,13 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
val invertRoll = if (Cobblemon.config.invertRoll) -1 else 1
val invertPitch = if (Cobblemon.config.invertPitch) -1 else 1
// Accumulate the mouse input
state.currMouseXForce.set((state.currMouseXForce.get() + (0.0015 * mouseX * invertRoll)).coerceIn(-1.0, 1.0))
// 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))
state.currMouseYForce.set((state.currMouseYForce.get() + (0.0015 * mouseY * invertPitch)).coerceIn(-1.0, 1.0))
//Get handling in degrees per second
@@ -232,8 +254,9 @@ 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)
}
@@ -285,7 +308,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.rideVel.get().length(), minSpeed, topSpeed)
val normalizedSpeed = normalizeSpeed(state.rideVelocity.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.
@@ -333,7 +356,7 @@ class JetAirBehaviour : RidingBehaviour<JetAirSettings, JetAirState> {
return false
}
override fun createDefaultState() = JetAirState()
override fun createDefaultState(settings: JetAirSettings) = JetAirState()
}
class JetAirSettings : RidingBehaviourSettings {
@@ -342,10 +365,10 @@ class JetAirSettings : RidingBehaviourSettings {
var gravity: Expression = "0".asExpression()
private set
var minSpeed: Expression = "1.2".asExpression()
var minSpeed: Expression = "0.8".asExpression()
private set
var handlingYawExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 25.0, 8.0)".asExpression()
var handlingYawExpr: Expression = "q.get_ride_stats('SKILL', 'AIR', 50.0, 25.0)".asExpression()
private set
// Make configurable by json
@@ -359,7 +382,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', 2.5, 1.0)".asExpression()
var speedExpr: Expression = "q.get_ride_stats('SPEED', 'AIR', 1.8, 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
@@ -367,6 +390,7 @@ class JetAirSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(gravity)
buffer.writeExpression(minSpeed)
buffer.writeExpression(handlingYawExpr)
@@ -393,50 +417,40 @@ class JetAirSettings : RidingBehaviourSettings {
}
}
class JetAirState : RidingBehaviourState {
class JetAirState : RidingBehaviourState() {
var currSpeed = 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)
var currMouseXForce = ridingState(0.0, Side.CLIENT)
var currMouseYForce = ridingState(0.0, Side.CLIENT)
override fun encode(buffer: RegistryFriendlyByteBuf) {
override fun encode(buffer: FriendlyByteBuf) {
super.encode(buffer)
buffer.writeDouble(currSpeed.get())
buffer.writeFloat(stamina.get())
buffer.writeVec3(rideVel.get())
}
override fun decode(buffer: RegistryFriendlyByteBuf) {
override fun decode(buffer: FriendlyByteBuf) {
super.decode(buffer)
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.rideVel.set(rideVel.get(), forced = true)
it.currMouseXForce.set(currMouseXForce.get(), forced = true)
it.currMouseYForce.set(currMouseYForce.get(), forced = true)
it.rideVelocity.set(rideVelocity.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
if (previous.stamina != stamina) return true
if (previous.rideVel != rideVel) return true
return false
return super.shouldSync(previous)
}
}
@@ -1,469 +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.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
}
}
@@ -1,450 +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.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,6 +10,7 @@ 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
@@ -33,6 +34,7 @@ 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) })
@@ -217,7 +219,7 @@ class SwimDashBehaviour : RidingBehaviour<SwimDashSettings, SwimDashState> {
return false
}
override fun createDefaultState() = SwimDashState()
override fun createDefaultState(settings: SwimDashSettings) = SwimDashState()
}
class SwimDashSettings : RidingBehaviourSettings {
@@ -227,6 +229,7 @@ class SwimDashSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeFloat(dashSpeed)
}
@@ -235,14 +238,12 @@ 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)
}
@@ -252,9 +253,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,6 +53,7 @@ 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) })
@@ -265,7 +266,7 @@ class VehicleLandBehaviour : RidingBehaviour<VehicleLandSettings, VehicleLandSta
return false
}
override fun createDefaultState() = VehicleLandState()
override fun createDefaultState(settings: VehicleLandSettings) = VehicleLandState()
}
class VehicleLandSettings : RidingBehaviourSettings {
@@ -296,6 +297,7 @@ class VehicleLandSettings : RidingBehaviourSettings {
private set
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeResourceLocation(key)
buffer.writeExpression(canJump)
buffer.writeExpression(jumpVector[0])
buffer.writeExpression(jumpVector[1])
@@ -324,14 +326,12 @@ 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
}
@@ -0,0 +1,426 @@
/*
* 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)
}
}
@@ -0,0 +1,32 @@
/*
* 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>
}
}
@@ -0,0 +1,53 @@
/*
* 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)
}
}
@@ -0,0 +1,99 @@
/*
* 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()
}
}
@@ -0,0 +1,68 @@
/*
* 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)
}
}
@@ -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.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)
}
}
@@ -0,0 +1,143 @@
/*
* 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
}
}
@@ -0,0 +1,68 @@
/*
* 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))
}
}
@@ -0,0 +1,77 @@
/*
* 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()
}
}
@@ -34,7 +34,11 @@ 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.*
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.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.Minecraft
import net.minecraft.network.syncher.EntityDataAccessor
@@ -345,9 +349,12 @@ 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 {
@@ -8,10 +8,8 @@
package com.cobblemon.mod.common.client.render.models.blockbench
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
@@ -36,7 +34,6 @@ 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(
@@ -79,11 +76,25 @@ abstract class PosableEntityModel<T : Entity>(
) {
setupEntityTypeContext(entity)
if (entity is PosableEntity) {
val state = entity.delegate as PosableState
posableModel.applyAnimations(entity, state, limbSwing, limbSwingAmount, ageInTicks, headYaw, headPitch)
val ticks = getTicksForAnimation(entity, limbSwing, limbSwingAmount, ageInTicks, headYaw, headPitch)
posableModel.applyAnimations(entity, entity.delegate as PosableState, limbSwing, limbSwingAmount, ticks, 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)
@@ -92,4 +103,4 @@ abstract class PosableEntityModel<T : Entity>(
}
}
}
}
}
@@ -48,6 +48,7 @@ import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexConsumer
import com.mojang.blaze3d.vertex.VertexFormat
import com.mojang.math.Axis
import net.minecraft.client.Minecraft
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderStateShard
@@ -826,4 +827,6 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
condition = condition,
animations = { animations(it) }
)
fun isReadyForAnimation() = ::context.isInitialized
}
@@ -35,8 +35,10 @@ 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
@@ -130,8 +132,137 @@ abstract class PosableState : Schedulable {
/** 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))
}
/** All of the MoLang functions that can be applied to something with this state. */
val functions = QueryStruct(hashMapOf())
val functions = QueryStruct(hashMapOf(
"riding" to java.util.function.Function { ridingFunctions },
"r" to java.util.function.Function { ridingFunctions }
))
.addFunction("anim_time") {
reusableAnimTime.value = animationSeconds.toDouble()
reusableAnimTime
@@ -157,10 +288,16 @@ abstract class PosableState : Schedulable {
.addFunction("render_item") { params ->
if (params.get<MoValue>(0) !is StringValue) 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 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 renderLocation = if (params.contains(1)) params.getString(1) else "item"
@@ -8,12 +8,16 @@
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?) {
@@ -26,4 +30,28 @@ 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
}
}
@@ -1,72 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.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,6 +38,7 @@ 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") }
@@ -87,6 +88,17 @@ 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
}
}
@@ -1,95 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.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
}
@@ -1,72 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.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
}
@@ -1,66 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.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,6 +38,7 @@ 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") }
@@ -50,8 +51,7 @@ class AmbipomModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, B
standing = registerPose(
poseName = "standing",
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
condition = { !it.isBattling },
poseTypes = PoseType.UI_POSES + PoseType.STAND,
quirks = arrayOf(blink),
animations = arrayOf(
singleBoneLook(),
@@ -80,10 +80,20 @@ 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
}
}
@@ -1,76 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.render.models.blockbench.pokemon.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
}
@@ -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.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,9 +404,6 @@ 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)
@@ -484,7 +481,6 @@ object VaryingModelRepository {
inbuilt("taillow", ::TaillowModel)
inbuilt("swellow", ::SwellowModel)
inbuilt("mudbray", ::MudbrayModel)
inbuilt("mudsdale", ::MudsdaleModel)
inbuilt("comfey", ::ComfeyModel)
inbuilt("tandemaus", ::TandemausModel)
inbuilt("maushold", ::MausholdModel)
@@ -642,7 +638,6 @@ object VaryingModelRepository {
inbuilt("gallade", ::GalladeModel)
inbuilt("beldum", ::BeldumModel)
inbuilt("metang", ::MetangModel)
inbuilt("metagross", ::MetagrossModel)
inbuilt("ursaluna", ::UrsalunaModel)
inbuilt("lechonk", ::LechonkModel)
inbuilt("oinkologne_male", ::OinkologneMaleModel)
@@ -702,7 +697,6 @@ 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)
@@ -11,6 +11,7 @@ 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.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.models.blockbench.bedrock.animation.BedrockAnimationRepository
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
@@ -20,6 +21,7 @@ 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
@@ -40,12 +42,7 @@ object MountedPlayerRenderer {
//Positions player
if (locator != null) {
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)
MountedPokemonAnimationRenderController.setup(entity, partialTicks)
//Undo seat position
val playerPos = Vec3(
@@ -61,20 +58,16 @@ object MountedPlayerRenderer {
)
matrix.translate(playerPos.subtract(entityPos).toVector3f().negate())
}
matrix.translate(locator.matrix.getTranslation(Vector3f()))
//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)
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))
}
matrix.translate(0f, 0.25f, 0f)
}
fun animate(
@@ -280,6 +280,9 @@ 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,8 +9,9 @@
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.
@@ -27,6 +28,7 @@ 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,6 +49,7 @@ 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
@@ -251,6 +252,7 @@ open class PokemonEntity(
var enablePoseTypeRecalculation = true
val ridingAnimationData: RidingAnimationData = RidingAnimationData()
var previousRidingState: RidingBehaviourState? = null
var ridingState: RidingBehaviourState? = null
@@ -283,9 +285,9 @@ open class PokemonEntity(
ridingBehaviourSettings = null
if (pokemon.riding.behaviour == null) return
riding = RidingBehaviours.get(pokemon.riding.behaviour!!.key) as RidingBehaviour<RidingBehaviourSettings, RidingBehaviourState>?
ridingState = riding!!.createDefaultState()
riding = RidingBehaviours.get(pokemon.riding.behaviour!!.key)
ridingBehaviourSettings = pokemon.riding.behaviour!!
ridingState = riding!!.createDefaultState(ridingBehaviourSettings!!)
}
/**
@@ -354,10 +356,11 @@ open class PokemonEntity(
}
var flyDistO = 0F
var isPokemonWalking = false
var isPokemonFlying = false
var tickSpawned = 0
init {
delegate.initialize(this)
delegate.changePokemon(pokemon)
@@ -482,6 +485,11 @@ open class PokemonEntity(
entityData.get(MOVING)
super.tick()
if (passengers.isNotEmpty()) {
ridingAnimationData.update(this)
}
flyDistO = flyDist
if (isBattling) {
@@ -1011,12 +1019,15 @@ 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,
this.canRide(player) && pokemon.riding.canRide
canRide
).sendToPlayer(player)
} else {
// TODO #105
@@ -1236,6 +1247,7 @@ 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(),
@@ -1560,6 +1572,8 @@ 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 ->
@@ -1919,7 +1933,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)
}
@@ -1937,6 +1951,22 @@ 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()) {
@@ -2100,4 +2130,4 @@ open class PokemonEntity(
override fun resolveEntityScan(): LivingEntity {
return this
}
}
}
@@ -8,10 +8,15 @@
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
@@ -21,11 +26,14 @@ 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
@@ -34,16 +42,20 @@ 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.*
import java.util.Optional
/** 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
@@ -102,6 +114,32 @@ 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() {
@@ -234,6 +272,15 @@ 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
@@ -243,6 +290,7 @@ class PokemonServerDelegate : PokemonSideDelegate {
isMoving && isFlying -> PoseType.FLY
isFlying -> PoseType.HOVER
isMoving -> PoseType.WALK
isDancing -> PoseType.DANCE
else -> PoseType.STAND
}
@@ -10,10 +10,8 @@ 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 com.cobblemon.mod.common.util.server
import net.minecraft.client.Minecraft
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceLocation
@@ -21,7 +19,7 @@ class ClientboundUpdateRidingStatePacket(
val entity: Int,
val behaviour: ResourceLocation,
val state: RidingBehaviourState? = null,
val data: RegistryFriendlyByteBuf? = null
val data: FriendlyByteBuf? = null
) : NetworkPacket<ClientboundUpdateRidingStatePacket> {
override val id = ID
@@ -37,7 +35,7 @@ class ClientboundUpdateRidingStatePacket(
fun decode(buffer: RegistryFriendlyByteBuf): ClientboundUpdateRidingStatePacket {
val entity = buffer.readInt()
val behaviour = buffer.readResourceLocation()
val state = RegistryFriendlyByteBuf(buffer.readBytes(buffer.readableBytes()), Minecraft.getInstance().player!!.registryAccess())
val state = FriendlyByteBuf(buffer.readBytes(buffer.readableBytes()))
return ClientboundUpdateRidingStatePacket(
entity = entity,
behaviour = behaviour,
@@ -48,6 +48,7 @@ class SpawnPokemonPacket(
var friendship: Int,
var freezeFrame: Float,
var passengers: IntArray,
var tickSpawned: Int,
vanillaSpawnPacket: ClientboundAddEntityPacket,
) : SpawnExtraDataEntityPacket<SpawnPokemonPacket, PokemonEntity>(vanillaSpawnPacket) {
@@ -76,6 +77,7 @@ class SpawnPokemonPacket(
entity.entityData.get(PokemonEntity.FRIENDSHIP),
entity.entityData.get(PokemonEntity.FREEZE_FRAME),
entity.passengers.map { it.id }.toIntArray(),
entity.tickCount,
vanillaSpawnPacket
)
@@ -102,6 +104,7 @@ 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) {
@@ -136,6 +139,8 @@ 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
@@ -165,9 +170,10 @@ 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, 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, tickSpawned, vanillaPacket)
}
}
@@ -10,6 +10,12 @@ 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
@@ -23,26 +29,42 @@ 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
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,
)
override fun deserialize(element: JsonElement, type: Type, context: JsonDeserializationContext): RidingBehaviourSettings {
val root = element.asJsonObject
val key = root.get("key").asString
val behaviourType = types[key.asIdentifierDefaultingNamespace()] ?: throw IllegalArgumentException("Unknown controller: $key")
val settings: RidingBehaviourSettings = context.deserialize(element, behaviourType)
return settings
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
}
}
}
@@ -0,0 +1,28 @@
{
"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,23 +2272,59 @@
"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]
}
}
}
}
@@ -2553,15 +2589,27 @@
"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": {
@@ -8763,19 +8811,43 @@
"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]
}
}
}
}
@@ -11221,23 +11293,59 @@
"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": {
@@ -13529,19 +13637,43 @@
"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": {
@@ -13740,14 +13872,20 @@
"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": {
@@ -14543,7 +14681,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": {
@@ -16036,7 +16174,7 @@
"animation_length": 4,
"bones": {
"body": {
"rotation": [22.5, 0, "math.sin(q.anim_time*90*1-90)*-0.5"],
"rotation": ["22.5 + q.riding.pitch(0)*-90", 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": {
@@ -17357,6 +17495,14 @@
"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": {
@@ -18633,6 +18779,17 @@
},
"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"
}
}
},
@@ -18898,6 +19055,9 @@
},
"locator_top": {
"position": [0, -6, 0]
},
"locator_seat_1": {
"rotation": [-60, 0, 0]
}
}
},
@@ -19097,23 +19257,59 @@
"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]
}
}
}
}
@@ -22458,7 +22654,10 @@
},
"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],
@@ -26129,23 +26328,59 @@
"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": {
@@ -29385,9 +29620,15 @@
"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": {
@@ -29722,19 +29963,43 @@
"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": {
@@ -29753,6 +30018,106 @@
}
}
},
"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": {
@@ -32994,19 +33359,43 @@
"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": {
@@ -34432,14 +34821,20 @@
"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,6 +535,11 @@
}
}
}
},
"sound_effects": {
"0.5": {
"effect": "animation.plumage.wing_flap.medium"
}
}
},
"animation.pidgeot.air_fly": {
@@ -710,6 +715,9 @@
},
"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]
}
}
},
@@ -1566,6 +1574,11 @@
}
}
}
},
"sound_effects": {
"1.375": {
"effect": "animation.plumage.wing_flap.medium"
}
}
},
"animation.pidgeot.air_fly_quirk2": {
@@ -2721,6 +2734,14 @@
}
}
}
},
"sound_effects": {
"1.4583": {
"effect": "animation.plumage.wing_flap.medium"
},
"3.0833": {
"effect": "animation.plumage.wing_flap.medium"
}
}
},
"animation.pidgeot.blink": {
@@ -182,6 +182,14 @@
"rotation": [0, 0, 0]
}
}
},
"animation.eevee.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.eevee.cry"
}
}
}
}
}
@@ -225,6 +225,14 @@
"rotation": [-59.83045, -1.29256, -14.94548]
}
}
},
"animation.vaporeon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.vaporeon.cry"
}
}
}
}
}
@@ -150,6 +150,14 @@
"rotation": [37.5, 37.5, 0]
}
}
},
"animation.jolteon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.jolteon.cry"
}
}
}
}
}
@@ -266,6 +266,14 @@
"rotation": [37.5, 27.5, 0]
}
}
},
"animation.flareon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.flareon.cry"
}
}
}
}
}
@@ -467,6 +467,7 @@
},
"animation.aerodactyl.air_idle": {
"loop": true,
"animation_length": 1.33333,
"bones": {
"aerodactyl": {
"position": [0, 3, 0]
@@ -642,10 +643,16 @@
"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]
@@ -827,6 +834,11 @@
"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,6 +1237,20 @@
"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": {
@@ -2053,6 +2067,89 @@
"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,6 +188,14 @@
"rotation": [12.5, 0, 0]
}
}
},
"animation.espeon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.espeon.cry"
}
}
}
}
}
@@ -233,6 +233,14 @@
"rotation": [-20, 0, 0]
}
}
},
"animation.umbreon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.umbreon.cry"
}
}
}
}
}
@@ -2,257 +2,102 @@
"format_version": "1.8.0",
"animations": {
"animation.treecko.test": {
"animation_length": 1.2,
"loop": true,
"bones": {
"head": {
"rotation": [-2.5, 0, 0]
"rotation": [-10, 0, 0],
"position": [0, 0.1, -0.3]
},
"jaw": {
"rotation": [42.5, 0, 0]
"rotation": [32.5, 0, 0]
},
"tail": {
"rotation": [-45, 0, 0],
"position": [0, -0.5, 0]
},
"left_tail": {
"tail_left": {
"rotation": [10, 0, 2.5]
},
"left_tail2": {
"tail_left2": {
"rotation": [17.5, 0, 0]
},
"right_tail": {
"tail_right": {
"rotation": [10, 0, -2.5]
},
"right_tail2": {
"tail_right2": {
"rotation": [15, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [0, 0, -5]
},
"left_hand": {
"hand_left": {
"rotation": [0, 0, -57.5]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 20]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 45]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 20]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 45]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, 20]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 45]
},
"right_upper_arm": {
"arm_right": {
"rotation": [0, 0, 5]
},
"torso": {
"rotation": [7.5, 0, 0]
},
"upper_torso": {
"torso2": {
"rotation": [-5, 0, 0]
},
"neck": {
"rotation": [-5, 0, 0]
},
"right_hand": {
"hand_right": {
"rotation": [0, 0, 57.5]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -20]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -45]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -20]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -45]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, -20]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -45]
},
"left_upper_leg": {
"leg_left": {
"rotation": [1.18155, -9.91358, -2.38565]
},
"left_foot": {
"foot_left": {
"rotation": [-0.4165, -7.26605, 3.29302]
},
"right_upper_leg": {
"leg_right": {
"rotation": [1.18155, 9.91358, 2.38565]
},
"right_foot": {
"foot_right": {
"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": {
@@ -262,19 +107,19 @@
"tail": {
"rotation": [-45, 0, 0]
},
"left_tail": {
"tail_left": {
"rotation": [10, 0, 0]
},
"left_tail2": {
"tail_left2": {
"rotation": [15, 0, 0]
},
"right_tail": {
"tail_right": {
"rotation": [10, 0, 0]
},
"right_tail2": {
"tail_right2": {
"rotation": [15, 0, 0]
},
"upper_torso": {
"torso2": {
"rotation": [-5, 0, 0]
},
"neck": {
@@ -283,95 +128,106 @@
"head": {
"rotation": [2.5, 0, 0]
},
"right_pupil": {
"pupil_right": {
"position": [0, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [10.08453, -7.38542, 48.69038]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 42.5, 0]
},
"left_hand": {
"hand_left": {
"rotation": [0, 0, 22.5],
"position": [-0.15, 0.05, 0]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [6.94363, 7.64256, 14.02881]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 22.5]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [-4.01743, -1.75217, 14.46202]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 30]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, 12.5]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 20]
},
"right_upper_arm": {
"arm_right": {
"rotation": [10.08453, 7.38542, -48.69038]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -42.5, 0]
},
"right_hand": {
"hand_right": {
"rotation": [0, 0, -22.5],
"position": [0.15, 0.05, 0]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [6.94363, -7.64256, -14.02881]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -22.5]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [-4.01743, 1.75217, -14.46202]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -30]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, -12.5]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -20]
},
"right_upper_leg": {
"leg_right": {
"rotation": [1.18155, 9.91358, 2.38565]
},
"right_foot": {
"foot_right": {
"rotation": [-0.4165, 7.26605, -3.29302]
},
"left_upper_leg": {
"leg_left": {
"rotation": [1.18155, -9.91358, -2.38565]
},
"left_foot": {
"foot_left": {
"rotation": [-0.4165, -7.26605, 3.29302]
},
"stick": {
"rotation": [30, 45, 0],
"scale": 0.7
}
}
},
"animation.treecko.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"left_eyelid": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": {"pre": [0.1, 0, 0], "post": [0.1, 0, 0]},
"0.125": [0.1, 0, 0],
"0.1667": {"pre": [0.1, 0, 0], "post": [0, 0, 0]}
}
},
"right_eyelid": {
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": {"pre": [-0.1, 0, 0], "post": [-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]}
}
}
}
},
@@ -422,25 +278,25 @@
"tail": {
"rotation": ["-42.5+math.sin(q.anim_time*90*8+0)*3", "math.sin(q.anim_time*90*4+60)*10", 0]
},
"left_tail": {
"tail_left": {
"rotation": ["10+math.sin(q.anim_time*90*8-25)*2", "0+math.sin(q.anim_time*90*4+30)*8", 0]
},
"left_tail2": {
"tail_left2": {
"rotation": ["15+math.sin(q.anim_time*90*8-55)*2", "0+math.sin(q.anim_time*90*4+0)*6", 0]
},
"left_tail3": {
"tail_left3": {
"rotation": ["0+math.sin(q.anim_time*90*8-85)*2", "0+math.sin(q.anim_time*90*4-30)*4", 0]
},
"right_tail": {
"tail_right": {
"rotation": ["10+math.sin(q.anim_time*90*8-35)*2", "0+math.sin(q.anim_time*90*4+30)*8", 0]
},
"right_tail2": {
"tail_right2": {
"rotation": ["15+math.sin(q.anim_time*90*8-65)*2", "0+math.sin(q.anim_time*90*4+0)*6", 0]
},
"right_tail3": {
"tail_right3": {
"rotation": ["0+math.sin(q.anim_time*90*8-95)*2", "0+math.sin(q.anim_time*90*4-30)*4", 0]
},
"upper_torso": {
"torso2": {
"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": {
@@ -449,66 +305,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"]
},
"right_pupil": {
"pupil_right": {
"position": [0, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"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"]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, "42.5+math.sin(q.anim_time*90*4-120)*20", 0]
},
"left_hand": {
"hand_left": {
"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]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [6.94363, 7.64256, 14.02881]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 22.5]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [-4.01743, -1.75217, 14.46202]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 30]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, 12.5]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 20]
},
"right_upper_arm": {
"arm_right": {
"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"]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, "-42.5+math.sin(q.anim_time*90*4-120)*20", 0]
},
"right_hand": {
"hand_right": {
"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]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [6.94363, -7.64256, -14.02881]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -22.5]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [-4.01743, 1.75217, -14.46202]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -30]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, -12.5]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -20]
},
"right_upper_leg": {
"leg_right": {
"rotation": {
"0.0": {
"post": [36.50677, 8.43184, 4.42536],
@@ -558,7 +414,7 @@
}
}
},
"right_lower_leg": {
"leg_right2": {
"rotation": {
"0.0": {
"post": [15, 0, 0],
@@ -586,7 +442,7 @@
}
}
},
"right_foot": {
"foot_right": {
"rotation": {
"0.0": {
"post": [24.37394, 0.4385, -6.40588],
@@ -614,7 +470,7 @@
}
}
},
"right_foot2": {
"foot_right2": {
"rotation": {
"0.0": {
"post": [-30, 0, 0],
@@ -652,7 +508,7 @@
}
}
},
"right_toes": {
"toes_right": {
"rotation": {
"0.0": {
"post": [-42.5, 0, 0],
@@ -690,7 +546,7 @@
}
}
},
"left_upper_leg": {
"leg_left": {
"rotation": {
"0.0": {
"post": [-61.31845, -9.91358, -2.38565],
@@ -740,7 +596,7 @@
}
}
},
"left_lower_leg": {
"leg_left2": {
"rotation": {
"0.0": {
"post": [47.5, 0, 0],
@@ -768,7 +624,7 @@
}
}
},
"left_foot": {
"foot_left": {
"rotation": {
"0.0": {
"post": [-30.4165, -7.26605, 3.29302],
@@ -796,7 +652,7 @@
}
}
},
"left_foot2": {
"foot_left2": {
"rotation": {
"0.0": {
"post": [12.5, 0, 0],
@@ -834,7 +690,7 @@
}
}
},
"left_toes": {
"toes_right2": {
"rotation": {
"0.0": {
"post": [15, 0, 0],
@@ -882,6 +738,265 @@
}
}
},
"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]
},
"upper_torso": {
"torso2": {
"rotation": [5, 0, 0]
},
"neck": {
@@ -17,100 +17,122 @@
"rotation": [2.5, 0, 0]
},
"leaf7": {
"rotation": [12.5, 0, 0]
"rotation": [-5, 0, 0]
},
"jaw": {
"rotation": [0, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [2.5, 7.5, 40]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 52.5, 0]
},
"left_hand": {
"hand_left": {
"rotation": [2.5, 0, 32.5]
},
"left_arm_leaves": {
"arm_leaves_left": {
"rotation": [-25.08377, -4.53051, 2.11751]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 10]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 27.5]
},
"left_tail": {
"tail_left": {
"rotation": [-10, 12.5, -2.5]
},
"left_tail2": {
"tail_left2": {
"rotation": [-15, 0, 0]
},
"left_upper_leg": {
"leg_left": {
"rotation": [0, -22.5, 0]
},
"left_lower_leg": {
"leg_left2": {
"rotation": [0, 0, 0]
},
"left_foot": {
"foot_left": {
"rotation": [0, 0, 0]
},
"left_inner_toe": {
"toe_inner_left": {
"rotation": [0, 10, 0]
},
"left_outer_toe": {
"toe_outer_left": {
"rotation": [0, -10, 0]
},
"right_tail": {
"tail_right": {
"rotation": [-10, -12.5, 2.5]
},
"right_upper_leg": {
"leg_right": {
"rotation": [0, 22.5, 0]
},
"right_lower_leg": {
"leg_right2": {
"rotation": [0, 0, 0]
},
"right_foot": {
"foot_right": {
"rotation": [0, 0, 0]
},
"right_inner_toe": {
"toe_inner_right": {
"rotation": [0, -10, 0]
},
"right_outer_toe": {
"toe_outer_right": {
"rotation": [0, 10, 0]
},
"right_upper_arm": {
"arm_right": {
"rotation": [2.5, -7.5, -40]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -52.5, 0]
},
"right_hand": {
"hand_right": {
"rotation": [2.5, 0, -32.5]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -10]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -27.5]
},
"right_arm_leaves": {
"arm_leaves_right": {
"rotation": [-25.08377, 4.53051, -2.11751]
},
"right_tail2": {
"tail_right2": {
"rotation": [-15, 0, 0]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 17.5]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 22.5]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -17.5]
},
"right_pinky_finger2": {
"finger_back_right2": {
"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
}
}
},
@@ -120,7 +142,7 @@
"torso": {
"rotation": [-5, 0, 0]
},
"upper_torso": {
"torso2": {
"rotation": [2.5, 0, 0]
},
"neck": {
@@ -135,94 +157,94 @@
"jaw": {
"rotation": [0, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [-52.5, 5, 27.5]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 65, 0]
},
"left_hand": {
"hand_left": {
"rotation": [2.38443, -0.75155, 49.98436]
},
"left_arm_leaves": {
"arm_leaves_left": {
"rotation": [-10, -17.5, 0]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 2.5]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 5]
},
"left_tail": {
"tail_left": {
"rotation": [-15, 12.5, -2.5]
},
"left_tail2": {
"tail_left2": {
"rotation": [7.5, 0, 0]
},
"left_upper_leg": {
"leg_left": {
"rotation": [0, -22.5, 0]
},
"left_lower_leg": {
"leg_left2": {
"rotation": [0, 0, 0]
},
"left_foot": {
"foot_left": {
"rotation": [0, 0, 0]
},
"left_inner_toe": {
"toe_inner_left": {
"rotation": [0, 10, 0]
},
"left_outer_toe": {
"toe_outer_left": {
"rotation": [0, -10, 0]
},
"right_tail": {
"tail_right": {
"rotation": [-15, -12.5, 2.5]
},
"right_upper_leg": {
"leg_right": {
"rotation": [0, 22.5, 0]
},
"right_lower_leg": {
"leg_right2": {
"rotation": [0, 0, 0]
},
"right_foot": {
"foot_right": {
"rotation": [0, 0, 0]
},
"right_inner_toe": {
"toe_inner_right": {
"rotation": [0, -10, 0]
},
"right_outer_toe": {
"toe_outer_right": {
"rotation": [0, 10, 0]
},
"right_upper_arm": {
"arm_right": {
"rotation": [-52.5, -5, -27.5]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -65, 0]
},
"right_hand": {
"hand_right": {
"rotation": [2.38443, 0.75155, -49.98436]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -2.5]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -5]
},
"right_arm_leaves": {
"arm_leaves_right": {
"rotation": [-10, 17.5, 0]
},
"right_tail2": {
"tail_right2": {
"rotation": [7.5, 0, 0]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 65]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 87.5]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -65]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -87.5]
}
}
@@ -233,7 +255,7 @@
"torso": {
"rotation": [45.38165, -3.51814, -7.08167]
},
"upper_torso": {
"torso2": {
"rotation": [-9.97857, 3.32943, 4.4913]
},
"neck": {
@@ -248,86 +270,86 @@
"jaw": {
"rotation": [42.5, 0, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [-12.58328, 9.94037, 39.45082]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 82.5, 0]
},
"left_hand": {
"hand_left": {
"rotation": [7.5, 0, 32.5]
},
"left_arm_leaves": {
"arm_leaves_left": {
"rotation": [-21.78282, -11.4487, 11.10461]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 10]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 22.5]
},
"left_tail": {
"tail_left": {
"rotation": [-17.99085, 11.53327, -4.85721]
},
"left_tail2": {
"tail_left2": {
"rotation": [-15, 0, 0]
},
"left_upper_leg": {
"leg_left": {
"rotation": [-37.5, -22.5, 0],
"position": [0.5, 0.5, -1]
},
"left_lower_leg": {
"leg_left2": {
"rotation": [5, 0, 0]
},
"left_foot": {
"foot_left": {
"rotation": [0, 0, 0]
},
"left_inner_toe": {
"toe_inner_left": {
"rotation": [10, 10, 0]
},
"left_outer_toe": {
"toe_outer_left": {
"rotation": [20, -10, 0]
},
"right_tail": {
"tail_right": {
"rotation": [-28.32455, -16.15901, -4.25872]
},
"right_upper_leg": {
"leg_right": {
"rotation": [38, 7.5, 2.5],
"position": [0, -0.5, -0.5]
},
"right_lower_leg": {
"leg_right2": {
"rotation": [5, 0, 0]
},
"right_foot": {
"foot_right": {
"rotation": [27.5, 0, 0]
},
"right_inner_toe": {
"toe_inner_right": {
"rotation": [-24.71447, -5.46269, -2.12052],
"position": [0, -0.1, 0.6]
},
"right_outer_toe": {
"toe_outer_right": {
"rotation": [-24.71447, 5.46269, 2.12052],
"position": [0, -0.1, 0.6]
},
"right_upper_arm": {
"arm_right": {
"rotation": [-14.26018, -29.40676, -34.54418]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -70, 0]
},
"right_hand": {
"hand_right": {
"rotation": [7.5, 0, -32.5]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -10]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -22.5]
},
"right_arm_leaves": {
"arm_leaves_right": {
"rotation": [-26.39218, 18.05776, -8.74472]
},
"right_tail2": {
"tail_right2": {
"rotation": [-15, 0, 0]
},
"body": {
@@ -345,76 +367,191 @@
"leaf6": {
"rotation": [5, 0, 0]
},
"left_back_toe": {
"toe_back_left": {
"rotation": [-5, 0, 0]
},
"right_back_toe": {
"toe_back_right": {
"rotation": [-10, 0, 0]
},
"left_outer_toe2": {
"toe_outer_left2": {
"rotation": [10, 0, 0]
},
"left_inner_toe2": {
"toe_inner_left2": {
"rotation": [10, 0, 0]
},
"right_inner_toe2": {
"toe_inner_right2": {
"rotation": [-45, 0, 0],
"position": [0, -0.55, 1.4]
},
"right_outer_toe2": {
"toe_outer_right2": {
"rotation": [-45, 0, 0],
"position": [0, -0.55, 1.4]
},
"left_leaf1": {
"arm_leaf_middle_left": {
"rotation": [15, 0, 0]
},
"left_leaf2": {
"arm_leaf_inner_left": {
"rotation": [5.76917, -1.99557, 14.05033]
},
"left_leaf3": {
"arm_leaf_outer_left": {
"rotation": [10, 0, 0]
},
"right_leaf1": {
"arm_leaf_middle_right": {
"rotation": [5, 0, 0]
},
"right_leaf2": {
"arm_leaf_inner_right": {
"rotation": [2.5, 0, 0]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 22.5]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 30]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -22.5]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -30]
}
}
},
"animation.grovyle.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": [-0.1, 0, 0],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [-0.1, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": [0.1, 0, 0],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [0.1, 0, 0], "post": [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.33333,
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.grovyle.cry"
@@ -7,7 +7,7 @@
"torso": {
"rotation": [17.5, 0, 0]
},
"upper_torso": {
"torso2": {
"rotation": [-7.5, 0, 0]
},
"neck": {
@@ -16,37 +16,34 @@
"head": {
"rotation": [5, 0, 0]
},
"jaw": {
"rotation": [0, 0, 0]
},
"right_upper_arm": {
"arm_right": {
"rotation": [0, 5, 0]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -50, 0]
},
"right_hand": {
"hand_right": {
"rotation": [0, 0, -27.5]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -20]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, -15]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -25]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -47.5]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -50]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -40]
},
"right_upper_leg": {
"leg_right": {
"rotation": [0, 15, 0]
},
"tail": {
@@ -64,77 +61,81 @@
"tail5": {
"rotation": [7.5, 0, 0]
},
"right_shoulder": {
"shoulder_right": {
"rotation": [0, 0, -45]
},
"left_upper_leg": {
"leg_left": {
"rotation": [0, -15, 0]
},
"left_shoulder": {
"shoulder_left": {
"rotation": [0, 0, 45]
},
"left_upper_arm": {
"arm_left": {
"rotation": [0, -5, 0]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 50, 0]
},
"left_hand": {
"hand_left": {
"rotation": [0, 0, 27.5]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 20]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 50]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, 15]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 40]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 25]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 47.5]
},
"right_arm_leaf_front_blade": {
"arm_leaf_front_blade_right": {
"scale": [1, 0, 1]
},
"right_arm_leaf_back_blade": {
"arm_leaf_back_blade_right": {
"scale": [1, 0, 1]
},
"left_arm_leaf_front_blade": {
"arm_leaf_front_blade_left": {
"scale": [1, 0, 1]
},
"left_arm_leaf_back_blade": {
"arm_leaf_back_blade_left": {
"scale": [1, 0, 1]
},
"left_top_leaves": {
"tail_leaves_top_left": {
"rotation": [2.5, 0, 0]
},
"left_bottom_leaves": {
"tail_leaves_bottom_left": {
"rotation": [0, -2.5, 0]
},
"left_top_leaves3": {
"tail_leaves_top_left3": {
"rotation": [-5, 0, 0]
},
"left_bottom_leaves3": {
"tail_leaves_bottom_left3": {
"rotation": [0, 5, 0]
},
"right_top_leaves": {
"tail_leaves_top_right": {
"rotation": [2.5, 0, 0]
},
"right_bottom_leaves": {
"tail_leaves_bottom_right": {
"rotation": [0, 2.5, 0]
},
"right_top_leaves3": {
"tail_leaves_top_right3": {
"rotation": [-5, 0, 0]
},
"right_bottom_leaves3": {
"tail_leaves_bottom_right3": {
"rotation": [0, -5, 0]
},
"stick": {
"rotation": [16, 40, 0],
"scale": 0.7
}
}
},
@@ -144,7 +145,7 @@
"torso": {
"rotation": [32.40109, 2.68407, -4.22005]
},
"upper_torso": {
"torso2": {
"rotation": [4.98107, -0.43523, 4.98107]
},
"neck": {
@@ -156,34 +157,34 @@
"jaw": {
"rotation": [45, 0, 0]
},
"right_upper_arm": {
"arm_right": {
"rotation": [-7.5, 2.5, 0]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -72.5, 0]
},
"right_hand": {
"hand_right": {
"rotation": [0, 0, -50]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -20]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, -15]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -25]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -47.5]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -50]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -40]
},
"right_upper_leg": {
"leg_right": {
"rotation": [22.5, 15, 0],
"position": [0, 0.5, 0.5]
},
@@ -202,92 +203,92 @@
"tail5": {
"rotation": [12.79362, 12.19908, 2.74715]
},
"right_shoulder": {
"shoulder_right": {
"rotation": [-10.01754, 2.34914, -25.85553]
},
"left_upper_leg": {
"leg_left": {
"rotation": [-17.5, -15, 0],
"position": [0, 0, -0.5]
},
"left_shoulder": {
"shoulder_left": {
"rotation": [-11.9857, 23.12519, 20.20473]
},
"left_upper_arm": {
"arm_left": {
"rotation": [-5, 10, 0]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 47.5, 0]
},
"left_hand": {
"hand_left": {
"rotation": [0, 0, 22.5]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 20]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 50]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, 15]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 40]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 25]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 47.5]
},
"right_lower_leg": {
"leg_right2": {
"rotation": [10, 0, 0]
},
"right_ankle": {
"leg_right3": {
"rotation": [0, 0, 0]
},
"right_foot": {
"foot_right": {
"rotation": [10, 0, 0]
},
"right_middle_toe": {
"toe_middle_right": {
"rotation": [-42.5, 0, 0],
"position": [0, -0.5, 0.6]
},
"right_inner_toe": {
"toe_inner_right": {
"rotation": [-43.11609, 4.07933, 4.44372],
"position": [0, -0.5, 0.6]
},
"right_outer_toe": {
"toe_outer_right": {
"rotation": [-43.11609, -4.07933, -4.44372],
"position": [0, -0.5, 0.6]
},
"left_lower_leg": {
"leg_left2": {
"rotation": [-5, 0, 0]
},
"left_ankle": {
"leg_left3": {
"rotation": [0, 0, 0]
},
"left_foot": {
"foot_left": {
"rotation": [22.5, 0, 0]
},
"right_arm_leaf_front_blade": {
"arm_leaf_front_blade_right": {
"scale": [1, 0, 1]
},
"right_arm_leaf_back_blade": {
"arm_leaf_back_blade_right": {
"scale": [1, 0, 1]
},
"left_arm_leaf_front_blade": {
"arm_leaf_front_blade_left": {
"scale": [1, 0, 1]
},
"left_arm_leaf_back_blade": {
"arm_leaf_back_blade_left": {
"scale": [1, 0, 1]
},
"left_top_leaves": {
"tail_leaves_top_left": {
"rotation": [10, 0, 0]
},
"left_top_leaves2": {
"tail_leaves_top_left2": {
"rotation": [2.5, 0, 0]
},
"left_top_leaves3": {
"tail_leaves_top_left3": {
"rotation": [-7.5, 0, 0]
}
}
@@ -301,7 +302,7 @@
"torso": {
"rotation": [49.75757, -7.34759, 2.92368]
},
"upper_torso": {
"torso2": {
"rotation": [14.94548, 1.29256, -4.83045]
},
"neck": {
@@ -310,68 +311,68 @@
"head": {
"rotation": [-55.48448, 3.48051, -3.55608]
},
"right_shoulder": {
"shoulder_right": {
"rotation": [-58.62702, 15.46973, -8.28342],
"position": [0, -0.5, 0]
},
"right_upper_arm": {
"arm_right": {
"rotation": [-7.5, -1, -7.5]
},
"right_lower_arm": {
"arm_right2": {
"rotation": [0, -30, 0]
},
"right_hand": {
"hand_right": {
"rotation": [0, 0, -15]
},
"right_index_finger": {
"finger_front_right": {
"rotation": [0, 0, -12.5]
},
"right_index_finger2": {
"finger_front_right2": {
"rotation": [0, 0, -45]
},
"right_middle_finger": {
"finger_middle_right": {
"rotation": [0, 0, 22.5],
"position": [0.5, 0, 0]
},
"right_middle_finger2": {
"finger_middle_right2": {
"rotation": [0, 0, -35]
},
"right_pinky_finger": {
"finger_back_right": {
"rotation": [0, 0, -37.5]
},
"right_pinky_finger2": {
"finger_back_right2": {
"rotation": [0, 0, -42.5]
},
"left_shoulder": {
"shoulder_left": {
"rotation": [-59.92127, -18.02575, 12.77165],
"position": [0, -0.5, 0]
},
"left_upper_arm": {
"arm_left": {
"rotation": [-7.5, 1, 7.5]
},
"left_lower_arm": {
"arm_left2": {
"rotation": [0, 42.5, 0]
},
"left_hand": {
"hand_left": {
"rotation": [0, 0, 15]
},
"left_index_finger": {
"finger_front_left": {
"rotation": [0, 0, 12.5]
},
"left_index_finger2": {
"finger_front_left2": {
"rotation": [0, 0, 45]
},
"left_middle_finger": {
"finger_middle_left": {
"rotation": [0, 0, -22.5],
"position": [-0.5, 0, 0]
},
"left_middle_finger2": {
"finger_middle_left2": {
"rotation": [0, 0, 35]
},
"left_pinky_finger": {
"finger_back_left": {
"rotation": [0, 0, 37.5]
},
"left_pinky_finger2": {
"finger_back_left2": {
"rotation": [0, 0, 42.5]
},
"tail": {
@@ -390,97 +391,170 @@
"tail5": {
"rotation": [10.08453, -7.38542, -1.30962]
},
"right_upper_leg": {
"leg_right": {
"rotation": [-25.44458, 0.21572, -4.69162],
"position": [0, 0, -1]
},
"right_lower_leg": {
"leg_right2": {
"rotation": [-5, -2.5, 0]
},
"right_ankle": {
"leg_right3": {
"rotation": [35, 0, 0],
"position": [0, 0, 0.6]
},
"right_foot": {
"foot_right": {
"rotation": [7.74222, 4.81281, 5.7589]
},
"right_middle_toe": {
"toe_middle_right": {
"rotation": [-12.5, 0, 0]
},
"right_inner_toe": {
"toe_inner_right": {
"rotation": [-12.5, 0, 0]
},
"right_outer_toe": {
"toe_outer_right": {
"rotation": [-12.5, 0, 0]
},
"left_upper_leg": {
"leg_left": {
"rotation": [32.71776, -4.77227, -5.22233],
"position": [0, 0, 1]
},
"left_lower_leg": {
"leg_left2": {
"rotation": [4.96271, -0.86717, 4.92442]
},
"left_ankle": {
"leg_left3": {
"rotation": [42.5, 0, 0],
"position": [0, 0, 1]
},
"left_foot": {
"foot_left": {
"rotation": [85, 0, 0],
"position": [0, 0.35, 1.2]
},
"left_middle_toe": {
"toe_middle_left": {
"rotation": [5, 0, 0]
},
"left_inner_toe": {
"toe_inner_left": {
"rotation": [10, 0, 0]
},
"left_outer_toe": {
"toe_outer_left": {
"rotation": [15, 0, 0]
},
"left_bottom_leaves": {
"tail_leaves_bottom_left": {
"rotation": [0, -5, 0]
},
"left_bottom_leaves3": {
"tail_leaves_bottom_left3": {
"rotation": [0, 5, 0]
},
"left_middle_toe2": {
"toe_middle_left2": {
"rotation": [17.5, 0, 0]
},
"left_inner_toe2": {
"toe_inner_left2": {
"rotation": [22.5, 0, 0]
},
"left_outer_toe2": {
"toe_outer_left2": {
"rotation": [15, 0, 0]
},
"right_top_leaves": {
"tail_leaves_top_right": {
"rotation": [2.5, 0, 0]
},
"right_top_leaves3": {
"tail_leaves_top_right3": {
"rotation": [-5, 0, 0]
}
}
},
"animation.sceptile.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"right_eyelid": {
"eyelid_right": {
"position": {
"0.0": [-0.1, 0, 0],
"0.125": {"pre": [-0.1, 0, 0], "post": [-0.1, 0, 0]},
"0.125": [-0.1, 0, 0],
"0.1667": {"pre": [-0.1, 0, 0], "post": [0, 0, 0]}
}
},
"left_eyelid": {
"eyelid_left": {
"position": {
"0.0": [0.1, 0, 0],
"0.125": {"pre": [0.1, 0, 0], "post": [0.1, 0, 0]},
"0.125": [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.33333,
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.sceptile.cry"
@@ -788,34 +788,30 @@
}
},
"animation.metagross.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"eye_open_left": {
"position": {
"0.0": [0, 0, 0.1],
"0.125": [0, 0, 0.1],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"eye_closed_left": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
},
"eye_open_right": {
"position": {
"0.0": [0, 0, 0.1],
"0.125": [0, 0, 0.1],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
}
},
"eye_closed_right": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
}
}
}
@@ -972,12 +968,6 @@
"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]
},
@@ -1013,6 +1003,12 @@
},
"hand_back_right": {
"rotation": [0, 0, -15]
},
"eye_open_right": {
"position": [0, 0, 0.1]
},
"eye_closed_right": {
"position": [0, 0, -0.1]
}
}
},
@@ -1023,6 +1019,87 @@
"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,7 +5,11 @@
"loop": true,
"bones": {
"body": {
"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"],
"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)"
],
"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": {
@@ -45,7 +49,11 @@
"loop": true,
"bones": {
"body": {
"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"],
"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)"
],
"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": {
@@ -266,45 +274,117 @@
"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]
}
}
}
},
@@ -470,6 +550,65 @@
}
}
},
"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,6 +159,14 @@
"rotation": [-9.99762, -0.10901, 10.00238]
}
}
},
"animation.leafeon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.leafeon.cry"
}
}
}
}
}
@@ -177,6 +177,14 @@
"rotation": [0, 0, -7.5]
}
}
},
"animation.glaceon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.glaceon.cry"
}
}
}
}
}
@@ -0,0 +1,427 @@
{
"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,112 +4,36 @@
"animation.braixen.ground_idle": {
"loop": true,
"bones": {
"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]
"torso": {
"rotation": [2.5, 0, 0]
},
"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": [0, 0, -7.5]
"rotation": [57.5, -10, 7.5]
},
"finger_front_left": {
"rotation": [0, 0, 25]
"neck": {
"rotation": [-5, 0, 0]
},
"finger_back_left": {
"rotation": [0, 0, 22.5]
"head": {
"rotation": [12.5, 0, 0]
},
"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": {
"tail": {
"rotation": [5, 0, 0]
},
"stick_tail": {
"rotation": [-5, 0, 0]
},
"leg_left": {
"rotation": [0.88045, -9.96156, -5.07673]
},
@@ -125,8 +49,78 @@
"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
}
}
},
@@ -134,13 +128,14 @@
"loop": true,
"bones": {
"body": {
"rotation": [0, -52.5, 0],
"position": [-0.5, -2.05, 0]
},
"torso": {
"rotation": [15, -10, 0]
},
"waist": {
"rotation": [5, 0, 0]
"rotation": [-2.5, -2.5, 0]
},
"chest": {
"rotation": [-5, 2.5, 0]
@@ -167,10 +162,10 @@
"rotation": [0, -10, 0]
},
"arm_right": {
"rotation": [-35.09473, -47.42923, -40.56425]
"rotation": [-60.09473, -14.92923, -20.56425]
},
"arm_right2": {
"rotation": [0, -40, 0]
"rotation": [0, -45, 0]
},
"hand_right": {
"rotation": [0, 27.5, 15]
@@ -185,10 +180,10 @@
"rotation": [0, 0, -77.5]
},
"neck": {
"rotation": [0, 5, 0]
"rotation": [0, 32.5, -7.5]
},
"head": {
"rotation": [-10, 0, 0]
"rotation": [-7.5, 20, -5]
},
"ear_ruff_left2": {
"rotation": [0, -12.5, 0]
@@ -221,28 +216,32 @@
"scale": 0
},
"leg_left": {
"rotation": [5.38152, -19.291, -15.91527]
"rotation": [-0.5, -35, -26],
"position": [1, 0, 0]
},
"leg_left2": {
"rotation": [25, 0, 0]
"rotation": [10, 0, 0]
},
"leg_left3": {
"rotation": [-16.28567, 14.26008, -10.25103]
"rotation": [-22.5, 0, 0]
},
"foot_left": {
"rotation": [-12.32417, 1.61888, 12.39638]
"rotation": [29.78634, -18.01295, 11.28749],
"position": [0, -0.5, 0]
},
"leg_right": {
"rotation": [-27.5, 0, 0]
"rotation": [-7.80674, 36.44232, 19.22515],
"position": [-1, -0.75, -0.75]
},
"leg_right2": {
"rotation": [27.25489, -5.05904, 5.54401]
"rotation": [29.75489, -5.05904, 8.04401]
},
"leg_right3": {
"rotation": [-25, 0, 0]
"rotation": [-30.5, -2, -1]
},
"foot_right": {
"rotation": [24.78729, 3.74196, -6.50446]
"rotation": [22.5, 20, -10],
"position": [0, -0.5, 0]
},
"ear_ruff_right2": {
"rotation": [0, 12.5, 0]
@@ -253,24 +252,111 @@
"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"
}
}
},
@@ -392,7 +478,7 @@
"finger_back_right": {
"rotation": [0, 0, -22.5]
},
"stick_hand": {
"wand": {
"scale": 0
},
"ear_ruff_shock_left": {
@@ -408,198 +494,6 @@
"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,295 +3,443 @@
"animations": {
"animation.delphox.ground_idle": {
"loop": true,
"animation_length": 8,
"bones": {
"head": {
"rotation": ["10+math.sin(q.anim_time*90*1-15)*2", 0, 0]
},
"ear_ruff_top_right": {
"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": [0, -2.5, -12.5]
},
"ear_ruff_middle_right2": {
"rotation": [0, 20, "5-math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_middle_right3": {
"rotation": [0, 15, "7.5-math.sin(q.anim_time*90*1-215)*3"]
},
"ear_ruff_bottom_right": {
"rotation": [0, 10, -17.5],
"position": [-0.1, 0, 0.25]
},
"ear_ruff_bottom_right2": {
"rotation": [0, 10, "12.5-math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_bottom_right3": {
"rotation": [0, 17.5, "12.5-math.sin(q.anim_time*90*1-215)*3"]
},
"ear_ruff_top_left": {
"rotation": [0, -7.5, 10],
"position": [0.3, 0, 0.5]
},
"ear_ruff_top_left2": {
"rotation": [0, -15, "math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_top_left3": {
"rotation": [0, -7.5, "-10+math.sin(q.anim_time*90*1-215)*3"]
},
"ear_ruff_middle_left": {
"rotation": [0, 2.5, 12.5]
},
"ear_ruff_middle_left2": {
"rotation": [0, -20, "-5+math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_middle_left3": {
"rotation": [0, -15, "-7.5+math.sin(q.anim_time*90*1-215)*3"]
},
"ear_ruff_bottom_left": {
"rotation": [0, -10, 17.5],
"position": [0.1, 0, 0.25]
},
"ear_ruff_bottom_left2": {
"rotation": [0, -10, "-12.5+math.sin(q.anim_time*90*1-180)*3"]
},
"ear_ruff_bottom_left3": {
"rotation": [0, -17.5, "-12.5+math.sin(q.anim_time*90*1-215)*3"]
},
"arm_right": {
"rotation": [0, "-12.5+math.sin(q.anim_time*90*1+30)*2", -52.5]
},
"arm_right2": {
"rotation": [3.31914, "-14.6364+math.sin(q.anim_time*90*1+90)*2", -12.92638]
},
"hand_right": {
"rotation": [0, 0, -12.5]
},
"finger_index_right": {
"rotation": [0, 0, -50]
},
"finger_middle_right": {
"rotation": [0, 0, -52.5]
},
"finger_ring_right": {
"rotation": [0, 0, -60]
},
"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"]
"rotation": [0, -5, 60]
},
"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"]
"rotation": [0, 12.5, 0]
},
"hand_left": {
"rotation": [0, 0, 20]
},
"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": [-5, 0, 0]
},
"shoulder_left_ruff": {
"rotation": [-12.5, 0, 0]
},
"arm_left_ruff2": {
"rotation": [-10, 0, 0]
},
"finger_front_left": {
"rotation": [0, 0, 17.5]
},
"finger_middle_left": {
"rotation": [0, 0, 12.5]
},
"finger_back_left": {
"rotation": [0, 0, 35]
"rotation": [0, 0, 30]
},
"arm_right_ruff": {
"rotation": [-5, 0, 0]
"arm_right": {
"rotation": [0, 5, -60]
},
"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": {
"arm_right2": {
"rotation": [0, -12.5, 0]
},
"ear_ruff_middle_left4": {
"rotation": [0, -10, 0]
"hand_right": {
"rotation": [0, 0, -15]
},
"ear_ruff_shock_right": {
"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]
},
"ear_ruff_top_right": {
"rotation": [0, 5, 0]
},
"ear_ruff_middle_right": {
"rotation": [-5, -10, 0]
},
"leg_left": {
"rotation": [-10.50431, -1.61684, -2.5578],
"position": [0, 0, -0.5]
},
"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_top_right4": {
"rotation": [0, 12.5, 0]
"ear_ruff_shock_right": {
"rotation": [0, 5, 0],
"scale": 0
},
"ear_ruff_middle_right4": {
"rotation": [0, 10, 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_bottom_right": {
"rotation": [0, 2.5, -15]
},
"leg_left2": {
"rotation": [5, 0, 0]
},
"leg_right2": {
"rotation": [2.5, 0, 0]
},
"robe_left_outer": {
"rotation": [0, 2.5, 0]
},
"robe_left_outer3": {
"rotation": [0, -2.5, 0]
},
"chest": {
"rotation": ["math.sin(q.anim_time*90*1)*-1", 0, 0]
},
"ear_right": {
"rotation": [0, 0, "math.sin(q.anim_time*90*1-60)*2"]
},
"ear_right_main": {
"rotation": [0, 0, "math.sin(q.anim_time*90*1-30)*1"]
},
"robe_right": {
"rotation": [0, 2.5, 0]
},
"robe_right_outer": {
"rotation": [0, 2.5, 0]
},
"robe_right_outer2": {
"rotation": [0, -2.5, 0]
},
"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]
},
"arm_right": {
"rotation": [-57.5, -30, -25],
"position": [-1, -0.75, 0.25]
},
"arm_right2": {
"rotation": [7.5, -55, -17.5]
},
"arm_right_ruff": {
"rotation": [-15, 15, -7.5]
},
"hand_right": {
"rotation": [0, 22.5, 0],
"position": [-0.25, 0, 0]
},
"finger_front_right": {
"rotation": [0, 0, -50]
},
"finger_middle_right": {
"rotation": [0, 0, -55]
},
"finger_back_right": {
"rotation": [0, 0, -65]
},
"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_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]
},
"hand_left": {
"rotation": [-12.5, 32.5, -15]
},
"shoulder_right_ruff": {
"rotation": [0, 10, 0]
},
"torso_cloak": {
"rotation": [-27.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]
}
}
},
"animation.delphox.battle_idle2_wip": {
"loop": true,
"bones": {
"robe_left": {
@@ -481,20 +629,6 @@
"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]
},
@@ -513,7 +647,7 @@
"tail7": {
"rotation": [-27.5, 0, 0]
},
"stick_hand": {
"wand": {
"rotation": [115.18907, -6.79382, 69.31542],
"position": [7.5, -2, -2]
},
@@ -530,6 +664,34 @@
"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]}
}
}
}
},
@@ -817,7 +979,7 @@
"finger_back_right": {
"rotation": [0, 0, -45]
},
"stick_hand": {
"wand": {
"scale": 0
},
"ear_ruff_shock_left": {
@@ -866,25 +1028,6 @@
}
}
},
"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": {
@@ -952,170 +1095,6 @@
"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,6 +280,14 @@
"rotation": [-5, 10, -7.5]
}
}
},
"animation.sylveon.cry": {
"animation_length": 1.2,
"sound_effects": {
"0.04": {
"effect": "pokemon.sylveon.cry"
}
}
}
}
}
@@ -155,6 +155,9 @@
"back_neck_braid_right4": {
"rotation": [2.5, 0, -10],
"position": [-0.5, 0, 0]
},
"body": {
"rotation": ["q.riding.velocity_y(0)*-90", 0, 0]
}
}
},
@@ -650,7 +653,7 @@
}
},
"neck2": {
"rotation": ["5+math.sin(q.anim_time*90*4-60)*2", 0, 0]
"rotation": ["5+math.sin(q.anim_time*90*4-60)*2 - math.pow(q.riding.yaw_change(0),2)*20", "q.riding.yaw_change(0)*-10", "q.riding.yaw_change(0)*10"]
},
"tail5": {
"rotation": ["-7.5+math.sin(q.anim_time*90*4-90)*2", "math.sin(q.anim_time*90*2)*1", "math.sin(q.anim_time*90*2)*4"]
@@ -677,7 +680,7 @@
}
},
"neck": {
"rotation": ["3+math.sin(q.anim_time*90*4-30)*1", 0, "math.sin(q.anim_time*90*2-30)*2"]
"rotation": ["3+math.sin(q.anim_time*90*4-30)*1", "q.riding.yaw_change(0)*-10", "math.sin(q.anim_time*90*2-30)*2 + q.riding.yaw_change(0)*10"]
},
"front_neck_braid_left": {
"rotation": ["5+math.sin(q.anim_time*90*4-60)*1", 0.5, 5]
@@ -844,6 +847,7 @@
"position": [-0.5, 0, 0]
},
"body": {
"rotation": ["q.riding.velocity_y(0)*-90", 0, 0],
"position": {
"0.0": [0, 0, 0],
"0.0417": [0, -0.25, 0],
@@ -1257,7 +1261,7 @@
}
},
"neck2": {
"rotation": ["math.sin(q.anim_time*90*4-60)*4", 0, 0]
"rotation": ["math.sin(q.anim_time*90*4-60)*4 - math.pow(q.riding.yaw_delta(0),2)*20", "q.riding.yaw_delta(0)*-10", "q.riding.yaw_delta(0)*10"]
},
"tail5": {
"rotation": ["-10+math.sin(q.anim_time*90*4-100)*6", "math.sin(q.anim_time*90*4-40)*2", "math.sin(q.anim_time*90*4-20)*1"]
@@ -1279,7 +1283,7 @@
}
},
"neck": {
"rotation": ["13+math.sin(q.anim_time*90*4-30)*7", 0, 0],
"rotation": ["13+math.sin(q.anim_time*90*4-30)*7", "q.riding.yaw_delta(0)*-10", "q.riding.yaw_delta(0)*10"],
"position": [0, 0, "-0.5+math.sin(q.anim_time*90*4-30)*0.2"]
},
"front_neck_braid_left": {
@@ -5,20 +5,20 @@
"loop": true,
"bones": {
"body": {
"position": [0, -0.7, 0]
},
"waist": {
"rotation": [0, 0, 9],
"position": [0, -0.2, 0]
"position": [0, -0.6, 0]
},
"torso": {
"rotation": [0, 0, -9]
"rotation": [-3, 5, 1.5],
"position": [0, -0.2, 0]
},
"torso2": {
"rotation": [4, 0, -1.5]
},
"head": {
"rotation": [0, 0, 0]
"rotation": [0, -5, 0]
},
"feather": {
"rotation": [-47.5, 22.5, 0]
"rotation": [-47.5, 28, 0]
},
"feather2": {
"rotation": [-35, 0, 0]
@@ -30,13 +30,13 @@
"rotation": [-32.5, 0, 0]
},
"arm_right": {
"rotation": [30, 22.5, -46.5]
"rotation": [30, 22.5, -52]
},
"arm_right2": {
"rotation": [45, -90, 0]
},
"hand_right": {
"rotation": [10, 5, -15]
"rotation": [20, 10, -15]
},
"arm_claw_back_right": {
"rotation": [0, 0, -30]
@@ -63,14 +63,14 @@
"rotation": [-20, 0, 0]
},
"leg_right": {
"rotation": [1.5, 5, 8],
"rotation": [5, 15, 8],
"position": [0, 0.4, 0]
},
"leg_right2": {
"rotation": [3, 0, 0]
"rotation": [0, 0, 0]
},
"foot_right": {
"rotation": [-3.5, 0, 0]
"rotation": [0, 0, 0]
},
"feather5": {
"rotation": [-27.5, 0, 0]
@@ -85,14 +85,14 @@
"rotation": [25, 0, 0]
},
"leg_left": {
"rotation": [-15, -15, -8],
"rotation": [-12.5, -15, -8],
"position": [0, -0.8, 0]
},
"leg_right3": {
"rotation": [0, 0, -8]
"rotation": [-2.5, 0, -7]
},
"leg_left2": {
"rotation": [25, 0, 0]
"rotation": [22.5, 0, 0]
},
"leg_left3": {
"rotation": [0, 0, 8]
@@ -102,62 +102,317 @@
}
}
},
"animation.sneasler.mouth_test": {
"animation_length": 2,
"animation.sneasler.battle_idle": {
"loop": true,
"bones": {
"fang": {
"rotation": {
"0.0": [0, 0, 0],
"0.6667": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.7083": {"pre": [0, 0, 0], "post": [0, 0, 11.5]},
"1.5": {"pre": [0, 0, 11.5], "post": [0, 0, 11.5]},
"1.5417": {"pre": [0, 0, 11.5], "post": [0, 0, 0]}
},
"position": {
"0.0": [0, 0, 0],
"0.6667": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.7083": {"pre": [0, 0, 0], "post": [0, 0.7, 0.4]},
"1.5": {"pre": [0, 0.7, 0.4], "post": [0, 0.7, 0.4]},
"1.5417": {"pre": [0, 0.7, 0.4], "post": [0, 0, 0]}
}
"locator_top": {
"position": [0, -4, 0]
},
"jaw": {
"position": {
"0.0": [0, 0, 0],
"0.6667": {"pre": [0, 0, 0], "post": [0, 0, 0]},
"0.7083": {"pre": [0, 0, 0], "post": [0, 0, 0.61]},
"1.5": {"pre": [0, 0, 0.61], "post": [0, 0, 0.61]},
"1.5417": {"pre": [0, 0, 0.61], "post": [0, 0, 0]}
}
"body": {
"rotation": [0, 20, 0],
"position": [0, -4.6, 0]
},
"torso": {
"rotation": [-5, 15, 0]
},
"torso2": {
"rotation": [12, 0, 0]
},
"neck": {
"rotation": [20, 0, 0]
},
"head": {
"rotation": [-26, -31, 18],
"position": [0, 0, -0.2]
},
"feather": {
"rotation": [-47.5, 28, 0]
},
"feather2": {
"rotation": [-35, 0, 0]
},
"feather3": {
"rotation": [-50, 0, 0]
},
"feather4": {
"rotation": [-32.5, 0, 0]
},
"feather5": {
"rotation": [-27.5, 0, 0]
},
"feather6": {
"rotation": [15, 0, 0]
},
"feather7": {
"rotation": [22.5, 0, 0]
},
"feather8": {
"rotation": [25, 0, 0]
},
"arm_right": {
"rotation": [-32.5, 50, -65]
},
"arm_right2": {
"rotation": [0, -70, 0]
},
"hand_right": {
"rotation": [5, -5, -5]
},
"arm_claw_back_right": {
"rotation": [0, 5, -10]
},
"arm_claw_middle_right": {
"rotation": [0, 0, -2]
},
"arm_claw_front_right": {
"rotation": [0, -5, 5]
},
"arm_left": {
"rotation": [-5, 0, 0]
},
"arm_left2": {
"rotation": [-5, 85, 0]
},
"hand_left": {
"rotation": [-5, 10, 0]
},
"arm_claw_back_left": {
"rotation": [0, -10, 15]
},
"arm_claw_middle_left": {
"rotation": [0, 0, 5]
},
"arm_claw_front_left": {
"rotation": [0, 10, -5]
},
"leg_right": {
"rotation": [-14.5, 40, 45],
"position": [-0.5, 0, 1]
},
"leg_right2": {
"rotation": [64, 0, 0],
"position": [0, 0, 1]
},
"leg_right3": {
"rotation": [-9.5, -2.5, -33.5],
"position": [0, -0.4, 0]
},
"foot_right": {
"rotation": [-4.5, 0, 0]
},
"leg_left": {
"rotation": [-30, -35, -32],
"position": [0, 0, -1]
},
"leg_left2": {
"rotation": [25, 0, 5]
},
"leg_left3": {
"rotation": [15.5, 0, 24.5]
},
"foot_left": {
"rotation": [5.5, 0, 0],
"position": [0, 0.6, 0]
}
}
},
"animation.sneasler.ground_idle_basket": {
"loop": true,
"bones": {
"body": {
"position": [0, -0.2, 0]
},
"torso": {
"rotation": [-2.5, 0, 0]
},
"torso2": {
"rotation": [3, 0, 0]
},
"basketstrap_right": {
"rotation": [-17.5, 10, 5]
},
"basketstrap_right3": {
"rotation": [-22, 0, 0]
},
"shoulder_fluff_right": {
"rotation": [0, 0, -15],
"position": [-0.5, 0, 0]
},
"shoulder_fluff_left": {
"rotation": [0, 0, 15],
"position": [0.5, 0, 0]
},
"neck": {
"rotation": [2, 0, 0]
},
"head": {
"rotation": [-1, 0, 0]
},
"feather": {
"rotation": [-47.5, 33, 0]
},
"feather2": {
"rotation": [-35, 0, 0]
},
"feather3": {
"rotation": [-50, 0, 0]
},
"feather4": {
"rotation": [-32.5, 0, 0]
},
"feather5": {
"rotation": [-27.5, 0, 0]
},
"feather6": {
"rotation": [15, 0, 0]
},
"feather7": {
"rotation": [22.5, 0, 0]
},
"feather8": {
"rotation": [25, 0, 0]
},
"arm_right": {
"rotation": [-12, 7.5, -62]
},
"arm_right2": {
"rotation": [0, -15, -2.5]
},
"hand_right": {
"rotation": [0, 0, -2.5]
},
"arm_claw_middle_right": {
"rotation": [0, 0, -5]
},
"arm_claw_front_right": {
"rotation": [0, 0, -10]
},
"arm_left": {
"rotation": [-12, -7.5, 62]
},
"arm_left2": {
"rotation": [0, 15, 2.5]
},
"hand_left": {
"rotation": [0, 0, 2.5]
},
"arm_claw_middle_left": {
"rotation": [0, 0, 5]
},
"arm_claw_front_left": {
"rotation": [0, 0, 10]
},
"leg_right": {
"rotation": [-2.5, 12, 5.5],
"position": [-0.3, 0, 0]
},
"leg_right2": {
"rotation": [5, 0, 0]
},
"leg_right3": {
"rotation": [-1, 0, -5]
},
"leg_left": {
"rotation": [-2.5, -12, -5.5],
"position": [0.3, 0, 0]
},
"leg_left2": {
"rotation": [5, 0, 0]
},
"leg_left3": {
"rotation": [-1, 0, 5]
},
"basketstrap_right4": {
"rotation": [35, 0, 0]
},
"shoulder_fluff_back_right": {
"rotation": [0, 0, 0]
},
"shoulder_fluff_front_right": {
"rotation": [15, 0, 0]
},
"shoulder_fluff_back_left": {
"rotation": [0, 0, 0]
},
"shoulder_fluff_front_left": {
"rotation": [15, 0, 0]
},
"basketstrap_right2": {
"rotation": [52, 0, 0]
},
"basketstrap_left": {
"rotation": [-17.5, -10, -5]
},
"basketstrap_left2": {
"rotation": [52, 0, 0]
},
"basketstrap_left3": {
"rotation": [-22, 0, 0]
},
"basketstrap_left4": {
"rotation": [35, 0, 0]
}
}
},
"animation.sneasler.blink": {
"animation_length": 0.16667,
"animation_length": 0.1667,
"bones": {
"eyelid_right": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
"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_left": {
"position": {
"0.0": [0, 0, -0.1],
"0.125": [0, 0, -0.1],
"0.1667": [0, 0, 0]
"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]
}
}
},
"eyelashes_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]
}
}
},
"eyelashes_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]
}
}
}
}
},
"animation.sneasler.cry": {
"animation_length": 1,
"sound_effects": {
"0.04": {
"effect": "pokemon.sneasler.cry"
}
},
"bones": {
"head": {
"rotation": {
@@ -171,24 +426,25 @@
"0.5": [0, 0, 0]
}
},
"fang": {
"rotation": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0, 0, 11.5]},
"0.1667": {"pre": [0, 0, 11.5], "post": [0, 0, 11.5]},
"0.2083": {"pre": [0, 0, 11.5], "post": [0, 0, 0]},
"0.25": {"pre": [0, 0, 0], "post": [0, 0, 11.5]},
"0.4583": {"pre": [0, 0, 11.5], "post": [0, 0, 11.5]},
"0.5": {"pre": [0, 0, 11.5], "post": [0, 0, 0]}
},
"fang_closed": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0, 0.7, 0.4]},
"0.1667": {"pre": [0, 0.7, 0.4], "post": [0, 0.7, 0.4]},
"0.2083": {"pre": [0, 0.7, 0.4], "post": [0, 0, 0]},
"0.25": {"pre": [0, 0, 0], "post": [0, 0.7, 0.4]},
"0.4583": {"pre": [0, 0.7, 0.4], "post": [0, 0.7, 0.4]},
"0.5": {"pre": [0, 0.7, 0.4], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [0, 0.1, 1.1]
},
"0.2083": {
"pre": [0, 0.1, 1.1],
"post": [0, 0, 0]
},
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0.1, 1.1]
},
"0.5": {
"pre": [0, 0.1, 1.1],
"post": [0, 0, 0]
}
}
},
"feather": {
@@ -206,13 +462,63 @@
"jaw": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {"pre": [0, 0, 0], "post": [0, 0, 0.61]},
"0.1667": {"pre": [0, 0, 0.61], "post": [0, 0, 0.61]},
"0.2083": {"pre": [0, 0, 0.61], "post": [0, 0, 0]},
"0.25": {"pre": [0, 0, 0], "post": [0, 0, 0.61]},
"0.4583": {"pre": [0, 0, 0.61], "post": [0, 0, 0.61]},
"0.5": {"pre": [0, 0, 0.61], "post": [0, 0, 0]}
"0.0417": {
"pre": [0, 0, 0],
"post": [0, 0, 1.1]
},
"0.2083": {
"pre": [0, 0, 1.1],
"post": [0, 0, 0]
},
"0.25": {
"pre": [0, 0, 0],
"post": [0, 0, 1.1]
},
"0.5": {
"pre": [0, 0, 1.1],
"post": [0, 0, 0]
}
}
},
"mouth_open": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [0, -0.3, -0.1]
},
"0.2083": {
"pre": [0, -0.3, -0.1],
"post": [0, 0, 0]
},
"0.25": {
"pre": [0, 0, 0],
"post": [0, -0.3, -0.1]
},
"0.5": {
"pre": [0, -0.3, -0.1],
"post": [0, 0, 0]
}
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.sneasler.cry"
}
}
},
"animation.sneasler.item_hold": {
"loop": true,
"bones": {
"arm_claw_back_right": {
"rotation": [0, 0, -45]
},
"arm_claw_middle_right": {
"rotation": [0, 0, -45]
},
"arm_claw_front_right": {
"rotation": [0, 0, -45]
}
}
}
@@ -7,8 +7,8 @@
"texture_width": 256,
"texture_height": 128,
"visible_bounds_width": 10,
"visible_bounds_height": 5,
"visible_bounds_offset": [0, 1.5, 0]
"visible_bounds_height": 6,
"visible_bounds_offset": [0, 2, 0]
},
"bones": [
{
@@ -20,7 +20,7 @@
"parent": "charizard",
"pivot": [0, 0, -1],
"locators": {
"root": [0, 0, 0]
"root": [0, 0, -1]
}
},
{
@@ -28,7 +28,7 @@
"parent": "charizard",
"pivot": [0, 41, -1],
"locators": {
"top": [0, 41, 0]
"top": [0, 41, -1]
}
},
{
@@ -116,7 +116,8 @@
{
"name": "head_correction",
"parent": "head",
"pivot": [0, 43.5, -0.5]
"pivot": [0, 43.5, -0.5],
"rotation": [-95, 0, 0]
},
{
"name": "head_ai",
@@ -127,20 +128,15 @@
"name": "head_angle",
"parent": "head_ai",
"pivot": [0, 43.5, -0.5],
"rotation": [95, 0, 0],
"cubes": [
{"origin": [-3.5, 41.5, -2], "size": [7, 7, 5], "uv": [48, 0]},
{"origin": [-3.5, 41.5, -4], "size": [7, 4, 2], "uv": [95, 64]}
{"origin": [-3.5, 41.5, -4], "size": [7, 4, 2], "uv": [95, 64]},
{"origin": [-2.5, 48, -2], "size": [5, 5, 2], "inflate": 0.02, "uv": [37, 31]},
{"origin": [-2, 51.48744, -3.03033], "size": [0, 1, 1], "inflate": 0.01, "pivot": [-2, 52.51777, -2], "rotation": [45, 0, 15], "uv": [43, 42]},
{"origin": [2, 51.48744, -3.03033], "size": [0, 1, 1], "inflate": 0.01, "pivot": [2, 52.51777, -2], "rotation": [45, 0, -15], "uv": [41, 42]}
]
},
{
"name": "item_hat",
"parent": "head_angle",
"pivot": [0, 45, 3],
"rotation": [-90, 0, 0],
"locators": {
"item_hat": [0, 45, 3]
}
},
{
"name": "locator_head",
"parent": "head_angle",
@@ -150,51 +146,59 @@
"head": [0, 46.5, 3]
}
},
{
"name": "locator_face",
"parent": "head_angle",
"pivot": [0, 53.75, -0.25],
"rotation": [-90, 0, 0],
"locators": {
"face": [0, 53.75, -0.25]
}
},
{
"name": "locator_item_face",
"parent": "head_angle",
"pivot": [0, 48.5, 0.5],
"rotation": [-90, 0, 0],
"locators": {
"item_face": [0, 48.5, 0.5]
}
},
{
"name": "locator_mouth",
"parent": "head_angle",
"pivot": [0, 45.75, -2],
"pivot": [0, 48.75, -3],
"rotation": [-90, 0, 0],
"locators": {
"mouth": [0, 45.75, -2],
"special": [0, 45.75, -2]
"mouth": [0, 48.75, -3]
}
},
{
"name": "eyes",
"name": "locator_special_attack",
"parent": "head_angle",
"pivot": [0, -3.5, 1.5]
"pivot": [0, 48.75, -3],
"rotation": [-90, 0, 0],
"locators": {
"special_attack": [0, 48.75, -3]
}
},
{
"name": "locator_jaw_upper",
"parent": "head_angle",
"pivot": [0, 51.75, -2.25],
"rotation": [-90, 0, 0],
"locators": {
"jaw1": [0, 51.75, -2.25]
}
},
{
"name": "brow",
"parent": "eyes",
"parent": "head_angle",
"pivot": [0, 48.275, 1.765],
"cubes": [
{"origin": [-2.5, 48.55, 1], "size": [5, 0, 1], "uv": [0, 14]},
{"origin": [-3.5, 47.5, 1.53], "size": [7, 1, 1], "inflate": 0.04, "uv": [0, 12]}
]
},
{
"name": "eye",
"parent": "head_angle",
"pivot": [0, -3.5, 1.5]
},
{
"name": "locator_face",
"parent": "eye",
"pivot": [0, 53.75, -0.25],
"rotation": [-90, 0, 0],
"locators": {
"face": [0, 53.75, -0.25]
}
},
{
"name": "eye_right",
"parent": "eyes",
"parent": "eye",
"pivot": [-2.75, 47.75, 0.875],
"cubes": [
{"origin": [-3.5, 47.5, 0], "size": [2, 1, 2], "inflate": 0.01, "uv": [106, 36]},
@@ -222,7 +226,7 @@
},
{
"name": "eye_left",
"parent": "eyes",
"parent": "eye",
"pivot": [2.75, 47.75, 0.875],
"cubes": [
{"origin": [1.5, 47.5, 0], "size": [2, 1, 2], "inflate": 0.01, "uv": [44, 82]},
@@ -251,91 +255,6 @@
{"origin": [2.41, 46.4, 0.5], "size": [1, 1, 1], "inflate": 0.03, "uv": [39, 86]}
]
},
{
"name": "muzzle",
"parent": "head_angle",
"pivot": [-3, 48.5, -2],
"cubes": [
{"origin": [-2.5, 48, -2], "size": [5, 5, 2], "inflate": 0.02, "uv": [37, 31]},
{"origin": [-2, 51.48744, -3.03033], "size": [0, 1, 1], "inflate": 0.01, "pivot": [-2, 52.51777, -2], "rotation": [45, 0, 15], "uv": [43, 42]},
{"origin": [2, 51.48744, -3.03033], "size": [0, 1, 1], "inflate": 0.01, "pivot": [2, 52.51777, -2], "rotation": [45, 0, -15], "uv": [41, 42]}
]
},
{
"name": "locator_jaw_upper",
"parent": "muzzle",
"pivot": [0, 51.75, -2.25],
"rotation": [-90, 0, 0],
"locators": {
"jaw1": [0, 51.75, -2.25]
}
},
{
"name": "nose",
"parent": "muzzle",
"pivot": [0, 53, 0],
"rotation": [-40, 0, 0],
"cubes": [
{"origin": [-2.5, 51.36698, -1.67861], "size": [5, 2, 2], "inflate": 0.03, "uv": [48, 12]},
{"origin": [-2, 53.40698, -1.17861], "size": [4, 0, 1], "uv": [0, 15]}
]
},
{
"name": "jaw",
"parent": "head_angle",
"pivot": [0, 45.5, -2],
"cubes": [
{"origin": [-3.5, 45.5, -4], "size": [7, 3, 2], "inflate": 0.01, "uv": [76, 20]}
]
},
{
"name": "jaw2",
"parent": "jaw",
"pivot": [0, 48.5, -4],
"rotation": [-7.5, 0, 0],
"cubes": [
{"origin": [-2, 48.49, -4], "size": [4, 4, 2], "uv": [0, 51]},
{"origin": [-1.5, 48.5, -2], "size": [3, 4, 0], "uv": [90, 0]},
{"origin": [1.5, 51.49749, -3.03033], "size": [0, 1, 1], "pivot": [1.5, 52.52782, -2], "rotation": [45, 0, -7.5], "uv": [37, 39]},
{"origin": [-1.5, 51.49749, -3.03033], "size": [0, 1, 1], "pivot": [-1.5, 52.52782, -2], "rotation": [45, 0, 7.5], "uv": [37, 38]}
]
},
{
"name": "locator_jaw_lower",
"parent": "jaw2",
"pivot": [0, 51.75, -1.75],
"locators": {
"jaw2": {
"offset": [0, 51.75, -1.75],
"rotation": [-90, 0, 0]
}
}
},
{
"name": "tongue",
"parent": "jaw",
"pivot": [0, 45.5, -2],
"cubes": [
{"origin": [-1.5, 45.5, -2], "size": [3, 3, 0], "uv": [87, 29]}
]
},
{
"name": "tongue2",
"parent": "tongue",
"pivot": [0, 48.5, -2],
"cubes": [
{"origin": [-1, 48.5, -2], "size": [2, 2, 0], "inflate": 0.01, "uv": [46, 38]}
]
},
{
"name": "tongue3",
"parent": "tongue2",
"pivot": [0, 50.5, -2],
"cubes": [
{"origin": [-1, 50.5, -2], "size": [2, 1, 0], "uv": [37, 43]},
{"origin": [-0.5, 51.5, -2], "size": [1, 1, 0], "uv": [45, 43]}
]
},
{
"name": "horns",
"parent": "head_angle",
@@ -381,6 +300,72 @@
"horn2": [2.5, 39, 2]
}
},
{
"name": "nose",
"parent": "head_angle",
"pivot": [0, 53, 0],
"rotation": [-40, 0, 0],
"cubes": [
{"origin": [-2.5, 51.36698, -1.67861], "size": [5, 2, 2], "inflate": 0.03, "uv": [48, 12]},
{"origin": [-2, 53.40698, -1.17861], "size": [4, 0, 1], "uv": [0, 15]}
]
},
{
"name": "jaw",
"parent": "head_angle",
"pivot": [0, 45.5, -2],
"cubes": [
{"origin": [-3.5, 45.5, -4], "size": [7, 3, 2], "inflate": 0.01, "uv": [76, 20]}
]
},
{
"name": "jaw2",
"parent": "jaw",
"pivot": [0, 48.5, -4],
"rotation": [-7.5, 0, 0],
"cubes": [
{"origin": [-2, 48.49, -4], "size": [4, 4, 2], "uv": [0, 51]},
{"origin": [-1.5, 48.5, -1.99], "size": [3, 4, 0], "uv": [90, 0]},
{"origin": [1.5, 51.49749, -3.03033], "size": [0, 1, 1], "pivot": [1.5, 52.52782, -2], "rotation": [45, 0, -7.5], "uv": [37, 39]},
{"origin": [-1.5, 51.49749, -3.03033], "size": [0, 1, 1], "pivot": [-1.5, 52.52782, -2], "rotation": [45, 0, 7.5], "uv": [37, 38]}
]
},
{
"name": "locator_jaw_lower",
"parent": "jaw2",
"pivot": [0, 51.75, -1.75],
"locators": {
"jaw2": {
"offset": [0, 51.75, -1.75],
"rotation": [-90, 0, 0]
}
}
},
{
"name": "tongue",
"parent": "jaw",
"pivot": [0, 45.5, -2],
"cubes": [
{"origin": [-1.5, 45.5, -2], "size": [3, 3, 0], "uv": [87, 29]}
]
},
{
"name": "tongue2",
"parent": "tongue",
"pivot": [0, 48.5, -2],
"cubes": [
{"origin": [-1, 48.5, -2], "size": [2, 2, 0], "inflate": 0.01, "uv": [46, 38]}
]
},
{
"name": "tongue3",
"parent": "tongue2",
"pivot": [0, 50.5, -2],
"cubes": [
{"origin": [-1, 50.5, -2], "size": [2, 1, 0], "uv": [37, 43]},
{"origin": [-0.5, 51.5, -2], "size": [1, 1, 0], "uv": [45, 43]}
]
},
{
"name": "arms",
"parent": "torso2",
@@ -418,14 +403,6 @@
{"origin": [-21.5, 22, -1.5], "size": [3, 2, 3], "inflate": 0.1, "uv": [0, 58]}
]
},
{
"name": "locator_item",
"parent": "hand_right",
"pivot": [-21.6, 23, 0],
"locators": {
"item": [-21.6, 23, 0]
}
},
{
"name": "locator_hand_primary",
"parent": "hand_right",
@@ -936,14 +913,6 @@
{"origin": [0, 9.5, 58.5], "size": [0, 13, 7], "pivot": [0, 14.45, 62], "rotation": [0, 90, 0], "uv": [0, 92]}
]
},
{
"name": "locator_fire",
"parent": "fire2",
"pivot": [0, 11, 62],
"locators": {
"fire": [0, 11, 62]
}
},
{
"name": "legs",
"parent": "body",
@@ -976,10 +945,9 @@
{
"name": "locator_foot_primary",
"parent": "foot_right",
"pivot": [-9, 1.5, -5],
"rotation": [90, 0, 0],
"pivot": [-9, 1.5, -7],
"locators": {
"foot_primary": [-9, 1.5, -5]
"foot_primary": [-9, 1.5, -7]
}
},
{
@@ -1041,10 +1009,9 @@
{
"name": "locator_foot_secondary",
"parent": "foot_left",
"pivot": [9, 1.5, -5],
"rotation": [90, 0, 0],
"pivot": [9, 1.5, -7],
"locators": {
"foot_secondary": [9, 1.5, -5]
"foot_secondary": [9, 1.5, -7]
}
},
{
@@ -15,14 +15,6 @@
"name": "lapras",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "lapras",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "body",
"parent": "lapras",
@@ -37,11 +29,11 @@
}
},
{
"name": "locator_body",
"name": "locator_middle",
"parent": "body",
"pivot": [0, 0, 0],
"locators": {
"body": [0, 14, 0]
"middle": [0, 14, 0]
}
},
{
@@ -68,6 +60,14 @@
{"origin": [-15.25, 13.5, -7], "size": [3, 3, 3], "pivot": [-12.5, 13.5, -4.5], "rotation": [0, -15, 5], "uv": [12, 120], "mirror": true}
]
},
{
"name": "locator_seat_1",
"parent": "shell",
"pivot": [0, 24, 0],
"locators": {
"seat_1": [0, 24, 0]
}
},
{
"name": "shell2",
"parent": "shell",
@@ -138,6 +138,31 @@
{"origin": [-5.5, 30, -14.5], "size": [11, 10, 8], "inflate": 0.01, "uv": [0, 0]}
]
},
{
"name": "locator_item_face",
"parent": "head_angle",
"pivot": [0, 37.25, -21],
"rotation": [-22.5, 0, 0],
"locators": {
"item_face": [0, 37.25, -21]
}
},
{
"name": "locator_face",
"parent": "head_angle",
"pivot": [0, 36, -24.1],
"locators": {
"face": [0, 36, -24.1]
}
},
{
"name": "locator_item_hat",
"parent": "head_angle",
"pivot": [0, 40, -12],
"locators": {
"item_hat": [0, 40, -12]
}
},
{
"name": "locator_head",
"parent": "head_angle",
@@ -160,14 +185,6 @@
"parent": "head_angle",
"pivot": [0, 30.75, -11.15]
},
{
"name": "locator_face",
"parent": "eyes",
"pivot": [0, 36, -24.1],
"locators": {
"face": [0, 36, -24.1]
}
},
{
"name": "eye_right",
"parent": "eyes",
@@ -306,6 +323,14 @@
"jaw_lower": [0, 32.15, -21.5]
}
},
{
"name": "locator_item",
"parent": "jaw",
"pivot": [0, 32, -22.5],
"locators": {
"item": [0, 32, -22.5]
}
},
{
"name": "tongue",
"parent": "jaw",
@@ -345,6 +370,15 @@
{"origin": [-6.5, 1.5, 11], "size": [13, 10, 7], "uv": [78, 40]}
]
},
{
"name": "locator_tail",
"parent": "tail",
"pivot": [0, 5, 17],
"rotation": [0, 180, 0],
"locators": {
"tail": [0, 5, 17]
}
},
{
"name": "tail2",
"parent": "tail",
@@ -499,26 +533,19 @@
]
},
{
"name": "bone2",
"pivot": [0, 0, 0]
},
{
"name": "bone4",
"parent": "bone2",
"pivot": [0, 0, 0]
},
{
"name": "bone",
"name": "locator_root",
"parent": "lapras",
"pivot": [0, 0, 0],
"locators": {
"locator5": [0, 0, 0]
"root": [0, 0, 0]
}
},
{
"name": "bone5",
"pivot": [0, 0, 0],
"name": "locator_top",
"parent": "lapras",
"pivot": [0, 45.2, -6],
"locators": {
"locator6": [0, 0, 0]
"top": [0, 45.2, -6]
}
}
]
@@ -7,468 +7,675 @@
"texture_width": 256,
"texture_height": 128,
"visible_bounds_width": 6,
"visible_bounds_height": 3.5,
"visible_bounds_offset": [0, 1.25, 0]
"visible_bounds_height": 4.5,
"visible_bounds_offset": [0, 1.75, 0]
},
"bones": [
{
"name": "metagross",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "metagross",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "metagross",
"pivot": [0, 35.5, 0],
"locators": {
"top": [0, 35.5, 0]
}
},
{
"name": "body",
"parent": "metagross",
"pivot": [0, 28, 0]
"pivot": [0, 26, 0]
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 25.5, 0],
"locators": {
"middle": [0, 25.5, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 25.5, -19],
"locators": {
"target": [0, 25.5, -19]
}
},
{
"name": "torso",
"parent": "body",
"pivot": [-0.5, 20, 0.5],
"pivot": [-0.5, 18, 0],
"cubes": [
{"origin": [-10, 18.5, -9.5], "size": [20, 5, 20], "uv": [0, 64]},
{"origin": [-15, 23.5, -14.5], "size": [30, 4, 30], "uv": [0, 30]},
{"origin": [-12, 27.25, -11.5], "size": [24, 6, 24], "uv": [0, 0]},
{"origin": [-9.5, 32.75, -9], "size": [19, 3, 19], "uv": [72, 2]}
{"origin": [-10.5, 16.5, -10.5], "size": [21, 5, 21], "uv": [0, 36]},
{"origin": [-16, 21.5, -16], "size": [32, 4, 32], "uv": [0, 0]},
{"origin": [-12, 25, -13], "size": [24, 6, 3], "uv": [156, 0]},
{"origin": [-13, 25, -3.5], "size": [26, 6, 7], "inflate": 0.01, "uv": [63, 36]},
{"origin": [-12, 25, 10], "size": [24, 6, 3], "uv": [156, 12]},
{"origin": [-9.5, 23.5, -10.5], "size": [19, 8, 21], "uv": [97, 0]},
{"origin": [-10.5, 31, -10.5], "size": [21, 3, 21], "inflate": 0.01, "uv": [0, 62]}
]
},
{
"name": "locator_face",
"parent": "torso",
"pivot": [0, 26.5, -16.5],
"locators": {
"face": [0, 26.5, -16.5]
}
},
{
"name": "locator_item_face",
"parent": "torso",
"pivot": [0, 27, -16.1],
"locators": {
"item_face": [0, 27, -16.1]
}
},
{
"name": "locator_mouth",
"parent": "torso",
"pivot": [0, 19.5, -10.5],
"locators": {
"mouth": [0, 19.5, -10.5],
"special": [0, 19.5, -10.5]
}
},
{
"name": "locator_item_hat",
"parent": "torso",
"pivot": [0, 34, 0],
"locators": {
"item_hat": [0, 34, 0]
}
},
{
"name": "locator_head",
"parent": "torso",
"pivot": [0, 34, -8],
"locators": {
"head": [0, 34, -8]
}
},
{
"name": "locator_seat_1",
"parent": "torso",
"pivot": [0, 37, 5],
"locators": {
"seat_1": [0, 37, 5]
}
},
{
"name": "eyes",
"parent": "torso",
"pivot": [-0.5, 20, 0.5]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-6.65, 29.15, -11.51],
"cubes": [
{"origin": [-9, 27.25, -11.51], "size": [5, 4, 0], "uv": [72, 4], "mirror": true}
]
},
{
"name": "eye_open_right",
"parent": "eye_right",
"pivot": [-6.65, 29.15, -11.51],
"cubes": [
{"origin": [-7.8, 28.05, -11.52], "size": [2, 2, 0], "uv": [86, 0], "mirror": true}
]
},
{
"name": "eye_shine_right",
"parent": "eye_open_right",
"pivot": [-7.3, 29.55, -11.525],
"cubes": [
{"origin": [-7.8, 29.05, -11.525], "size": [1, 1, 0], "uv": [88, 2], "mirror": true}
]
},
{
"name": "pupil_right",
"parent": "eye_open_right",
"pivot": [-6.8, 29.05, -11.53],
"cubes": [
{"origin": [-7.3, 28.55, -11.53], "size": [1, 1, 0], "uv": [86, 2], "mirror": true}
]
},
{
"name": "eye_closed_right",
"parent": "eye_right",
"pivot": [-6.8, 29.05, -11.42],
"cubes": [
{"origin": [-7.8, 28.55, -11.42], "size": [2, 1, 0], "uv": [86, 3], "mirror": true}
]
"pivot": [-0.5, 18, -1]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [6.65, 29.15, -11.51],
"pivot": [5.9, 27.15, -13.01],
"cubes": [
{"origin": [4, 27.25, -11.51], "size": [5, 4, 0], "uv": [72, 0]}
{"origin": [2.25, 25.25, -13.01], "size": [6, 4, 0], "uv": [1, 63]}
]
},
{
"name": "eye_open_left",
"parent": "eye_left",
"pivot": [6.65, 29.15, -11.51],
"pivot": [5.5, 27.4, -12.72],
"cubes": [
{"origin": [5.8, 28.05, -11.52], "size": [2, 2, 0], "uv": [82, 0]}
{"origin": [4.5, 26.4, -12.72], "size": [2, 2, 0], "inflate": 0.3, "uv": [1, 71]}
]
},
{
"name": "eye_shine_left",
"name": "eye_angry_left",
"parent": "eye_open_left",
"pivot": [7.3, 29.55, -11.525],
"pivot": [4.5, 28.3, -12.93],
"cubes": [
{"origin": [6.8, 29.05, -11.525], "size": [1, 1, 0], "uv": [84, 2]}
{"origin": [3.5, 27.3, -12.93], "size": [2, 2, 0], "inflate": 0.01, "uv": [1, 75]}
]
},
{
"name": "eye_sad_left",
"parent": "eye_open_left",
"pivot": [6.5, 28.3, -12.93],
"cubes": [
{"origin": [5.5, 27.3, -12.93], "size": [2, 2, 0], "inflate": 0.01, "uv": [1, 73]}
]
},
{
"name": "pupil_left",
"parent": "eye_open_left",
"pivot": [6.8, 29.05, -11.53],
"pivot": [5.5, 27.4, -13.03],
"cubes": [
{"origin": [6.3, 28.55, -11.53], "size": [1, 1, 0], "uv": [82, 2]}
{"origin": [5, 26.9, -13.03], "size": [1, 1, 0], "uv": [9, 71]}
]
},
{
"name": "locator_eye_left",
"parent": "pupil_left",
"pivot": [5.5, 27.4, -13],
"locators": {
"eye2": [5.5, 27.4, -13]
}
},
{
"name": "eye_shine_left",
"parent": "eye_open_left",
"pivot": [6.3, 28.4, -13.025],
"cubes": [
{"origin": [5.8, 27.9, -13.025], "size": [1, 1, 0], "uv": [11, 71]}
]
},
{
"name": "eye_closed_left",
"parent": "eye_left",
"pivot": [6.8, 29.05, -11.42],
"pivot": [5.3, 27.3, -12.92],
"cubes": [
{"origin": [5.8, 28.55, -11.42], "size": [2, 1, 0], "uv": [82, 3]}
{"origin": [4.3, 26.8, -12.92], "size": [2, 1, 0], "uv": [9, 73]}
]
},
{
"name": "eye_happy_left",
"parent": "eye_left",
"pivot": [5.3, 27.3, -12.92],
"cubes": [
{"origin": [3.8, 26.55, -12.92], "size": [3, 1, 0], "uv": [13, 71]},
{"origin": [4.8, 27.05, -12.92], "size": [1, 1, 0], "uv": [13, 73]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-5.25, 27.25, -13.01],
"cubes": [
{"origin": [-8.25, 25.25, -13.01], "size": [6, 4, 0], "uv": [1, 67], "mirror": true}
]
},
{
"name": "eye_open_right",
"parent": "eye_right",
"pivot": [-5.5, 27.4, -12.72],
"cubes": [
{"origin": [-6.5, 26.4, -12.72], "size": [2, 2, 0], "inflate": 0.3, "uv": [5, 71], "mirror": true}
]
},
{
"name": "eye_angry_right",
"parent": "eye_open_right",
"pivot": [-4.5, 28.3, -12.93],
"cubes": [
{"origin": [-5.5, 27.3, -12.93], "size": [2, 2, 0], "inflate": 0.01, "uv": [5, 75], "mirror": true}
]
},
{
"name": "eye_sad_right",
"parent": "eye_open_right",
"pivot": [-6.5, 28.3, -12.93],
"cubes": [
{"origin": [-7.5, 27.3, -12.93], "size": [2, 2, 0], "inflate": 0.01, "uv": [5, 73], "mirror": true}
]
},
{
"name": "pupil_right",
"parent": "eye_open_right",
"pivot": [-5.5, 27.4, -13.03],
"cubes": [
{"origin": [-6, 26.9, -13.03], "size": [1, 1, 0], "uv": [9, 72], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "pupil_right",
"pivot": [-5.5, 27.4, -13],
"locators": {
"eye1": [-5.5, 27.4, -13]
}
},
{
"name": "eye_shine_right",
"parent": "eye_open_right",
"pivot": [-6.3, 28.4, -13.025],
"cubes": [
{"origin": [-6.8, 27.9, -13.025], "size": [1, 1, 0], "uv": [11, 72], "mirror": true}
]
},
{
"name": "eye_closed_right",
"parent": "eye_right",
"pivot": [-5.3, 27.3, -12.92],
"cubes": [
{"origin": [-6.3, 26.8, -12.92], "size": [2, 1, 0], "uv": [9, 74], "mirror": true}
]
},
{
"name": "eye_happy_right",
"parent": "eye_right",
"pivot": [-5.3, 27.3, -12.92],
"cubes": [
{"origin": [-6.8, 26.55, -12.92], "size": [3, 1, 0], "uv": [13, 72], "mirror": true},
{"origin": [-5.8, 27.05, -12.92], "size": [1, 1, 0], "uv": [13, 74], "mirror": true}
]
},
{
"name": "mouth",
"parent": "torso",
"pivot": [0, 21.5, -9.41],
"pivot": [0, 19.5, -10.41],
"cubes": [
{"origin": [-8, 19.5, -9.41], "size": [16, 4, 0], "uv": [0, 89]}
{"origin": [-8, 17.5, -10.41], "size": [16, 4, 0], "uv": [64, 50]}
]
},
{
"name": "torso_spikes",
"parent": "torso",
"pivot": [-0.5, 23.5, 0.5],
"pivot": [-0.5, 21.5, 0],
"cubes": [
{"origin": [-13.9, 19, -1], "size": [3, 2, 3], "uv": [18, 40], "mirror": true},
{"origin": [-14.4, 21, -1.5], "size": [4, 3, 4], "uv": [14, 33], "mirror": true},
{"origin": [10.4, 21, -1.5], "size": [4, 3, 4], "uv": [0, 30]},
{"origin": [10.9, 19, -1], "size": [3, 2, 3], "uv": [0, 37]}
{"origin": [11.4, 19, -2], "size": [4, 3, 4], "uv": [97, 7]},
{"origin": [11.9, 16.5, -1.5], "size": [3, 3, 3], "inflate": -0.1, "uv": [16, 12]},
{"origin": [-15.4, 19, -2], "size": [4, 3, 4], "uv": [97, 0], "mirror": true},
{"origin": [-14.9, 16.5, -1.5], "size": [3, 3, 3], "inflate": -0.1, "uv": [16, 6], "mirror": true}
]
},
{
"name": "head_metal",
"parent": "torso",
"pivot": [-0.5, 30.5, -12.1],
"rotation": [-35, 0, 0]
},
{
"name": "head_metal_right",
"parent": "head_metal",
"pivot": [-9.5, 32.5, -13.35],
"rotation": [-2, 10, -60],
"cubes": [
{"origin": [-11, 22.5, -13.35], "size": [3, 10, 1], "uv": [0, 11], "mirror": true}
]
},
{
"name": "head_metal_right2",
"parent": "head_metal_right",
"pivot": [-9.5, 22.5, -13.35],
"rotation": [15, 0, 0],
"cubes": [
{"origin": [-11, 14.5, -13.35], "size": [3, 8, 1], "inflate": 0.01, "uv": [8, 9], "mirror": true}
]
},
{
"name": "head_metal_right3",
"parent": "head_metal_right2",
"pivot": [-9.5, 14.5, -13.35],
"rotation": [20, 0, 0],
"cubes": [
{"origin": [-11, 9.5, -13.35], "size": [3, 5, 1], "inflate": 0.02, "uv": [16, 6], "mirror": true},
{"origin": [-8, 9.5, -13.35], "size": [3, 2, 1], "uv": [16, 12], "mirror": true}
]
"pivot": [-0.5, 29.5, -12.15],
"rotation": [-40, 0, 0]
},
{
"name": "head_metal_left",
"parent": "head_metal",
"pivot": [9.5, 32.5, -13.35],
"rotation": [-2, -10, 60],
"pivot": [9.5, 31.5, -13.4],
"rotation": [-2, -10, 55],
"cubes": [
{"origin": [8, 22.5, -13.35], "size": [3, 10, 1], "uv": [0, 0]}
{"origin": [8, 21.5, -13.4], "size": [3, 10, 1], "pivot": [9.5, 21.5, -13.4], "rotation": [4.5, 0, 0], "uv": [8, 0]}
]
},
{
"name": "head_metal_left2",
"parent": "head_metal_left",
"pivot": [9.5, 22.5, -13.35],
"pivot": [9.5, 21.5, -13.4],
"rotation": [15, 0, 0],
"cubes": [
{"origin": [8, 14.5, -13.35], "size": [3, 8, 1], "inflate": 0.01, "uv": [8, 0]}
{"origin": [8, 13.5, -13.4], "size": [3, 8, 1], "inflate": 0.01, "uv": [8, 11]}
]
},
{
"name": "head_metal_left3",
"parent": "head_metal_left2",
"pivot": [9.5, 14.5, -13.35],
"pivot": [9.5, 13.5, -13.4],
"rotation": [20, 0, 0],
"cubes": [
{"origin": [8, 9.5, -13.35], "size": [3, 5, 1], "inflate": 0.02, "uv": [16, 0]},
{"origin": [5, 9.5, -13.35], "size": [3, 2, 1], "uv": [16, 15]}
{"origin": [8, 8.5, -13.4], "size": [3, 5, 1], "inflate": 0.02, "uv": [0, 20]},
{"origin": [5, 8.5, -13.4], "size": [6, 2, 1], "pivot": [11, 8.5, -12.9], "rotation": [0, 0, -15], "uv": [16, 0]}
]
},
{
"name": "leg_holes",
"parent": "torso",
"pivot": [-0.5, 2.5, 0]
},
{
"name": "leg_hole_right",
"parent": "leg_holes",
"pivot": [-0.5, 2.5, 0],
"name": "head_metal_right",
"parent": "head_metal",
"pivot": [-9.5, 31.5, -13.4],
"rotation": [-2, 10, -55],
"cubes": [
{"origin": [-9, 27.25, -8], "size": [0, 6, 17], "uv": [90, 19], "mirror": true},
{"origin": [-12, 27.25, -8], "size": [3, 6, 0], "uv": [90, 48], "mirror": true},
{"origin": [-12, 27.25, -2], "size": [3, 6, 0], "uv": [96, 48], "mirror": true},
{"origin": [-12, 27.25, 3], "size": [3, 6, 0], "uv": [102, 48], "mirror": true},
{"origin": [-12, 27.25, 9], "size": [3, 6, 0], "uv": [108, 48], "mirror": true}
{"origin": [-11, 21.5, -13.4], "size": [3, 10, 1], "pivot": [-9.5, 21.5, -13.4], "rotation": [4.5, 0, 0], "uv": [0, 0], "mirror": true}
]
},
{
"name": "leg_hole_left",
"parent": "leg_holes",
"pivot": [0.5, 2.5, 0],
"name": "head_metal_right2",
"parent": "head_metal_right",
"pivot": [-9.5, 21.5, -13.4],
"rotation": [15, 0, 0],
"cubes": [
{"origin": [9, 27.25, -8], "size": [0, 6, 17], "uv": [90, 13]},
{"origin": [9, 27.25, -8], "size": [3, 6, 0], "uv": [90, 42]},
{"origin": [9, 27.25, -2], "size": [3, 6, 0], "uv": [96, 42]},
{"origin": [9, 27.25, 3], "size": [3, 6, 0], "uv": [102, 42]},
{"origin": [9, 27.25, 9], "size": [3, 6, 0], "uv": [108, 42]}
{"origin": [-11, 13.5, -13.4], "size": [3, 8, 1], "inflate": 0.01, "uv": [0, 11], "mirror": true}
]
},
{
"name": "leg_front_right",
"name": "head_metal_right3",
"parent": "head_metal_right2",
"pivot": [-9.5, 13.5, -13.4],
"rotation": [20, 0, 0],
"cubes": [
{"origin": [-11, 8.5, -13.4], "size": [3, 5, 1], "inflate": 0.02, "uv": [8, 20], "mirror": true},
{"origin": [-11, 8.5, -13.4], "size": [6, 2, 1], "pivot": [-11, 8.5, -12.9], "rotation": [0, 0, 15], "uv": [16, 3], "mirror": true}
]
},
{
"name": "legs",
"parent": "body",
"pivot": [-10.85, 29.5, -5.05],
"cubes": [
{"origin": [-12.85, 27.5, -7], "size": [4, 4, 4], "inflate": 0.01, "uv": [0, 101], "mirror": true},
{"origin": [-22.85, 28.5, -6], "size": [11, 2, 2], "uv": [12, 101], "mirror": true},
{"origin": [-24.29905, 27.94362, -6.5], "size": [3, 3, 3], "pivot": [-24.29905, 27.94362, -5], "rotation": [0, 0, -2.5], "uv": [36, 103], "mirror": true}
]
},
{
"name": "leg_front_right2",
"parent": "leg_front_right",
"pivot": [-22.79905, 29.49362, -5],
"rotation": [0, 0, 2.5],
"cubes": [
{"origin": [-27.57171, 16.5824, -6.5], "size": [6, 3, 3], "pivot": [-22.27171, 18.1324, -4.5], "rotation": [0, 0, 62.5], "uv": [193, 79], "mirror": true},
{"origin": [-27.77171, 6.1324, -9], "size": [8, 13, 8], "uv": [153, 93], "mirror": true},
{"origin": [-24.17171, 33.1824, -7], "size": [2, 4, 4], "pivot": [-22.17171, 28.7324, -5], "rotation": [0, 0, -2.5], "uv": [199, 106], "mirror": true},
{"origin": [-25.17171, 28.6824, -7], "size": [3, 5, 4], "inflate": 0.01, "pivot": [-22.17171, 28.7324, -5], "rotation": [0, 0, -2.5], "uv": [197, 97], "mirror": true},
{"origin": [-29.17171, 24.6324, -7], "size": [5, 7, 4], "inflate": 0.02, "pivot": [-29.17171, 24.6324, -5], "rotation": [0, 0, 30], "uv": [193, 86], "mirror": true},
{"origin": [-28.77171, 16.6324, -6.5], "size": [6, 8, 3], "inflate": 0.01, "pivot": [-28.27171, 15.6324, -5], "rotation": [0, 0, -2.5], "uv": [193, 114], "mirror": true},
{"origin": [-29.27171, 5.6324, -7], "size": [2, 11, 4], "pivot": [-29.27171, 6.1324, -4], "rotation": [0, 0, -2.5], "uv": [185, 99], "mirror": true}
]
},
{
"name": "hand_front_right",
"parent": "leg_front_right2",
"pivot": [-29.27171, 6.1324, -4.5],
"rotation": [0, 0, -2.5],
"cubes": [
{"origin": [-29.27171, 3.1324, -10.5], "size": [11, 3, 11], "inflate": 0.01, "uv": [160, 114], "mirror": true}
]
},
{
"name": "finger_front_right1",
"parent": "hand_front_right",
"pivot": [-27.77171, 3.1324, -4.5],
"cubes": [
{"origin": [-27.77171, -0.3676, -6.5], "size": [0, 4, 4], "uv": [153, 89], "mirror": true}
]
},
{
"name": "bone",
"parent": "finger_front_right1",
"pivot": [-27.77171, 3.1324, -4.5]
},
{
"name": "finger_front_right2",
"parent": "hand_front_right",
"pivot": [-21.32171, 3.1324, -8.65],
"rotation": [0, -120, 0],
"cubes": [
{"origin": [-21.39671, -0.3676, -10.65], "size": [0, 4, 4], "uv": [153, 93], "mirror": true}
]
},
{
"name": "finger_front_right3",
"parent": "hand_front_right",
"pivot": [-21.32171, 3.1324, -1.25],
"rotation": [0, 120, 0],
"cubes": [
{"origin": [-21.39671, -0.3676, -3.25], "size": [0, 4, 4], "uv": [177, 93], "mirror": true}
]
"pivot": [0, 27, 0]
},
{
"name": "leg_front_left",
"parent": "body",
"pivot": [10.85, 29.5, -5.05],
"parent": "legs",
"pivot": [10.85, 27, -6.8],
"cubes": [
{"origin": [8.85, 27.5, -7], "size": [4, 4, 4], "inflate": 0.01, "uv": [0, 109]},
{"origin": [11.85, 28.5, -6], "size": [11, 2, 2], "uv": [12, 109]},
{"origin": [21.29905, 27.94362, -6.5], "size": [3, 3, 3], "pivot": [24.29905, 27.94362, -5], "rotation": [0, 0, 2.5], "uv": [48, 103]}
{"origin": [8.35, 23.75, -9.75], "size": [5, 6, 6], "inflate": 0.01, "uv": [22, 86]},
{"origin": [11.85, 25.25, -8.25], "size": [13, 3, 3], "uv": [32, 110]},
{"origin": [21.75, 24.75, -8.75], "size": [4, 4, 4], "pivot": [24.75, 24.75, -7.25], "rotation": [0, 0, 2.5], "uv": [60, 86]}
]
},
{
"name": "leg_front_left2",
"parent": "leg_front_left",
"pivot": [22.79905, 29.49362, -5],
"pivot": [23.7981, 27.53724, -6.75],
"rotation": [0, 0, -2.5],
"cubes": [
{"origin": [21.57171, 16.5824, -6.5], "size": [6, 3, 3], "pivot": [22.27171, 18.1324, -4.5], "rotation": [0, 0, -62.5], "uv": [95, 76]},
{"origin": [19.77171, 6.1324, -9], "size": [8, 13, 8], "uv": [73, 93]},
{"origin": [22.17171, 33.1824, -7], "size": [2, 4, 4], "pivot": [22.17171, 28.7324, -5], "rotation": [0, 0, 2.5], "uv": [73, 74]},
{"origin": [22.17171, 28.6824, -7], "size": [3, 5, 4], "inflate": 0.01, "pivot": [22.17171, 28.7324, -5], "rotation": [0, 0, 2.5], "uv": [81, 69]},
{"origin": [24.17171, 24.6324, -7], "size": [5, 7, 4], "inflate": 0.02, "pivot": [29.17171, 24.6324, -5], "rotation": [0, 0, -30], "uv": [95, 65]},
{"origin": [22.77171, 16.6324, -6.5], "size": [6, 8, 3], "inflate": 0.01, "pivot": [28.27171, 15.6324, -5], "rotation": [0, 0, 2.5], "uv": [93, 82]},
{"origin": [27.27171, 5.6324, -7], "size": [2, 11, 4], "pivot": [29.27171, 6.1324, -4], "rotation": [0, 0, 2.5], "uv": [81, 78]}
{"origin": [23.2, 30.25, -9.25], "size": [2, 5, 5], "pivot": [21.2, 25.75, -7.25], "rotation": [0, 0, -2.5], "uv": [209, 90]},
{"origin": [23.2, 25.75, -9.25], "size": [4, 5, 5], "inflate": 0.01, "pivot": [23.2, 25.75, -7.25], "rotation": [0, 0, -2.5], "uv": [196, 95]},
{"origin": [24.75, 14.75, -8.75], "size": [6, 8, 4], "inflate": 0.01, "pivot": [29.25, 13.75, -7.25], "rotation": [0, 0, 2.5], "uv": [224, 93]},
{"origin": [26.2, 22.75, -9.25], "size": [5, 7, 5], "inflate": 0.02, "pivot": [31.2, 22.75, -7.25], "rotation": [0, 0, -35], "uv": [209, 100]},
{"origin": [20.75, 6.15, -11.25], "size": [9, 11, 9], "uv": [220, 105]},
{"origin": [22.5, 14.7, -8.75], "size": [8, 3, 4], "pivot": [23.25, 16.2, -6.25], "rotation": [0, 0, -62.5], "uv": [185, 105]},
{"origin": [28.75, 5.7, -9.25], "size": [3, 10, 5], "pivot": [30.75, 6.2, -6.25], "rotation": [0, 0, 2.5], "uv": [174, 107]}
]
},
{
"name": "hand_front_left",
"parent": "leg_front_left2",
"pivot": [29.27171, 6.1324, -4.5],
"pivot": [30.25, 6.17602, -6.25],
"rotation": [0, 0, 2.5],
"cubes": [
{"origin": [18.27171, 3.1324, -10.5], "size": [11, 3, 11], "inflate": 0.01, "uv": [73, 114]}
{"origin": [19.25, 3.2, -13.25], "size": [13, 3, 13], "inflate": 0.01, "uv": [181, 112]}
]
},
{
"name": "locator_hand_secondary1",
"parent": "hand_front_left",
"pivot": [25.75, 4.7, -6.75],
"rotation": [90, 0, 0],
"locators": {
"hand_secondary1": [25.75, 4.7, -6.75]
}
},
{
"name": "finger_front_left1",
"parent": "hand_front_left",
"pivot": [27.77171, 3.1324, -4.5],
"pivot": [29.75, 3.25, -6.75],
"cubes": [
{"origin": [27.77171, -0.3676, -6.5], "size": [0, 4, 4], "uv": [73, 89]}
{"origin": [30.25, -0.25, -8.75], "size": [0, 4, 4], "uv": [227, 29]}
]
},
{
"name": "finger_front_left2",
"parent": "hand_front_left",
"pivot": [21.32171, 3.1324, -8.65],
"rotation": [0, 120, 0],
"pivot": [23.25, 3.25, -11.15],
"rotation": [0, 27.5, 0]
},
{
"name": "finger_front_left2_rotaiton",
"parent": "finger_front_left2",
"pivot": [23.25, 3.25, -11.15],
"cubes": [
{"origin": [21.39671, -0.3676, -10.65], "size": [0, 4, 4], "uv": [73, 93]}
{"origin": [21.25, -0.25, -11.15], "size": [4, 4, 0], "uv": [227, 39]}
]
},
{
"name": "finger_front_left3",
"parent": "hand_front_left",
"pivot": [21.32171, 3.1324, -1.25],
"rotation": [0, -120, 0],
"cubes": [
{"origin": [21.39671, -0.3676, -3.25], "size": [0, 4, 4], "uv": [97, 93]}
]
"pivot": [23.25, 3.25, -2.65],
"rotation": [0, -27.5, 0]
},
{
"name": "leg_back_right",
"parent": "body",
"pivot": [-10.85, 29.5, 5.95],
"name": "finger_front_left3_rotation",
"parent": "finger_front_left3",
"pivot": [23.25, 3.25, -2.65],
"cubes": [
{"origin": [-12.85, 27.5, 4], "size": [4, 4, 4], "inflate": 0.01, "uv": [0, 93], "mirror": true},
{"origin": [-22.85, 28.5, 5], "size": [11, 2, 2], "uv": [12, 93], "mirror": true},
{"origin": [-24.29905, 27.94362, 4.5], "size": [3, 3, 3], "pivot": [-24.29905, 27.94362, 6], "rotation": [0, 0, -2.5], "uv": [36, 110], "mirror": true}
]
},
{
"name": "leg_back_right2",
"parent": "leg_back_right",
"pivot": [-22.79905, 29.49362, 6],
"rotation": [0, 0, 2.5],
"cubes": [
{"origin": [-27.57171, 16.5824, 4.5], "size": [6, 3, 3], "pivot": [-22.27171, 18.1324, 5.5], "rotation": [0, 0, 62.5], "uv": [188, 0], "mirror": true},
{"origin": [-27.77171, 6.1324, 2], "size": [8, 13, 8], "uv": [148, 14], "mirror": true},
{"origin": [-24.17171, 33.1824, 4], "size": [2, 4, 4], "pivot": [-22.17171, 28.7324, 6], "rotation": [0, 0, -2.5], "uv": [194, 27], "mirror": true},
{"origin": [-25.17171, 28.6824, 4], "size": [3, 5, 4], "inflate": 0.01, "pivot": [-22.17171, 28.7324, 6], "rotation": [0, 0, -2.5], "uv": [192, 18], "mirror": true},
{"origin": [-29.17171, 24.6324, 4], "size": [5, 7, 4], "inflate": 0.02, "pivot": [-29.17171, 24.6324, 6], "rotation": [0, 0, 30], "uv": [188, 7], "mirror": true},
{"origin": [-28.77171, 16.6324, 4.5], "size": [6, 8, 3], "inflate": 0.01, "pivot": [-28.27171, 15.6324, 6], "rotation": [0, 0, -2.5], "uv": [188, 35], "mirror": true},
{"origin": [-29.27171, 5.6324, 4], "size": [2, 11, 4], "pivot": [-29.27171, 6.1324, 5], "rotation": [0, 0, -2.5], "uv": [180, 20], "mirror": true}
]
},
{
"name": "hand_back_right",
"parent": "leg_back_right2",
"pivot": [-29.27171, 6.1324, 5.5],
"rotation": [0, 0, -2.5],
"cubes": [
{"origin": [-29.27171, 3.1324, 0.5], "size": [11, 3, 11], "inflate": 0.01, "uv": [155, 35], "mirror": true}
]
},
{
"name": "finger_back_right",
"parent": "hand_back_right",
"pivot": [-27.77171, 3.1324, 5.5],
"cubes": [
{"origin": [-27.77171, -0.3676, 3.5], "size": [0, 4, 4], "uv": [148, 10], "mirror": true}
]
},
{
"name": "finger_back_right2",
"parent": "hand_back_right",
"pivot": [-21.32171, 3.1324, 9.65],
"rotation": [0, 120, 0],
"cubes": [
{"origin": [-21.39671, -0.3676, 7.65], "size": [0, 4, 4], "uv": [148, 14], "mirror": true}
]
},
{
"name": "finger_back_right3",
"parent": "hand_back_right",
"pivot": [-21.32171, 3.1324, 2.25],
"rotation": [0, -120, 0],
"cubes": [
{"origin": [-21.39671, -0.3676, 0.25], "size": [0, 4, 4], "uv": [172, 14], "mirror": true}
{"origin": [21.25, -0.25, -2.65], "size": [4, 4, 0], "uv": [227, 45]}
]
},
{
"name": "leg_back_left",
"parent": "body",
"pivot": [10.85, 29.5, 5.95],
"parent": "legs",
"pivot": [10.85, 27, 6.7],
"cubes": [
{"origin": [8.85, 27.5, 4], "size": [4, 4, 4], "inflate": 0.01, "uv": [0, 117]},
{"origin": [11.85, 28.5, 5], "size": [11, 2, 2], "uv": [12, 117]},
{"origin": [21.29905, 27.94362, 4.5], "size": [3, 3, 3], "pivot": [24.29905, 27.94362, 6], "rotation": [0, 0, 2.5], "uv": [48, 110]}
{"origin": [8.35, 23.75, 3.75], "size": [5, 6, 6], "inflate": 0.01, "uv": [22, 98]},
{"origin": [11.85, 25.25, 5.25], "size": [13, 3, 3], "uv": [32, 116]},
{"origin": [21.75, 24.75, 4.75], "size": [4, 4, 4], "pivot": [24.75, 24.75, 6.25], "rotation": [0, 0, 2.5], "uv": [60, 94]}
]
},
{
"name": "leg_back_left2",
"parent": "leg_back_left",
"pivot": [22.79905, 29.49362, 6],
"pivot": [23.7981, 27.53724, 6.75],
"rotation": [0, 0, -2.5],
"cubes": [
{"origin": [21.57171, 16.5824, 4.5], "size": [6, 3, 3], "pivot": [22.27171, 18.1324, 6.5], "rotation": [0, 0, -62.5], "uv": [139, 76]},
{"origin": [19.77171, 6.1324, 2], "size": [8, 13, 8], "uv": [117, 93]},
{"origin": [22.17171, 33.1824, 4], "size": [2, 4, 4], "pivot": [22.17171, 28.7324, 6], "rotation": [0, 0, 2.5], "uv": [117, 74]},
{"origin": [22.17171, 28.6824, 4], "size": [3, 5, 4], "inflate": 0.01, "pivot": [22.17171, 28.7324, 6], "rotation": [0, 0, 2.5], "uv": [125, 69]},
{"origin": [24.17171, 24.6324, 4], "size": [5, 7, 4], "inflate": 0.02, "pivot": [29.17171, 24.6324, 6], "rotation": [0, 0, -30], "uv": [139, 65]},
{"origin": [22.77171, 16.6324, 4.5], "size": [6, 8, 3], "inflate": 0.01, "pivot": [28.27171, 15.6324, 6], "rotation": [0, 0, 2.5], "uv": [137, 82]},
{"origin": [27.27171, 5.6324, 4], "size": [2, 11, 4], "pivot": [29.27171, 6.1324, 7], "rotation": [0, 0, 2.5], "uv": [125, 78]}
{"origin": [23.2, 30.25, 4.25], "size": [2, 5, 5], "pivot": [21.2, 25.75, 6.25], "rotation": [0, 0, -2.5], "uv": [209, 51]},
{"origin": [23.2, 25.75, 4.25], "size": [4, 5, 5], "inflate": 0.01, "pivot": [23.2, 25.75, 6.25], "rotation": [0, 0, -2.5], "uv": [196, 56]},
{"origin": [24.75, 14.75, 4.75], "size": [6, 8, 4], "inflate": 0.01, "pivot": [29.25, 13.75, 6.25], "rotation": [0, 0, 2.5], "uv": [224, 54]},
{"origin": [26.2, 22.75, 4.25], "size": [5, 7, 5], "inflate": 0.02, "pivot": [31.2, 22.75, 6.25], "rotation": [0, 0, -35], "uv": [209, 61]},
{"origin": [20.75, 6.15, 2.25], "size": [9, 11, 9], "uv": [220, 66]},
{"origin": [22.5, 14.7, 4.75], "size": [8, 3, 4], "pivot": [23.25, 16.2, 7.25], "rotation": [0, 0, -62.5], "uv": [185, 66]},
{"origin": [28.75, 5.7, 4.25], "size": [3, 10, 5], "pivot": [30.75, 6.2, 7.25], "rotation": [0, 0, 2.5], "uv": [174, 68]}
]
},
{
"name": "hand_back_left",
"parent": "leg_back_left2",
"pivot": [29.27171, 6.1324, 6.5],
"pivot": [30.25, 6.17602, 7.25],
"rotation": [0, 0, 2.5],
"cubes": [
{"origin": [18.27171, 3.1324, 0.5], "size": [11, 3, 11], "inflate": 0.01, "uv": [117, 114]}
{"origin": [19.25, 3.2, 0.25], "size": [13, 3, 13], "inflate": 0.01, "uv": [181, 73]}
]
},
{
"name": "finger_back_left",
"name": "locator_hand_secondary2",
"parent": "hand_back_left",
"pivot": [27.77171, 3.1324, 6.5],
"pivot": [25.75, 4.7, 6.75],
"rotation": [90, 0, 0],
"locators": {
"hand_secondary2": [25.75, 4.7, 6.75]
}
},
{
"name": "finger_back_left1",
"parent": "hand_back_left",
"pivot": [29.75, 3.25, 6.75],
"cubes": [
{"origin": [27.77171, -0.3676, 4.5], "size": [0, 4, 4], "uv": [117, 89]}
{"origin": [30.25, -0.25, 4.75], "size": [0, 4, 4], "uv": [246, 29]}
]
},
{
"name": "finger_back_left2",
"parent": "hand_back_left",
"pivot": [21.32171, 3.1324, 2.35],
"rotation": [0, 120, 0],
"pivot": [23.25, 3.25, 2.35],
"rotation": [0, 27.5, 0]
},
{
"name": "finger_back_left2_rotaiton",
"parent": "finger_back_left2",
"pivot": [23.25, 3.25, 2.35],
"cubes": [
{"origin": [21.39671, -0.3676, 0.35], "size": [0, 4, 4], "uv": [117, 93]}
{"origin": [21.25, -0.25, 2.35], "size": [4, 4, 0], "uv": [246, 39]}
]
},
{
"name": "finger_back_left3",
"parent": "hand_back_left",
"pivot": [21.32171, 3.1324, 9.75],
"rotation": [0, -120, 0],
"pivot": [23.25, 3.25, 10.85],
"rotation": [0, -27.5, 0]
},
{
"name": "finger_back_left3_rotation",
"parent": "finger_back_left3",
"pivot": [23.25, 3.25, 10.85],
"cubes": [
{"origin": [21.39671, -0.3676, 7.75], "size": [0, 4, 4], "uv": [141, 93]}
{"origin": [21.25, -0.25, 10.85], "size": [4, 4, 0], "uv": [246, 45]}
]
},
{
"name": "leg_front_right",
"parent": "legs",
"pivot": [-10.85, 27, -6.8],
"cubes": [
{"origin": [-13.35, 23.75, -9.75], "size": [5, 6, 6], "inflate": 0.01, "uv": [0, 86], "mirror": true},
{"origin": [-24.85, 25.25, -8.25], "size": [13, 3, 3], "uv": [0, 110], "mirror": true},
{"origin": [-25.75, 24.75, -8.75], "size": [4, 4, 4], "pivot": [-24.75, 24.75, -7.25], "rotation": [0, 0, -2.5], "uv": [44, 86], "mirror": true}
]
},
{
"name": "leg_front_right2",
"parent": "leg_front_right",
"pivot": [-23.7981, 27.53724, -6.75],
"rotation": [0, 0, 2.5],
"cubes": [
{"origin": [-25.2, 30.25, -9.25], "size": [2, 5, 5], "pivot": [-21.2, 25.75, -7.25], "rotation": [0, 0, 2.5], "uv": [126, 90], "mirror": true},
{"origin": [-27.2, 25.75, -9.25], "size": [4, 5, 5], "inflate": 0.01, "pivot": [-23.2, 25.75, -7.25], "rotation": [0, 0, 2.5], "uv": [113, 95], "mirror": true},
{"origin": [-30.75, 14.75, -8.75], "size": [6, 8, 4], "inflate": 0.01, "pivot": [-29.25, 13.75, -7.25], "rotation": [0, 0, -2.5], "uv": [141, 93], "mirror": true},
{"origin": [-31.2, 22.75, -9.25], "size": [5, 7, 5], "inflate": 0.02, "pivot": [-31.2, 22.75, -7.25], "rotation": [0, 0, 35], "uv": [126, 100], "mirror": true},
{"origin": [-29.75, 6.15, -11.25], "size": [9, 11, 9], "uv": [137, 105], "mirror": true},
{"origin": [-30.5, 14.7, -8.75], "size": [8, 3, 4], "pivot": [-23.25, 16.2, -6.25], "rotation": [0, 0, 62.5], "uv": [102, 105], "mirror": true},
{"origin": [-31.75, 5.7, -9.25], "size": [3, 10, 5], "pivot": [-30.75, 6.2, -6.25], "rotation": [0, 0, -2.5], "uv": [91, 107], "mirror": true}
]
},
{
"name": "hand_front_right",
"parent": "leg_front_right2",
"pivot": [-30.25, 6.17602, -6.25],
"rotation": [0, 0, -2.5],
"cubes": [
{"origin": [-32.25, 3.2, -13.25], "size": [13, 3, 13], "inflate": 0.01, "uv": [98, 112], "mirror": true}
]
},
{
"name": "locator_hand_primary1",
"parent": "hand_front_right",
"pivot": [-25.75, 4.7, -6.75],
"rotation": [90, 0, 0],
"locators": {
"hand_primary": [-25.75, 4.7, -6.75],
"physical": [-25.75, 4.7, -6.75]
}
},
{
"name": "locator_item",
"parent": "hand_front_right",
"pivot": [-25.75, 3.2, -6.75],
"rotation": [90, 0, 0],
"locators": {
"item": [-25.75, 3.2, -6.75]
}
},
{
"name": "finger_front_right1",
"parent": "hand_front_right",
"pivot": [-29.75, 3.25, -6.75],
"cubes": [
{"origin": [-30.25, -0.25, -8.75], "size": [0, 4, 4], "uv": [217, 29], "mirror": true}
]
},
{
"name": "finger_front_right2",
"parent": "hand_front_right",
"pivot": [-23.25, 3.25, -11.15],
"rotation": [0, -27.5, 0]
},
{
"name": "finger_front_right2_rotation",
"parent": "finger_front_right2",
"pivot": [-23.25, 3.25, -11.15],
"cubes": [
{"origin": [-25.25, -0.25, -11.15], "size": [4, 4, 0], "uv": [217, 39], "mirror": true}
]
},
{
"name": "finger_front_right3",
"parent": "hand_front_right",
"pivot": [-23.25, 3.25, -2.65],
"rotation": [0, 27.5, 0]
},
{
"name": "finger_front_right3_rotation",
"parent": "finger_front_right3",
"pivot": [-23.25, 3.25, -2.65],
"cubes": [
{"origin": [-25.25, -0.25, -2.65], "size": [4, 4, 0], "uv": [217, 45], "mirror": true}
]
},
{
"name": "leg_back_right",
"parent": "legs",
"pivot": [-10.85, 27, 6.7],
"cubes": [
{"origin": [-13.35, 23.75, 3.75], "size": [5, 6, 6], "inflate": 0.01, "uv": [0, 98], "mirror": true},
{"origin": [-24.85, 25.25, 5.25], "size": [13, 3, 3], "uv": [0, 116], "mirror": true},
{"origin": [-25.75, 24.75, 4.75], "size": [4, 4, 4], "pivot": [-24.75, 24.75, 6.25], "rotation": [0, 0, -2.5], "uv": [44, 94], "mirror": true}
]
},
{
"name": "leg_back_right2",
"parent": "leg_back_right",
"pivot": [-23.7981, 27.53724, 6.75],
"rotation": [0, 0, 2.5],
"cubes": [
{"origin": [-25.2, 30.25, 4.25], "size": [2, 5, 5], "pivot": [-21.2, 25.75, 6.25], "rotation": [0, 0, 2.5], "uv": [126, 51], "mirror": true},
{"origin": [-27.2, 25.75, 4.25], "size": [4, 5, 5], "inflate": 0.01, "pivot": [-23.2, 25.75, 6.25], "rotation": [0, 0, 2.5], "uv": [113, 56], "mirror": true},
{"origin": [-30.75, 14.75, 4.75], "size": [6, 8, 4], "inflate": 0.01, "pivot": [-29.25, 13.75, 6.25], "rotation": [0, 0, -2.5], "uv": [141, 54], "mirror": true},
{"origin": [-31.2, 22.75, 4.25], "size": [5, 7, 5], "inflate": 0.02, "pivot": [-31.2, 22.75, 6.25], "rotation": [0, 0, 35], "uv": [126, 61], "mirror": true},
{"origin": [-29.75, 6.15, 2.25], "size": [9, 11, 9], "uv": [137, 66], "mirror": true},
{"origin": [-30.5, 14.7, 4.75], "size": [8, 3, 4], "pivot": [-23.25, 16.2, 7.25], "rotation": [0, 0, 62.5], "uv": [102, 66], "mirror": true},
{"origin": [-31.75, 5.7, 4.25], "size": [3, 10, 5], "pivot": [-30.75, 6.2, 7.25], "rotation": [0, 0, -2.5], "uv": [91, 68], "mirror": true}
]
},
{
"name": "hand_back_right",
"parent": "leg_back_right2",
"pivot": [-30.25, 6.17602, 7.25],
"rotation": [0, 0, -2.5],
"cubes": [
{"origin": [-32.25, 3.2, 0.25], "size": [13, 3, 13], "inflate": 0.01, "uv": [98, 73], "mirror": true}
]
},
{
"name": "locator_hand_primary2",
"parent": "hand_back_right",
"pivot": [-25.75, 4.7, 6.75],
"rotation": [90, 0, 0],
"locators": {
"hand_primary2": [-25.75, 4.7, 6.75]
}
},
{
"name": "finger_back_right1",
"parent": "hand_back_right",
"pivot": [-29.75, 3.25, 6.75],
"cubes": [
{"origin": [-30.25, -0.25, 4.75], "size": [0, 4, 4], "uv": [237, 29], "mirror": true}
]
},
{
"name": "finger_back_right2",
"parent": "hand_back_right",
"pivot": [-23.25, 3.25, 2.35],
"rotation": [0, -27.5, 0]
},
{
"name": "finger_back_right2_rotaiton",
"parent": "finger_back_right2",
"pivot": [-23.25, 3.25, 2.35],
"cubes": [
{"origin": [-25.25, -0.25, 2.35], "size": [4, 4, 0], "uv": [237, 39], "mirror": true}
]
},
{
"name": "finger_back_right3",
"parent": "hand_back_right",
"pivot": [-23.25, 3.25, 10.85],
"rotation": [0, 27.5, 0]
},
{
"name": "finger_back_right3_rotation",
"parent": "finger_back_right3",
"pivot": [-23.25, 3.25, 10.85],
"cubes": [
{"origin": [-25.25, -0.25, 10.85], "size": [4, 4, 0], "uv": [237, 45], "mirror": true}
]
}
]
@@ -18,6 +18,22 @@
"collapse": [0, 0.25, 0]
}
},
{
"name": "locator_root",
"parent": "magnezone",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "magnezone",
"pivot": [0, 27.5, 0],
"locators": {
"top": [0, 27.5, 0]
}
},
{
"name": "body",
"parent": "magnezone",
@@ -34,6 +50,63 @@
"sparks3": [-1.5, 5.5, -11.5]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 10, -18],
"locators": {
"target": [0, 10, -18]
}
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 10, 0],
"locators": {
"middle": [0, 10, 0]
}
},
{
"name": "locator_head",
"parent": "body",
"pivot": [0, 15.5, -9.5],
"locators": {
"head": [0, 15.5, -9.5]
}
},
{
"name": "locator_seat_1",
"parent": "body",
"pivot": [0, 21, 6],
"locators": {
"seat1": [0, 21, 6]
}
},
{
"name": "locator_face",
"parent": "body",
"pivot": [0, 10, -15],
"locators": {
"face": [0, 10, -15],
"physical": [0, 10, -15]
}
},
{
"name": "locator_item_face",
"parent": "body",
"pivot": [0, 13.5, -11.5],
"locators": {
"item_face": [0, 13.5, -11.5]
}
},
{
"name": "locator_tera_hat",
"parent": "body",
"pivot": [0, 18, 0],
"locators": {
"tera_hat": [0, 18, 0]
}
},
{
"name": "red_light",
"parent": "body",
@@ -43,6 +116,15 @@
{"origin": [-1.5, 12, -11.52], "size": [3, 3, 0], "uv": [0, 12]}
]
},
{
"name": "locator_eye_center",
"parent": "red_light",
"pivot": [0, 13.5, -11.5],
"locators": {
"eye1": [0, 13.5, -11.5],
"special3": [0, 13.5, -11.5]
}
},
{
"name": "antenna",
"parent": "body",
@@ -53,6 +135,14 @@
{"origin": [-1.5, 24.5, -1.5], "size": [3, 3, 3], "uv": [70, 17]}
]
},
{
"name": "locator_item_hat",
"parent": "antenna",
"pivot": [0, 27.5, 0],
"locators": {
"item_hat": [0, 27.5, 0]
}
},
{
"name": "body_left",
"parent": "body",
@@ -70,6 +160,14 @@
{"origin": [13.5, 10.1, -4.51], "size": [4, 4, 0], "uv": [0, 0]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [15.5, 12.1, -4.5],
"locators": {
"eye3": [15.5, 12.1, -4.5]
}
},
{
"name": "pupil_left",
"parent": "eye_left",
@@ -86,6 +184,23 @@
{"origin": [14, 11.6, -4.42], "size": [3, 1, 0], "uv": [8, 0]}
]
},
{
"name": "pupil_happy_left",
"parent": "eye_left",
"pivot": [15.5, 12.1, -4.42],
"cubes": [
{"origin": [14, 11.1, -4.42], "size": [3, 2, 0], "uv": [14, 0]}
]
},
{
"name": "pupil_recoil_left",
"parent": "eye_left",
"pivot": [15.5, 12.1, -4.42],
"rotation": [0, 0, -45],
"cubes": [
{"origin": [14, 10.6, -4.42], "size": [3, 3, 0], "uv": [8, 4]}
]
},
{
"name": "magnet_left",
"parent": "body_left",
@@ -97,9 +212,26 @@
"parent": "magnet_left",
"pivot": [13.5, 8, -5],
"cubes": [
{"origin": [8.5, 6.5, -9], "size": [10, 3, 4], "uv": [0, 82]},
{"origin": [8.5, 6.5, -19], "size": [4, 3, 10], "uv": [0, 89]},
{"origin": [14.5, 6.5, -19], "size": [4, 3, 10], "uv": [0, 102]}
{"origin": [8.5, 6.5, -9], "size": [10, 3, 4], "inflate": 0.02, "uv": [0, 82]},
{"origin": [8.5, 6.5, -19], "size": [4, 3, 10], "inflate": 0.01, "uv": [0, 89]},
{"origin": [14.5, 6.5, -19], "size": [4, 3, 10], "inflate": 0.01, "uv": [0, 102]}
]
},
{
"name": "locator_cannon_left",
"parent": "magnet_left_rotation",
"pivot": [13.5, 8, -19],
"locators": {
"cannon2": [13.5, 8, -19],
"special2": [13.5, 8, -19]
}
},
{
"name": "magnet_lights_left",
"parent": "magnet_left_rotation",
"pivot": [13.5, 8, -18.92],
"cubes": [
{"origin": [8.5, 6.5, -18.92], "size": [10, 3, 0], "uv": [18, 96]}
]
},
{
@@ -135,6 +267,14 @@
{"origin": [-17.5, 10.1, -4.51], "size": [4, 4, 0], "uv": [0, 4], "mirror": true}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-15.5, 12.1, -4.5],
"locators": {
"eye2": [-15.5, 12.1, -4.5]
}
},
{
"name": "pupil_right",
"parent": "eye_right",
@@ -151,6 +291,23 @@
{"origin": [-17, 11.6, -4.42], "size": [3, 1, 0], "uv": [8, 1], "mirror": true}
]
},
{
"name": "pupil_happy_right",
"parent": "eye_right",
"pivot": [-15.5, 12.1, -4.42],
"cubes": [
{"origin": [-17, 11.1, -4.42], "size": [3, 2, 0], "uv": [10, 2], "mirror": true}
]
},
{
"name": "pupil_recoil_right",
"parent": "eye_right",
"pivot": [-15.5, 12.1, -4.42],
"rotation": [0, 0, 45],
"cubes": [
{"origin": [-17, 10.6, -4.42], "size": [3, 3, 0], "uv": [8, 7], "mirror": true}
]
},
{
"name": "magnet_right",
"parent": "body_right",
@@ -162,9 +319,34 @@
"parent": "magnet_right",
"pivot": [-13.5, 8, -5],
"cubes": [
{"origin": [-18.5, 6.5, -9], "size": [10, 3, 4], "uv": [28, 82], "mirror": true},
{"origin": [-12.5, 6.5, -19], "size": [4, 3, 10], "uv": [28, 89], "mirror": true},
{"origin": [-18.5, 6.5, -19], "size": [4, 3, 10], "uv": [28, 102], "mirror": true}
{"origin": [-18.5, 6.5, -9], "size": [10, 3, 4], "inflate": 0.02, "uv": [28, 82], "mirror": true},
{"origin": [-12.5, 6.5, -19], "size": [4, 3, 10], "inflate": 0.01, "uv": [28, 89], "mirror": true},
{"origin": [-18.5, 6.5, -19], "size": [4, 3, 10], "inflate": 0.01, "uv": [28, 102], "mirror": true}
]
},
{
"name": "locator_cannon_right",
"parent": "magnet_right_rotation",
"pivot": [-13.5, 8, -19],
"locators": {
"cannon1": [-13.5, 8, -19],
"special1": [-13.5, 8, -19]
}
},
{
"name": "locator_item",
"parent": "magnet_right_rotation",
"pivot": [-13.5, 8, -19],
"locators": {
"item": [-13.5, 8, -19]
}
},
{
"name": "magnet_lights_right",
"parent": "magnet_right_rotation",
"pivot": [-13.5, 8, -18.92],
"cubes": [
{"origin": [-18.5, 6.5, -18.92], "size": [10, 3, 0], "uv": [18, 109], "mirror": true}
]
},
{
@@ -186,18 +368,51 @@
{
"name": "magnet_back",
"parent": "body",
"pivot": [0, 8, 12],
"rotation": [0, 0, 0]
"pivot": [0, 8, 12]
},
{
"name": "magnet_back_rotation",
"parent": "magnet_back",
"pivot": [0, 8, 12],
"cubes": [
{"origin": [-5, 6.5, 12], "size": [10, 3, 4], "uv": [69, 0]},
{"origin": [-5, 6.5, 16], "size": [4, 3, 10], "uv": [87, 0]},
{"origin": [1, 6.5, 16], "size": [4, 3, 10], "uv": [92, 13]}
{"origin": [-5, 6.5, 12], "size": [10, 3, 4], "inflate": 0.02, "uv": [69, 0]},
{"origin": [-5, 6.5, 16], "size": [4, 3, 10], "inflate": 0.01, "uv": [87, 0]},
{"origin": [1, 6.5, 16], "size": [4, 3, 10], "inflate": 0.01, "uv": [92, 13]}
]
},
{
"name": "locator_tail",
"parent": "magnet_back_rotation",
"pivot": [0, 8, 19.5],
"rotation": [180, 0, -180],
"locators": {
"locator": [0, 8, 19.5]
}
},
{
"name": "locator_tail_tip",
"parent": "magnet_back_rotation",
"pivot": [0, 8, 26],
"rotation": [180, 0, -180],
"locators": {
"tail_tip": [0, 8, 26]
}
},
{
"name": "magnet_lights_back",
"parent": "magnet_back_rotation",
"pivot": [0, 8, 25.92],
"cubes": [
{"origin": [-5, 6.5, 25.92], "size": [10, 3, 0], "uv": [77, 7]}
]
},
{
"name": "locator_seat_1",
"parent": "body",
"pivot": [0, 0, 0],
"locators": {
"seat_1": [0, 17.5, 4]
}
}
]
}
@@ -0,0 +1,936 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.unknown",
"texture_width": 256,
"texture_height": 256,
"visible_bounds_width": 5,
"visible_bounds_height": 4.5,
"visible_bounds_offset": [0, 1.75, 0]
},
"bones": [
{
"name": "druddigon",
"pivot": [0, 0, 0]
},
{
"name": "locator_root",
"parent": "druddigon",
"pivot": [0, 0, 0],
"locators": {
"root": [0, 0, 0]
}
},
{
"name": "locator_top",
"parent": "druddigon",
"pivot": [0, 35, 0],
"locators": {
"top": [0, 35, 0]
}
},
{
"name": "body",
"parent": "druddigon",
"pivot": [0, 0, 0]
},
{
"name": "locator_middle",
"parent": "body",
"pivot": [0, 15, 0],
"locators": {
"middle": [0, 15, 0]
}
},
{
"name": "locator_target",
"parent": "body",
"pivot": [0, 15, -8],
"locators": {
"target": [0, 15, -8]
}
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 11, 0],
"rotation": [37.5, 0, 0],
"cubes": [
{"origin": [-5, 6, -3.4], "size": [10, 12, 10.8], "uv": [34, 0]},
{"origin": [-5, 6, -3.4], "size": [10, 12, 10.8], "inflate": 0.4, "uv": [34, 22]}
]
},
{
"name": "tail_1",
"parent": "torso",
"pivot": [0, 7.95, 2],
"rotation": [-60, 0, 0],
"cubes": [
{"origin": [-4, 3.45, 0], "size": [8, 8, 12], "uv": [34, 44]},
{"origin": [0, 9.45, 7], "size": [0, 7, 4], "uv": [26, 83]}
]
},
{
"name": "tail_2",
"parent": "tail_1",
"pivot": [0, 7.45, 12],
"rotation": [17.5, 0, 0],
"cubes": [
{"origin": [-3, 4.45, 10], "size": [6, 6, 9], "uv": [74, 17]},
{"origin": [0, 9.95, 13], "size": [0, 7, 5], "pivot": [0, 10.45, 16], "rotation": [-5, 0, 0], "uv": [116, 100]}
]
},
{
"name": "locator_tail",
"parent": "tail_2",
"pivot": [0, 8, 18],
"locators": {
"tail": [0, 8, 18]
}
},
{
"name": "tail_3",
"parent": "tail_2",
"pivot": [0, 7.95, 19],
"rotation": [10, 0, 0],
"cubes": [
{"origin": [-2, 5.95, 17], "size": [4, 4, 8], "uv": [100, 43]},
{"origin": [0, 8.95, 19], "size": [0, 5, 4], "pivot": [0, 9.95, 21], "rotation": [-7.5, 0, 0], "uv": [76, 95]}
]
},
{
"name": "tail_4",
"parent": "tail_3",
"pivot": [0, 7.95, 25],
"rotation": [7.5, 0, 0],
"cubes": [
{"origin": [-1.5, 6.45, 23], "size": [3, 3, 6], "uv": [52, 108]}
]
},
{
"name": "locator_tail_tip",
"parent": "tail_4",
"pivot": [0, 8, 29],
"locators": {
"tail_tip": [0, 8, 29]
}
},
{
"name": "chest",
"parent": "torso",
"pivot": [0, 18, 4],
"rotation": [5, 0, 0],
"cubes": [
{"origin": [-4, 17, -2], "size": [8, 9, 8], "uv": [0, 66]},
{"origin": [-4, 17, -2], "size": [8, 9, 8], "inflate": 0.4, "uv": [74, 0]}
]
},
{
"name": "wing_left",
"parent": "chest",
"pivot": [3, 24.5, 5.5],
"rotation": [-7.5, 32.5, 0],
"cubes": [
{"origin": [3, 14.5, 4.5], "size": [0, 18, 13], "uv": [34, 64]}
]
},
{
"name": "locator_wing_left",
"parent": "wing_left",
"pivot": [3, 29, 15.5],
"locators": {
"wing2": [3, 29, 15.5]
}
},
{
"name": "wing_left2",
"parent": "wing_left",
"pivot": [3, 24.5, 17.5],
"cubes": [
{"origin": [3, 15.5, 17.5], "size": [0, 16, 17], "uv": [0, 0]}
]
},
{
"name": "wing_right",
"parent": "chest",
"pivot": [-3, 24.5, 5.5],
"rotation": [-7.5, -32.5, 0],
"cubes": [
{"origin": [-3, 14.5, 4.5], "size": [0, 18, 13], "uv": [60, 64]}
]
},
{
"name": "locator_wing_right",
"parent": "wing_right",
"pivot": [-3, 29, 15.5],
"locators": {
"wing1": [-3, 29, 15.5]
}
},
{
"name": "wing_right2",
"parent": "wing_right",
"pivot": [-3, 24.5, 17.5],
"cubes": [
{"origin": [-3, 15.5, 17.5], "size": [0, 16, 17], "uv": [0, 33]}
]
},
{
"name": "arms",
"parent": "chest",
"pivot": [0.25, 23.1, 1.3]
},
{
"name": "arm_right1",
"parent": "arms",
"pivot": [-3.25, 23.1, 1.3],
"cubes": [
{"origin": [-7.25, 22.1, -0.2], "size": [5, 3, 3], "uv": [48, 117]}
]
},
{
"name": "shoulder_spike_right",
"parent": "arm_right1",
"pivot": [-5.95, 24.6, 0.8],
"rotation": [0, 0, -17.5],
"cubes": [
{"origin": [-7.45, 23.6, 1.3], "size": [3, 5, 0], "pivot": [-5.95, 24.6, 1.3], "rotation": [0, 0, -9], "uv": [128, 6]}
]
},
{
"name": "arm_right2",
"parent": "arm_right1",
"pivot": [-5, 23.2, 1.3],
"cubes": [
{"origin": [-13, 22.2, 0.3], "size": [9, 2, 2], "uv": [112, 66]}
]
},
{
"name": "arm_right3",
"parent": "arm_right2",
"pivot": [-12, 23.2, 2.3],
"cubes": [
{"origin": [-18, 21.2, -0.7], "size": [6, 4, 4], "uv": [76, 106]},
{"origin": [-16.5, 25.2, 1.3], "size": [2, 3, 0], "uv": [42, 129]},
{"origin": [-23, 21.7, -0.2], "size": [5, 3, 3], "uv": [118, 112]},
{"origin": [-20.5, 24.7, 1.3], "size": [3, 4, 0], "uv": [46, 128]},
{"origin": [-23, 24.7, 1.3], "size": [2, 2, 0], "uv": [86, 130]}
]
},
{
"name": "hand_right",
"parent": "arm_right3",
"pivot": [-23, 23.2, 1.3],
"cubes": [
{"origin": [-25, 22.2, -0.2], "size": [2, 2, 3], "inflate": 0.01, "uv": [102, 121]}
]
},
{
"name": "locator_blade_primary",
"parent": "hand_right",
"pivot": [-24, 23.2, 1.3],
"rotation": [0, 90, 0],
"locators": {
"blade_primary": [-24, 23.2, 1.3]
}
},
{
"name": "locator_hand_primary",
"parent": "hand_right",
"pivot": [-24, 23.2, 1.3],
"rotation": [0, 90, 0],
"locators": {
"hand_primary": [-24, 23.2, 0.3],
"physical": [-24, 23.2, 1.3],
"item": [-24, 23.2, 1.3]
}
},
{
"name": "finger_right1",
"parent": "hand_right",
"pivot": [-25, 24.2, 1.3],
"cubes": [
{"origin": [-28, 22.2, 0.3], "size": [3, 2, 2], "uv": [0, 123]}
]
},
{
"name": "claw_right1",
"parent": "finger_right1",
"pivot": [-28, 24.2, 1.3],
"cubes": [
{"origin": [-29.9, 22.2, 0.3], "size": [2, 2, 2], "inflate": -0.1, "uv": [86, 126]},
{"origin": [-31.4, 21.7, 1.3], "size": [2, 2, 0], "inflate": 0.01, "uv": [90, 130]}
]
},
{
"name": "finger_right2",
"parent": "hand_right",
"pivot": [-23, 24.2, -0.2],
"cubes": [
{"origin": [-25, 22.2, -3.2], "size": [2, 2, 3], "uv": [1, 162]}
]
},
{
"name": "claw_right2",
"parent": "finger_right2",
"pivot": [-24, 24.2, -3.2],
"cubes": [
{"origin": [-25, 22.2, -5.1], "size": [2, 2, 2], "inflate": -0.1, "uv": [127, 88]},
{"origin": [-23.9, 21.7, -6.7], "size": [0, 2, 2], "uv": [130, 90]}
]
},
{
"name": "finger_right3",
"parent": "hand_right",
"pivot": [-23, 24.2, 2.8],
"cubes": [
{"origin": [-25, 22.2, 2.8], "size": [2, 2, 3], "uv": [21, 162]}
]
},
{
"name": "claw_right3",
"parent": "finger_right3",
"pivot": [-24, 24.2, 5.8],
"cubes": [
{"origin": [-25, 22.2, 5.7], "size": [2, 2, 2], "inflate": -0.1, "uv": [27, 154]},
{"origin": [-23.9, 21.7, 7.3], "size": [0, 2, 2], "uv": [117, 145]}
]
},
{
"name": "arm_left1",
"parent": "arms",
"pivot": [3.25, 23.1, 1.3],
"cubes": [
{"origin": [2.25, 22.1, -0.2], "size": [5, 3, 3], "uv": [48, 117], "mirror": true}
]
},
{
"name": "shoulder_spike_left",
"parent": "arm_left1",
"pivot": [5.95, 24.6, 0.8],
"rotation": [0, 0, 17.5],
"cubes": [
{"origin": [4.45, 23.6, 1.3], "size": [3, 5, 0], "pivot": [5.95, 24.6, 1.3], "rotation": [0, 0, 9], "uv": [128, 6], "mirror": true}
]
},
{
"name": "arm_left2",
"parent": "arm_left1",
"pivot": [5, 23.2, 1.3],
"cubes": [
{"origin": [4, 22.2, 0.3], "size": [9, 2, 2], "uv": [112, 66], "mirror": true}
]
},
{
"name": "arm_left3",
"parent": "arm_left2",
"pivot": [12, 23.2, 2.3],
"cubes": [
{"origin": [12, 21.2, -0.7], "size": [6, 4, 4], "uv": [76, 106], "mirror": true},
{"origin": [14.5, 25.2, 1.3], "size": [2, 3, 0], "uv": [42, 129], "mirror": true},
{"origin": [18, 21.7, -0.2], "size": [5, 3, 3], "uv": [118, 112], "mirror": true},
{"origin": [17.5, 24.7, 1.3], "size": [3, 4, 0], "uv": [46, 128], "mirror": true},
{"origin": [21, 24.7, 1.3], "size": [2, 2, 0], "uv": [86, 130], "mirror": true}
]
},
{
"name": "hand_left",
"parent": "arm_left3",
"pivot": [23, 23.2, 1.3],
"cubes": [
{"origin": [23, 22.2, -0.2], "size": [2, 2, 3], "inflate": 0.01, "uv": [102, 121], "mirror": true}
]
},
{
"name": "locator_blade_secondary",
"parent": "hand_left",
"pivot": [24, 23.2, 1.3],
"rotation": [0, -90, 0],
"locators": {
"blade_secondary": [24, 23.2, 1.3]
}
},
{
"name": "locator_hand_secondary",
"parent": "hand_left",
"pivot": [24, 23.2, 1.3],
"rotation": [0, -90, 0],
"locators": {
"hand_secondary": [24, 23.2, 1.3]
}
},
{
"name": "finger_left1",
"parent": "hand_left",
"pivot": [25, 24.2, 1.3],
"cubes": [
{"origin": [25, 22.2, 0.3], "size": [3, 2, 2], "uv": [0, 123], "mirror": true}
]
},
{
"name": "claw_left1",
"parent": "finger_left1",
"pivot": [28, 24.2, 1.3],
"cubes": [
{"origin": [27.9, 22.2, 0.3], "size": [2, 2, 2], "inflate": -0.1, "uv": [86, 126], "mirror": true},
{"origin": [29.4, 21.7, 1.3], "size": [2, 2, 0], "inflate": 0.01, "uv": [90, 130], "mirror": true}
]
},
{
"name": "finger_left2",
"parent": "hand_left",
"pivot": [23, 24.2, -0.2],
"cubes": [
{"origin": [23, 22.2, -3.2], "size": [2, 2, 3], "uv": [1, 162], "mirror": true}
]
},
{
"name": "claw_left2",
"parent": "finger_left2",
"pivot": [24, 24.2, -3.2],
"cubes": [
{"origin": [23, 22.2, -5.1], "size": [2, 2, 2], "inflate": -0.1, "uv": [127, 88], "mirror": true},
{"origin": [23.9, 21.7, -6.7], "size": [0, 2, 2], "uv": [130, 90], "mirror": true}
]
},
{
"name": "finger_left3",
"parent": "hand_left",
"pivot": [23, 24.2, 2.8],
"cubes": [
{"origin": [23, 22.2, 2.8], "size": [2, 2, 3], "uv": [21, 162], "mirror": true}
]
},
{
"name": "claw_left3",
"parent": "finger_left3",
"pivot": [24, 24.2, 5.8],
"cubes": [
{"origin": [23, 22.2, 5.7], "size": [2, 2, 2], "inflate": -0.1, "uv": [27, 154], "mirror": true},
{"origin": [23.9, 21.7, 7.3], "size": [0, 2, 2], "uv": [117, 145], "mirror": true}
]
},
{
"name": "neck",
"parent": "chest",
"pivot": [0, 26, 3],
"rotation": [15, 0, 0]
},
{
"name": "neck_mouth_closed",
"parent": "neck",
"pivot": [0, 26, 3],
"cubes": [
{"origin": [-3.5, 24, -0.5], "size": [7, 9, 6], "uv": [86, 91]}
]
},
{
"name": "neck_mouth_open",
"parent": "neck",
"pivot": [0, 26, 3],
"cubes": [
{"origin": [-3.5, 24, -0.5], "size": [7, 9, 6], "inflate": -0.01, "uv": [26, 95]}
]
},
{
"name": "neck_flair_top",
"parent": "neck",
"pivot": [0, 32, 5.5],
"rotation": [7.5, 0, 0],
"cubes": [
{"origin": [-4, 26.5, 5.5], "size": [8, 7, 0], "uv": [102, 114]}
]
},
{
"name": "neck_flair_bottom",
"parent": "neck",
"pivot": [0, 32, -0.5],
"rotation": [-7.5, 0, 0],
"cubes": [
{"origin": [-4, 27.5, -0.5], "size": [8, 5, 0], "pivot": [0, 32, -0.5], "rotation": [-10, 0, 0], "uv": [118, 118]}
]
},
{
"name": "neck_flair_left",
"parent": "neck",
"pivot": [3.5, 32, 2.5],
"rotation": [0, 0, -8],
"cubes": [
{"origin": [3.5, 27.5, -1], "size": [0, 5, 7], "uv": [112, 70]}
]
},
{
"name": "neck_flair_right",
"parent": "neck",
"pivot": [-3.5, 32, 2.5],
"rotation": [0, 0, 8],
"cubes": [
{"origin": [-3.5, 27.5, -1], "size": [0, 5, 7], "uv": [112, 82]}
]
},
{
"name": "head",
"parent": "neck",
"pivot": [0, 33, 2],
"rotation": [-35, 0, 0]
},
{
"name": "head_ai",
"parent": "head",
"pivot": [0, 33, 2]
},
{
"name": "head_angle",
"parent": "head_ai",
"pivot": [0, 33, 2],
"cubes": [
{"origin": [-4, 33, -3], "size": [8, 3, 8], "uv": [74, 32]},
{"origin": [3.99, 35.5, -3], "size": [0, 3, 8], "uv": [0, 112]},
{"origin": [-4, 35.5, -2.99], "size": [1, 1, 0], "uv": [32, 82]},
{"origin": [-3.99, 35.5, -3], "size": [0, 3, 8], "uv": [112, 55]},
{"origin": [3, 35.5, -2.99], "size": [1, 1, 0], "uv": [84, 61]},
{"origin": [-3, 33, -7], "size": [6, 3, 4], "uv": [24, 110]},
{"origin": [1, 35.5, -6.99], "size": [2, 2, 0], "uv": [82, 130]},
{"origin": [2.99, 35.5, -7], "size": [0, 2, 4], "uv": [30, 123]},
{"origin": [-3, 35.5, -6.99], "size": [2, 2, 0], "uv": [130, 94]},
{"origin": [-2.99, 35.5, -7], "size": [0, 2, 4], "uv": [38, 123]},
{"origin": [-4, 31, 1], "size": [8, 2, 4], "uv": [106, 0]},
{"origin": [2.29, 31.2, -6.6], "size": [0, 2, 3], "pivot": [2.29, 33.2, -5.1], "rotation": [0, 25, 0], "uv": [126, 127]},
{"origin": [-2.29, 31.2, -6.6], "size": [0, 2, 3], "pivot": [-2.29, 33.2, -5.1], "rotation": [0, -25, 0], "uv": [128, 11]},
{"origin": [3.99, 31, -3], "size": [0, 2, 4], "uv": [44, 110]},
{"origin": [-3.99, 31, -3], "size": [0, 2, 4], "uv": [70, 122]},
{"origin": [-3.99, 32, -3], "size": [1, 1, 0], "uv": [32, 80]},
{"origin": [2.99, 32, -3], "size": [1, 1, 0], "uv": [32, 81]}
]
},
{
"name": "locator_head",
"parent": "head_angle",
"pivot": [0, 36, -1.5],
"locators": {
"head": [0, 36, -1.5],
"item_hat": [0, 36, -1.5]
}
},
{
"name": "locator_face",
"parent": "head_angle",
"pivot": [0, 34.4, -7],
"locators": {
"face": [0, 34.4, -7],
"item_face": [0, 34.4, -7]
}
},
{
"name": "locator_mouth",
"parent": "head_angle",
"pivot": [0, 33, 1],
"locators": {
"mouth": [0, 33, 1],
"special": [0, 33, 1]
}
},
{
"name": "locator_jaw_upper",
"parent": "head_angle",
"pivot": [0, 33, -6.4],
"locators": {
"jaw1": [0, 33, -6.4]
}
},
{
"name": "eyes",
"parent": "head_angle",
"pivot": [4, 34.2, -1.5]
},
{
"name": "eye_left",
"parent": "eyes",
"pivot": [4, 34.2, -1.5],
"cubes": [
{"origin": [4, 33.2, -3], "size": [0, 2, 3], "inflate": 0.01, "uv": [70, 108]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [4, 34.2, -2],
"locators": {
"eye2": [4, 34.2, -2]
}
},
{
"name": "pupil_left",
"parent": "eye_left",
"pivot": [3.5, 34.2, -2.1],
"cubes": [
{"origin": [3, 33.2, -2.4], "size": [1, 2, 1], "inflate": 0.02, "uv": [128, 63]}
]
},
{
"name": "eyelid_left",
"parent": "eye_left",
"pivot": [0.9, 32.2, 2],
"cubes": [
{"origin": [2.9, 33.2, -2.9], "size": [1, 2, 3], "inflate": 0.03, "uv": [126, 28]}
]
},
{
"name": "eyelid_angry_left",
"parent": "eye_left",
"pivot": [1, 32.7, 2.5],
"cubes": [
{"origin": [3, 34.2, -3], "size": [1, 1, 1], "inflate": 0.03, "uv": [82, 104]},
{"origin": [3, 34.7, -2.5], "size": [1, 1, 2], "inflate": 0.03, "uv": [128, 25]}
]
},
{
"name": "eyelid_sad_left",
"parent": "eye_left",
"pivot": [0.9, 32.7, 2.5],
"cubes": [
{"origin": [2.9, 34.7, -2], "size": [1, 1, 2], "inflate": 0.03, "uv": [128, 53]}
]
},
{
"name": "eyelid_unamused_left",
"parent": "eye_left",
"pivot": [0.9, 32.7, 2.5],
"cubes": [
{"origin": [2.9, 34.7, -2.89], "size": [1, 1, 3], "inflate": 0.03, "uv": [8, 127]}
]
},
{
"name": "eyelid_happy_left",
"parent": "eye_left",
"pivot": [0.9, 32.2, 2],
"cubes": [
{"origin": [2.9, 33.2, -2.9], "size": [1, 2, 3], "inflate": 0.03, "uv": [126, 33]}
]
},
{
"name": "eyelid_recoil_left",
"parent": "eye_left",
"pivot": [0.9, 32.2, 2],
"cubes": [
{"origin": [2.9, 33.2, -2.9], "size": [1, 2, 3], "inflate": 0.03, "uv": [126, 38]}
]
},
{
"name": "eye_right",
"parent": "eyes",
"pivot": [-4, 34.2, -1.5],
"cubes": [
{"origin": [-4, 33.2, -3], "size": [0, 2, 3], "inflate": 0.01, "uv": [128, 16]}
]
},
{
"name": "locator_eye_right",
"parent": "eye_right",
"pivot": [-4, 34.2, -2],
"locators": {
"eye1": [-4, 34.2, -2]
}
},
{
"name": "pupil_right",
"parent": "eye_right",
"pivot": [-3.5, 34.2, -2.1],
"cubes": [
{"origin": [-4, 33.2, -2.4], "size": [1, 2, 1], "inflate": 0.02, "uv": [130, 0]}
]
},
{
"name": "eyelid_right",
"parent": "eye_right",
"pivot": [-0.9, 32.2, 2],
"cubes": [
{"origin": [-3.9, 33.2, -2.9], "size": [1, 2, 3], "inflate": 0.03, "uv": [62, 126]}
]
},
{
"name": "eyelid_angry_right",
"parent": "eye_right",
"pivot": [-1, 32.7, 2.5],
"cubes": [
{"origin": [-4, 34.2, -3], "size": [1, 1, 1], "inflate": 0.03, "uv": [130, 96]},
{"origin": [-4, 34.7, -2.5], "size": [1, 1, 2], "inflate": 0.03, "uv": [56, 128]}
]
},
{
"name": "eyelid_sad_right",
"parent": "eye_right",
"pivot": [-0.9, 32.7, 2.5],
"cubes": [
{"origin": [-3.9, 34.7, -2], "size": [1, 1, 2], "inflate": 0.03, "uv": [128, 56]}
]
},
{
"name": "eyelid_unamused_right",
"parent": "eye_right",
"pivot": [-0.9, 32.7, 2.5],
"cubes": [
{"origin": [-3.9, 34.7, -2.89], "size": [1, 1, 3], "inflate": 0.03, "uv": [16, 127]}
]
},
{
"name": "eyelid_happy_right",
"parent": "eye_right",
"pivot": [-0.9, 32.2, 2],
"cubes": [
{"origin": [-3.9, 33.2, -2.9], "size": [1, 2, 3], "inflate": 0.03, "uv": [126, 70]}
]
},
{
"name": "eyelid_recoil_right",
"parent": "eye_right",
"pivot": [-0.9, 32.2, 2],
"cubes": [
{"origin": [-3.9, 33.2, -2.9], "size": [1, 2, 3], "inflate": 0.03, "uv": [126, 75]}
]
},
{
"name": "head_hidden",
"parent": "head_angle",
"pivot": [0, 32.5, 3],
"cubes": [
{"origin": [-3.5, 29.5, 0], "size": [7, 6, 5], "inflate": -0.02, "uv": [104, 17]}
]
},
{
"name": "jaw",
"parent": "head_angle",
"pivot": [0, 33, 2.5],
"rotation": [-27.5, 0, 0],
"cubes": [
{"origin": [-4, 29, 0.5], "size": [8, 5, 2], "inflate": 0.01, "uv": [106, 36]},
{"origin": [3.8, 28, 0.5], "size": [0, 6, 3], "inflate": 0.01, "pivot": [3.8, 31.5, 1], "rotation": [-2.81797, 27.47162, -1.30078], "uv": [64, 117]},
{"origin": [-3.8, 28, 0.5], "size": [0, 6, 3], "inflate": 0.01, "pivot": [-3.8, 31.5, 1], "rotation": [-2.81797, -27.47162, 1.30078], "uv": [112, 121]},
{"origin": [-3.5, 28.8, -1], "size": [7, 2, 4], "inflate": 0.01, "pivot": [0, 29, 2.5], "rotation": [27.5, 0, 0], "uv": [106, 6]},
{"origin": [-2, 30.3, -3], "size": [4, 2, 6], "inflate": 0.01, "pivot": [0, 29, 2.5], "rotation": [27.5, 0, 0], "uv": [96, 106]},
{"origin": [-2.5, 28.8, -4.5], "size": [5, 2, 4], "inflate": 0.01, "pivot": [0, 29, 2.5], "rotation": [27.5, 0, 0], "uv": [112, 94]},
{"origin": [2.5, 30.8, -3], "size": [0, 2, 2], "inflate": 0.01, "pivot": [0, 29, 2.5], "rotation": [27.5, 0, 0], "uv": [98, 122]},
{"origin": [2.5, 30.8, -1], "size": [1, 1, 0], "inflate": 0.01, "pivot": [0, 29, 2.5], "rotation": [27.5, 0, 0], "uv": [84, 59]},
{"origin": [3.5, 30.8, -1], "size": [0, 1, 1], "inflate": 0.01, "pivot": [0, 29, 2.5], "rotation": [27.5, 0, 0], "uv": [32, 76]},
{"origin": [-3.5, 30.8, -1], "size": [1, 1, 0], "inflate": 0.01, "pivot": [0, 29, 2.5], "rotation": [27.5, 0, 0], "uv": [84, 60]},
{"origin": [-3.5, 30.8, -1], "size": [0, 1, 1], "inflate": 0.01, "pivot": [0, 29, 2.5], "rotation": [27.5, 0, 0], "uv": [32, 78]},
{"origin": [-2.5, 30.8, -3], "size": [0, 2, 2], "inflate": 0.01, "pivot": [0, 29, 2.5], "rotation": [27.5, 0, 0], "uv": [128, 59]},
{"origin": [2.5, 26.24473, -1.8992], "size": [0, 1, 1], "pivot": [2.5, 26.74473, -1.3992], "rotation": [-17.5, 0, 0], "uv": [32, 72]},
{"origin": [-2.5, 26.24473, -1.8992], "size": [0, 1, 1], "pivot": [-2.5, 26.74473, -1.3992], "rotation": [-17.5, 0, 0], "uv": [32, 74]},
{"origin": [-1.5, 27.36438, -4.54022], "size": [3, 2, 0], "pivot": [0, 27.36438, -4.54022], "rotation": [37.5, 0, 0], "uv": [76, 104]},
{"origin": [1.5, 26.36438, -4.54022], "size": [0, 2, 1], "pivot": [0, 27.36438, -4.54022], "rotation": [37.5, 0, 0], "uv": [32, 66]},
{"origin": [-1.5, 26.36438, -4.54022], "size": [0, 2, 1], "pivot": [0, 27.36438, -4.54022], "rotation": [37.5, 0, 0], "uv": [32, 69]}
]
},
{
"name": "locator_jaw_lower",
"parent": "jaw",
"pivot": [0, 27.59235, -4.11544],
"rotation": [27.5, 0, 0],
"locators": {
"jaw2": {
"offset": [0, 27.59235, -4.11544],
"rotation": [-90, 0, 0]
}
}
},
{
"name": "leg_left1",
"parent": "body",
"pivot": [4.5, 11, 0],
"rotation": [-37.5, 0, 0],
"cubes": [
{"origin": [2.5, 3.5, -4], "size": [6, 9, 7], "uv": [74, 43]},
{"origin": [2.5, 3.5, -4], "size": [6, 9, 7], "inflate": 0.25, "uv": [0, 83]}
]
},
{
"name": "leg_left2",
"parent": "leg_left1",
"pivot": [5.5, 3.6, -0.5],
"rotation": [-32.5, 0, 0],
"cubes": [
{"origin": [4, 1.6, -2.5], "size": [3, 4, 9], "uv": [52, 95]}
]
},
{
"name": "foot_left",
"parent": "leg_left2",
"pivot": [5.5, 5.6, 6],
"rotation": [2.5, 0, 0],
"cubes": [
{"origin": [3, 0.6, 6], "size": [5, 5, 3], "inflate": -0.01, "uv": [70, 114]}
]
},
{
"name": "locator_foot_secondary",
"parent": "foot_left",
"pivot": [5.5, 2.6, 7.5],
"rotation": [90, 0, 0],
"locators": {
"foot_secondary": [5.5, 2.6, 7.5]
}
},
{
"name": "toe_left1",
"parent": "foot_left",
"pivot": [5.5, 0.6, 8],
"cubes": [
{"origin": [4.5, -1.9, 6.9], "size": [2, 3, 2], "inflate": 0.1, "uv": [16, 112]}
]
},
{
"name": "toe_claw_left1",
"parent": "toe_left1",
"pivot": [5.5, -2, 7],
"cubes": [
{"origin": [4.5, -4, 6.9], "size": [2, 2, 2], "uv": [126, 100]},
{"origin": [5.5, -5.5, 6.9], "size": [0, 2, 2], "uv": [70, 128]}
]
},
{
"name": "toe_left2",
"parent": "foot_left",
"pivot": [3.5, 1.1, 8],
"cubes": [
{"origin": [2.5, -1.4, 6.9], "size": [2, 3, 2], "inflate": 0.1, "uv": [46, 123]}
]
},
{
"name": "toe_claw_left2",
"parent": "toe_left2",
"pivot": [3.5, -1.5, 7],
"cubes": [
{"origin": [2.5, -3.5, 6.9], "size": [2, 2, 2], "uv": [102, 126]},
{"origin": [3.5, -5, 6.9], "size": [0, 2, 2], "uv": [74, 128]}
]
},
{
"name": "toe_left3",
"parent": "foot_left",
"pivot": [7.5, 1.1, 8],
"cubes": [
{"origin": [6.5, -1.4, 6.9], "size": [2, 3, 2], "inflate": 0.1, "uv": [54, 123]}
]
},
{
"name": "toe_claw_left3",
"parent": "toe_left3",
"pivot": [7.5, -1.5, 7],
"cubes": [
{"origin": [6.5, -3.5, 6.9], "size": [2, 2, 2], "uv": [126, 104]},
{"origin": [7.5, -5, 6.9], "size": [0, 2, 2], "uv": [118, 128]}
]
},
{
"name": "spike_foot_left",
"parent": "foot_left",
"pivot": [5.5, 5.6, 7],
"rotation": [27.5, 0, 0],
"cubes": [
{"origin": [5.5, 5.1, 6], "size": [0, 4, 2], "uv": [112, 100]}
]
},
{
"name": "leg_right1",
"parent": "body",
"pivot": [-4.5, 11, 0],
"rotation": [-37.5, 0, 0],
"cubes": [
{"origin": [-8.5, 3.5, -4], "size": [6, 9, 7], "uv": [86, 59]},
{"origin": [-8.5, 3.5, -4], "size": [6, 9, 7], "inflate": 0.25, "uv": [86, 75]}
]
},
{
"name": "leg_right2",
"parent": "leg_right1",
"pivot": [-5.5, 3.6, -0.5],
"rotation": [-32.5, 0, 0],
"cubes": [
{"origin": [-7, 1.6, -2.5], "size": [3, 4, 9], "uv": [0, 99]}
]
},
{
"name": "foot_right",
"parent": "leg_right2",
"pivot": [-5.5, 5.6, 6],
"rotation": [2.5, 0, 0],
"cubes": [
{"origin": [-8, 0.6, 6], "size": [5, 5, 3], "inflate": -0.01, "uv": [86, 114]}
]
},
{
"name": "locator_foot_primary",
"parent": "foot_right",
"pivot": [-5.5, 2.6, 7.5],
"rotation": [90, 0, 0],
"locators": {
"foot_primary": [-5.5, 2.6, 7.5]
}
},
{
"name": "toe_right1",
"parent": "foot_right",
"pivot": [-5.5, 0.6, 8],
"cubes": [
{"origin": [-6.5, -1.9, 6.9], "size": [2, 3, 2], "inflate": 0.1, "uv": [118, 123]}
]
},
{
"name": "toe_claw_right1",
"parent": "toe_right1",
"pivot": [-5.5, -2, 7],
"cubes": [
{"origin": [-6.5, -4, 6.9], "size": [2, 2, 2], "uv": [126, 108]},
{"origin": [-5.5, -5.5, 6.9], "size": [0, 2, 2], "uv": [122, 128]}
]
},
{
"name": "toe_right2",
"parent": "foot_right",
"pivot": [-3.5, 1.1, 8],
"cubes": [
{"origin": [-4.5, -1.4, 6.9], "size": [2, 3, 2], "inflate": 0.1, "uv": [124, 43]}
]
},
{
"name": "toe_claw_right2",
"parent": "toe_right2",
"pivot": [-3.5, -1.5, 7],
"cubes": [
{"origin": [-4.5, -3.5, 6.9], "size": [2, 2, 2], "uv": [126, 123]},
{"origin": [-3.5, -5, 6.9], "size": [0, 2, 2], "uv": [30, 129]}
]
},
{
"name": "toe_right3",
"parent": "foot_right",
"pivot": [-7.5, 1.1, 8],
"cubes": [
{"origin": [-8.5, -1.4, 6.9], "size": [2, 3, 2], "inflate": 0.1, "uv": [124, 48]}
]
},
{
"name": "toe_claw_right3",
"parent": "toe_right3",
"pivot": [-7.5, -1.5, 7],
"cubes": [
{"origin": [-8.5, -3.5, 6.9], "size": [2, 2, 2], "uv": [0, 127]},
{"origin": [-7.5, -5, 6.9], "size": [0, 2, 2], "uv": [34, 129]}
]
},
{
"name": "spike_foot_right",
"parent": "foot_right",
"pivot": [-5.5, 5.6, 7],
"rotation": [27.5, 0, 0],
"cubes": [
{"origin": [-5.5, 5.1, 6], "size": [0, 4, 2], "uv": [52, 128]}
]
}
]
}
]
}
@@ -69,13 +69,13 @@
{"origin": [-25.5, 35.75, 5.5], "size": [1, 2, 2], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [236, 85]},
{"origin": [-25.5, 36.75, 6.5], "size": [1, 2, 2], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [242, 85]},
{"origin": [-25.5, 38.75, 8.5], "size": [1, 2, 2], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [242, 89]},
{"origin": [-26, 40.75, 9.5], "size": [1, 1, 1], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [240, 77]},
{"origin": [-25.5, 40.75, 9.5], "size": [1, 1, 1], "pivot": [-27, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [240, 77]},
{"origin": [-25.5, 39.75, 10.5], "size": [1, 5, 2], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [236, 93]},
{"origin": [-25.5, 39.75, 12.5], "size": [1, 3, 1], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [248, 95]},
{"origin": [-25.5, 40.75, 13.5], "size": [1, 2, 2], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [248, 77]},
{"origin": [-25.5, 41.75, 14.5], "size": [1, 2, 2], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [248, 81]},
{"origin": [-25.5, 42.75, 15.5], "size": [1, 4, 2], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [242, 93]},
{"origin": [-26, 44.75, 11.5], "size": [1, 1, 1], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [246, 77]},
{"origin": [-25.5, 44.75, 11.5], "size": [1, 1, 1], "pivot": [-27, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [246, 77]},
{"origin": [-25.5, 32.75, 3.5], "size": [1, 3, 2], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [248, 85]},
{"origin": [-25.5, 37.75, 7.5], "size": [1, 2, 2], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [236, 89]},
{"origin": [-25.5, 38.75, 4.5], "size": [1, 2, 3], "pivot": [-27.5, 28.75, -0.5], "rotation": [45, 0, 0], "uv": [247, 117]},
@@ -7,8 +7,8 @@
"texture_width": 128,
"texture_height": 128,
"visible_bounds_width": 6,
"visible_bounds_height": 4.5,
"visible_bounds_offset": [0, 1.75, 0]
"visible_bounds_height": 5,
"visible_bounds_offset": [0, 1.5, 0]
},
"bones": [
{
@@ -480,6 +480,14 @@
{"origin": [-4.5, 24.5, 26.5], "size": [9, 9, 7], "uv": [66, 109]}
]
},
{
"name": "locator_seat_1",
"parent": "torso",
"pivot": [0, 0, 0],
"locators": {
"seat_1": [0, 30, 0]
}
},
{
"name": "legs",
"parent": "body",
@@ -99,7 +99,14 @@
"poseTypes": ["FLY"],
"isBattle": false,
"condition": "!q.is_gliding",
"animations": ["q.look('head_ai')", "q.bedrock('charizard', 'air_fly')"],
"animations": [
"q.look('head_ai')",
"q.bedrock('charizard', 'air_fly')",
{
"condition": "q.is_ridden",
"animation": "q.bedrock('charizard', 'ride_air_look')"
}
],
"quirks": [
"q.bedrock_quirk('charizard', 'blink')",
"q.bedrock_quirk('charizard', 'air_fly_quirk')"
@@ -109,7 +116,14 @@
"poseTypes": ["FLY"],
"isBattle": false,
"condition": "q.is_gliding",
"animations": ["q.look('head_ai')", "q.bedrock('charizard', 'air_glide_TEST')"],
"animations": [
"q.look('head_ai')",
"q.bedrock('charizard', 'air_glide_TEST')",
{
"condition": "q.is_ridden",
"animation": "q.bedrock('charizard', 'ride_air_look')"
}
],
"quirks": [
"q.bedrock_quirk('charizard', 'blink')"
]
@@ -1,32 +1,46 @@
{
"portraitScale": 1.94,
"portraitTranslation": [-0.32, -0.41, 0],
"profileScale": 0.77,
"profileTranslation": [0, 0.6, 0],
"animations": {},
"poses": {
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE", "FLOAT"],
"isBattle": false,
"animations": [
"q.look('head', 1, 1, 70, -45, 45, -45)",
"q.bedrock('eevee', 'ground_idle')"
],
"quirks": [
"q.bedrock_quirk('eevee', 'blink')"
]
},
"walking": {
"poseTypes": ["WALK", "SWIM"],
"animations": [
"q.look('head', 1, 1, 70, -45, 45, -45)",
"q.bedrock('eevee', 'ground_idle')",
"q.quadruped_walk(0.66, 1.4, 'front_leg_left', 'front_leg_right', 'back_leg_left', 'back_leg_right')"
],
"quirks": ["q.bedrock_quirk('eevee', 'blink')"]
}
"portraitScale": 1.94,
"portraitTranslation": [-0.32, -0.41, 0],
"profileScale": 0.77,
"profileTranslation": [0, 0.6, 0],
"rootBone": "eevee",
"animations": {
"cry": "q.bedrock_stateful('eevee', 'cry')"
},
"poses": {
"standing": {
"poseTypes": [
"STAND",
"NONE",
"PORTRAIT",
"PROFILE",
"FLOAT"
],
"isBattle": false,
"animations": [
"q.look('head', 1, 1, 70, -45, 45, -45)",
"q.bedrock('eevee', 'ground_idle')"
],
"quirks": [
"q.bedrock_quirk('eevee', 'blink')"
]
},
"walking": {
"poseTypes": [
"WALK",
"SWIM"
],
"animations": [
"q.look('head', 1, 1, 70, -45, 45, -45)",
"q.bedrock('eevee', 'ground_idle')",
"q.quadruped_walk(0.66, 1.4, 'front_leg_left', 'front_leg_right', 'back_leg_left', 'back_leg_right')"
],
"quirks": [
"q.bedrock_quirk('eevee', 'blink')"
]
}
}
}
}
@@ -1,32 +1,46 @@
{
"portraitScale": 2.08,
"portraitTranslation": [-0.7, -0.37, 0],
"profileScale": 0.85,
"profileTranslation": [0, 0.45, 0],
"animations": {},
"poses": {
"standing": {
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE", "FLOAT"],
"isBattle": false,
"animations": [
"q.look('head', 1, 1, 70, -45, 45, -45)",
"q.bedrock('vaporeon', 'ground_idle')"
],
"quirks": [
"q.bedrock_quirk('vaporeon', 'blink')"
]
},
"walking": {
"poseTypes": ["WALK", "SWIM"],
"animations": [
"q.look('head', 1, 1, 70, -45, 45, -45)",
"q.bedrock('vaporeon', 'ground_idle')",
"q.quadruped_walk(0.66, 1.4, 'frontleg_left', 'frontleg_right', 'back_leg_left', 'back_leg_right')"
],
"quirks": ["q.bedrock_quirk('vaporeon', 'blink')"]
}
"portraitScale": 2.08,
"portraitTranslation": [-0.7, -0.37, 0],
"profileScale": 0.85,
"profileTranslation": [0, 0.45, 0],
"rootBone": "vaporeon",
"animations": {
"cry": "q.bedrock_stateful('vaporeon', 'cry')"
},
"poses": {
"standing": {
"poseTypes": [
"STAND",
"NONE",
"PORTRAIT",
"PROFILE",
"FLOAT"
],
"isBattle": false,
"animations": [
"q.look('head', 1, 1, 70, -45, 45, -45)",
"q.bedrock('vaporeon', 'ground_idle')"
],
"quirks": [
"q.bedrock_quirk('vaporeon', 'blink')"
]
},
"walking": {
"poseTypes": [
"WALK",
"SWIM"
],
"animations": [
"q.look('head', 1, 1, 70, -45, 45, -45)",
"q.bedrock('vaporeon', 'ground_idle')",
"q.quadruped_walk(0.66, 1.4, 'frontleg_left', 'frontleg_right', 'back_leg_left', 'back_leg_right')"
],
"quirks": [
"q.bedrock_quirk('vaporeon', 'blink')"
]
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More