mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-20 14:16:26 -04:00
Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e24ee6b4e | ||
|
|
3d6a3fbfec | ||
|
|
708b810e6b | ||
|
|
509016e133 | ||
|
|
690183b994 | ||
|
|
33d56124f5 | ||
|
|
a5a65abe2b | ||
|
|
f73ab3b001 | ||
|
|
9a571984db |
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"lastSavedVersion": "1.7.0",
|
||||
"maxPokemonLevel": 100,
|
||||
"maxPokemonFriendship": 255,
|
||||
"announceDropItems": true,
|
||||
"defaultDropItemMethod": "on-entity",
|
||||
"ambientPokemonCryTicks": 1080,
|
||||
"defaultBoxCount": 30,
|
||||
"pokemonSaveIntervalSeconds": 30,
|
||||
"storageFormat": "nbt",
|
||||
"preventCompletePartyDeposit": false,
|
||||
"mongoDBConnectionString": "mongodb://localhost:27017",
|
||||
"mongoDBDatabaseName": "cobblemon",
|
||||
"maxVerticalCorrectionBlocks": 64,
|
||||
"minimumLevelRangeMax": 10,
|
||||
"enableSpawning": true,
|
||||
"minimumDistanceBetweenEntities": 8.0,
|
||||
"maxNearbyBlocksHorizontalRange": 4,
|
||||
"maxNearbyBlocksVerticalRange": 2,
|
||||
"maxVerticalSpace": 8,
|
||||
"worldSliceDiameter": 8,
|
||||
"worldSliceHeight": 16,
|
||||
"ticksBetweenSpawnAttempts": 20.0,
|
||||
"minimumSliceDistanceFromPlayer": 16.0,
|
||||
"maximumSliceDistanceFromPlayer": 64.0,
|
||||
"exportSpawnConfig": false,
|
||||
"savePokemonToWorld": true,
|
||||
"exportStarterConfig": false,
|
||||
"autoUpdateShowdown": true,
|
||||
"defaultFleeDistance": 32.0,
|
||||
"allowExperienceFromPvP": true,
|
||||
"experienceShareMultiplier": 0.5,
|
||||
"luckyEggMultiplier": 1.5,
|
||||
"allowSpectating": true,
|
||||
"experienceMultiplier": 2.0,
|
||||
"pokemonPerChunk": 1.0,
|
||||
"passiveStatuses": {
|
||||
"cobblemon:poison": "180-300",
|
||||
"cobblemon:poisonbadly": "180-300",
|
||||
"cobblemon:paralysis": "180-300",
|
||||
"cobblemon:frozen": "180-300",
|
||||
"cobblemon:sleep": "180-300",
|
||||
"cobblemon:burn": "180-300"
|
||||
},
|
||||
"infiniteHealerCharge": false,
|
||||
"maxHealerCharge": 6.0,
|
||||
"secondsToChargeHealingMachine": 900.0,
|
||||
"defaultFaintTimer": 300,
|
||||
"faintAwakenHealthPercent": 0.2,
|
||||
"healPercent": 0.05,
|
||||
"healTimer": 60,
|
||||
"baseApricornTreeGenerationChance": 0.1,
|
||||
"displayEntityLevelLabel": true,
|
||||
"displayEntityNameLabel": true,
|
||||
"displayNameForUnknownPokemon": false,
|
||||
"displayEntityLabelsWhenCrouchingOnly": false,
|
||||
"shinyRate": 8192.0,
|
||||
"shinyNoticeParticlesDistance": 24.0,
|
||||
"captureCalculator": "cobblemon",
|
||||
"playerDamagePokemon": true,
|
||||
"appleLeftoversChance": 0.025,
|
||||
"maxRootsInArea": 5,
|
||||
"bigRootPropagationChance": 0.1,
|
||||
"energyRootChance": 0.25,
|
||||
"maxDynamaxLevel": 10,
|
||||
"teraTypeRate": 20.0,
|
||||
"defaultPasturedPokemonLimit": 16,
|
||||
"pastureBlockUpdateTicks": 40,
|
||||
"pastureMaxWanderDistance": 64,
|
||||
"pastureMaxPerChunk": 4.0,
|
||||
"maxInsertedFossilItems": 2,
|
||||
"walkingInBattleAnimations": false,
|
||||
"battleWildMaxDistance": 12.0,
|
||||
"tradeMaxDistance": 12.0,
|
||||
"battlePvPMaxDistance": 32.0,
|
||||
"battleSpectateMaxDistance": 64.0,
|
||||
"maxPokedexScanningDetectionRange": 10.0,
|
||||
"hideUnimplementedPokemonInThePokedex": false,
|
||||
"summaryPokemonFollowCursor": true,
|
||||
"enableDebugKeys": false
|
||||
}
|
||||
@@ -9,6 +9,9 @@
|
||||
package com.cobblemon.mod.common;
|
||||
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.SmoothDouble;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Vector3f;
|
||||
@@ -117,8 +120,22 @@ public interface Rollable {
|
||||
return (float) Mth.wrapDegrees(-Math.toDegrees(getUpVector().angleSigned(UP, getForwardVector())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the angular velocity in degrees per second as a Vec3
|
||||
*/
|
||||
Vec3 angRollVel( double deltaTime );
|
||||
|
||||
public Vec3 rotationOnMouseXY(double yMouse,
|
||||
double xMouse,
|
||||
SmoothDouble yMouseSmoother,
|
||||
SmoothDouble xMouseSmoother,
|
||||
double sensitivity,
|
||||
double deltaTime );
|
||||
|
||||
boolean shouldRoll();
|
||||
|
||||
boolean useAngVelSmoothing();
|
||||
|
||||
void clearRotation();
|
||||
|
||||
}
|
||||
|
||||
@@ -12,9 +12,15 @@ import com.cobblemon.mod.common.api.pokemon.effect.ShoulderEffectRegistry;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(LivingEntity.class)
|
||||
@@ -28,4 +34,70 @@ public abstract class LivingEntityMixin {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@Inject(method = "travelRidden", at = @At(value = "HEAD"))
|
||||
private void cobblemon$altTravelRidden(Player player, Vec3 travelVector)
|
||||
{
|
||||
this.setSpeed(this.getRiddenSpeed(player));
|
||||
this.travel(vec3);
|
||||
}
|
||||
|
||||
/*
|
||||
// Shadow the original method so we can call it.
|
||||
@Shadow
|
||||
protected abstract boolean isControlledByLocalInstance();
|
||||
|
||||
/**
|
||||
* Redirect the call to isControlledByLocalInstance() within travelRidden.
|
||||
* When travelRidden calls isControlledByLocalInstance(), it will get our modified result.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Redirect(
|
||||
method = "travelRidden(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/phys/Vec3;)V",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/LivingEntity;isControlledByLocalInstance()Z"
|
||||
)
|
||||
)
|
||||
private boolean redirectIsControlledByLocalInstance(LivingEntity instance) {
|
||||
// Return true if either the original method returns true or our custom condition is true.
|
||||
return this.isControlledByLocalInstance() || this.b;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Overwrite
|
||||
private void travelRidden(Player player, Vec3 travelVector) {
|
||||
Vec3 vec3 = this.getRiddenInput(player, travelVector);
|
||||
this.tickRidden(player, vec3);
|
||||
if (this.isControlledByLocalInstance()) {
|
||||
this.setSpeed(this.getRiddenSpeed(player));
|
||||
this.travel(vec3);
|
||||
} else {
|
||||
this.calculateEntityAnimation(false);
|
||||
this.setDeltaMovement(Vec3.ZERO);
|
||||
this.tryCheckInsideBlocks();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ModifyArg(
|
||||
method = "travelRidden",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "setDeltaMovement(Lnet/minecraft/world/phys/Vec3;)V"
|
||||
),
|
||||
index = 0 // the first (and only) argument
|
||||
)
|
||||
private Vec3 modifyDeltaMovementArgument(Vec3 original) {
|
||||
// Optionally, check if original is Vec3.ZERO, to only replace that call:
|
||||
if (original.equals(Vec3.ZERO)) {
|
||||
// Return your custom vector instead of Vec3.ZERO
|
||||
return original;
|
||||
}
|
||||
// Otherwise, return the original value
|
||||
return original;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 net.minecraft.client.player.LocalPlayer;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(LocalPlayer.class)
|
||||
public abstract class LocalPlayerMixin {
|
||||
@Shadow
|
||||
private float jumpRidingScale;
|
||||
|
||||
@Inject(method = "getJumpRidingScale", at = @At("HEAD"), cancellable = true)
|
||||
public void modifyJumpRidingScale(CallbackInfoReturnable<Float> cir) {
|
||||
|
||||
LocalPlayer player = (LocalPlayer) (Object) this;
|
||||
if (player.isPassenger() && player.getVehicle() instanceof PokemonEntity) {
|
||||
PokemonEntity ride = (PokemonEntity) player.getVehicle();
|
||||
//ride.getRiding().canJump()
|
||||
if( !ride.getRiding().canJump(ride, player))
|
||||
{
|
||||
cir.setReturnValue(0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if the player is riding your custom entity (for example, a Pokemon)
|
||||
/*
|
||||
if (player.isRiding() && player.getVehicle() instanceof PokemonEntity) {
|
||||
PokemonEntity rideable = (PokemonEntity) player.getVehicle();
|
||||
// Get your custom fuel ratio (a value from 0.0 to 1.0)
|
||||
float fuelRatio = rideable.getRidingFuelRatio();
|
||||
cir.setReturnValue(fuelRatio);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,13 @@ import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding;
|
||||
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;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.SmoothDouble;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -33,8 +35,11 @@ public class MouseHandlerMixin {
|
||||
@Shadow private double accumulatedScrollY;
|
||||
@Shadow @Final private Minecraft minecraft;
|
||||
|
||||
@Unique SmoothDouble xMouseSmoother = new SmoothDouble();
|
||||
@Unique SmoothDouble yMouseSmoother = new SmoothDouble();
|
||||
@Unique SmoothDouble pitchSmoother = new SmoothDouble();
|
||||
@Unique SmoothDouble rollSmoother = new SmoothDouble();
|
||||
@Unique SmoothDouble yawSmoother = new SmoothDouble();
|
||||
|
||||
@Shadow @Final private SmoothDouble smoothTurnY;
|
||||
|
||||
@@ -44,6 +49,8 @@ public class MouseHandlerMixin {
|
||||
|
||||
@Shadow private double accumulatedDY;
|
||||
|
||||
@Shadow private double accumulatedScrollX;
|
||||
|
||||
@Inject(
|
||||
method = "onScroll",
|
||||
at = @At(
|
||||
@@ -95,7 +102,12 @@ public class MouseHandlerMixin {
|
||||
target = "Lnet/minecraft/client/player/LocalPlayer;turn(DD)V"
|
||||
)
|
||||
)
|
||||
public boolean cobblemon$modifyRotation(LocalPlayer player, double cursorDeltaX, double cursorDeltaY, @Local(argsOnly = true) double d) {
|
||||
public boolean cobblemon$modifyRotation(LocalPlayer player,
|
||||
double cursorDeltaX,
|
||||
double cursorDeltaY,
|
||||
@Local(argsOnly = true) double d,
|
||||
@Local(argsOnly = true) double movementTime
|
||||
) {
|
||||
PokedexUsageContext usageContext = CobblemonClient.INSTANCE.getPokedexUsageContext();
|
||||
if (usageContext.getScanningGuiOpen()) {
|
||||
this.smoothTurnY.reset();
|
||||
@@ -109,16 +121,92 @@ public class MouseHandlerMixin {
|
||||
}
|
||||
|
||||
if (!(player instanceof Rollable rollable)) return true;
|
||||
|
||||
if (!rollable.shouldRoll()) {
|
||||
xMouseSmoother.reset();
|
||||
yMouseSmoother.reset();
|
||||
pitchSmoother.reset();
|
||||
rollSmoother.reset();
|
||||
yawSmoother.reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
var pitch = pitchSmoother.getNewDeltaValue(cursorDeltaY * 0.15f, d);
|
||||
var roll = rollSmoother.getNewDeltaValue(cursorDeltaX * 0.15f, d);
|
||||
rollable.rotate(0.0F, (float)pitch, (float)roll);
|
||||
//maybe have a rollable x mouse and rollable y mouse that take the xmousesmoother
|
||||
//and y mouse smoother ( which are right now named pichsmoother and roll smoother)
|
||||
// values and feed it to those rollable functions which will be called by the
|
||||
//specific ride controller where rollable.rotate can then be called and used
|
||||
//controller specific.
|
||||
|
||||
//return a vec3 of the yaw pitch and roll that are wanted.
|
||||
//multiply by sensitivity before passing it in
|
||||
|
||||
//var xMouse = xMouseSmoother.getNewDeltaValue(cursorDeltaX * 0.05f, d);
|
||||
//var yMouse = yMouseSmoother.getNewDeltaValue(cursorDeltaY * 0.05f, d);
|
||||
|
||||
var defaultSensitivity = this.minecraft.options.sensitivity().get() * 0.6000000238418579 + 0.20000000298023224;
|
||||
var ridingSensitivity = Math.pow(defaultSensitivity, 3);
|
||||
|
||||
Vec3 angVecMouse = rollable.rotationOnMouseXY
|
||||
( cursorDeltaY,
|
||||
cursorDeltaX ,
|
||||
yMouseSmoother,
|
||||
xMouseSmoother,
|
||||
ridingSensitivity,
|
||||
movementTime );
|
||||
|
||||
//make this configurable maybe?
|
||||
|
||||
//var mRoll = rollSmoother.getNewDeltaValue(angVecMouse.z * 0.15f, d);
|
||||
|
||||
rollable.rotate((float) angVecMouse.x,
|
||||
(float) angVecMouse.y,
|
||||
(float) angVecMouse.z);
|
||||
|
||||
//var yMouse = yMouseSmoother.getNewDeltaValue(angVecMouse.y * 0.15f, d);
|
||||
//var xMouse = xMouseSmoother.getNewDeltaValue(cursorDeltaX * 0.15f, d);
|
||||
|
||||
//get the current angular velocity requested to be applied
|
||||
//by the ride controller
|
||||
var angRot = rollable.angRollVel(movementTime);
|
||||
|
||||
if( rollable.useAngVelSmoothing() )
|
||||
{
|
||||
//get the current angular velocity requested to be applied
|
||||
//by the ride controller
|
||||
|
||||
//Multiply against deltatime to get a consistent turn
|
||||
//independent of framerate
|
||||
if( angRot != null ) {
|
||||
//var yaw = angRot.x * d;
|
||||
//Add the yaw to the mouse here... this all needs changed. It should
|
||||
//just map which 0 1 or 2 of the three it is going to modulate with
|
||||
//what
|
||||
|
||||
var yaw = yawSmoother.getNewDeltaValue(angRot.x * 0.5f, d);
|
||||
var pitch = pitchSmoother.getNewDeltaValue(angRot.y * 0.5f, d);
|
||||
var roll = rollSmoother.getNewDeltaValue(angRot.z * 0.5f, d);
|
||||
rollable.rotate((float) yaw, (float) pitch, (float) roll);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//Multiply against deltatime to get a consistent turn
|
||||
//independent of framerate
|
||||
if( angRot != null ) {
|
||||
//var yaw = angRot.x * d;
|
||||
//Add the yaw to the mouse here... this all needs changed. It should
|
||||
//just map which 0 1 or 2 of the three it is going to modulate with
|
||||
//what
|
||||
|
||||
rollable.rotate((float) (angRot.x * 10 * d),
|
||||
(float) (angRot.y * 10 * d),
|
||||
(float) (angRot.z * 10 * d));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Inject(method = "handleAccumulatedMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MouseHandler;isMouseGrabbed()Z", ordinal = 0))
|
||||
|
||||
@@ -38,6 +38,7 @@ import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.SmoothDouble;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
@@ -47,6 +48,7 @@ import net.minecraft.world.food.FoodProperties;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix3f;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
@@ -55,6 +57,7 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||
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.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@@ -272,6 +275,7 @@ public abstract class PlayerMixin extends LivingEntity implements Rollable, Scan
|
||||
|
||||
@Override
|
||||
public Rollable updateOrientation(Function<Matrix3f, Matrix3f> update) {
|
||||
//Disabled to allow non mouse inputs to modify roll
|
||||
if (!shouldRoll()) return this;
|
||||
|
||||
if (this.orientation == null) {
|
||||
@@ -297,6 +301,61 @@ public abstract class PlayerMixin extends LivingEntity implements Rollable, Scan
|
||||
return pokemonEntity.getRiding().shouldRoll(pokemonEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 rotationOnMouseXY(double yMouse,
|
||||
double xMouse,
|
||||
SmoothDouble yMouseSmoother,
|
||||
SmoothDouble xMouseSmoother,
|
||||
double sensitivity,
|
||||
double deltaTime )
|
||||
{
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (!this.equals(player)) return Vec3.ZERO;
|
||||
|
||||
var playerVehicle = player.getVehicle();
|
||||
if (playerVehicle == null) return Vec3.ZERO;
|
||||
if (!(playerVehicle instanceof PokemonEntity pokemonEntity)) return Vec3.ZERO;
|
||||
|
||||
//this is ridiculous. There likely needs to be some sort of mouseInfo class.
|
||||
return pokemonEntity.getRiding().rotationOnMouseXY
|
||||
(
|
||||
pokemonEntity,
|
||||
player,
|
||||
yMouse,
|
||||
xMouse,
|
||||
yMouseSmoother,
|
||||
xMouseSmoother,
|
||||
sensitivity,
|
||||
deltaTime );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAngVelSmoothing() {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (!this.equals(player)) return true;
|
||||
if (player.isHolding(Items.DIAMOND)) return false;
|
||||
|
||||
var playerVehicle = player.getVehicle();
|
||||
if (playerVehicle == null) return true;
|
||||
if (!(playerVehicle instanceof PokemonEntity pokemonEntity)) return true;
|
||||
|
||||
return pokemonEntity.getRiding().useAngVelSmoothing(pokemonEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 angRollVel( double deltaTime ) {
|
||||
var ret = new Vec3(0.0, 0.0, 0.0);
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (!this.equals(player)) return ret;
|
||||
|
||||
var playerVehicle = player.getVehicle();
|
||||
if (playerVehicle == null) return ret;
|
||||
if (!(playerVehicle instanceof PokemonEntity pokemonEntity)) return ret;
|
||||
|
||||
return pokemonEntity.getRiding().angRollVel( pokemonEntity, player, deltaTime );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clearRotation() {
|
||||
this.orientation = null;
|
||||
|
||||
@@ -10,15 +10,20 @@ package com.cobblemon.mod.common.api.riding
|
||||
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.cobblemon.mod.common.Rollable
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.riding.controller.RideController
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.network.chat.Component
|
||||
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
|
||||
import kotlin.math.sin
|
||||
|
||||
data class RidingManager(val entity: PokemonEntity) {
|
||||
var lastSpeed = 0F
|
||||
@@ -58,8 +63,12 @@ data class RidingManager(val entity: PokemonEntity) {
|
||||
|
||||
val pose = controller.pose(entity)
|
||||
entity.entityData.set(PokemonEntity.POSE_TYPE, pose)
|
||||
//val speedPlayer = driver.deltaMovement.horizontalDistance()
|
||||
//driver.displayClientMessage(Component.literal("Speed player: ").withStyle { it.withColor(ChatFormatting.GREEN) }.append(Component.literal("$speedPlayer b/t")), true)
|
||||
//val speedEntity = entity.deltaMovement.length() //* 20 * 60 * 60) / ( 1000 )
|
||||
//println(speedEntity)
|
||||
//driver.displayClientMessage(Component.literal("Speed: ").withStyle { it.withColor(ChatFormatting.GREEN) }.append(Component.literal("${String.format("%.2f", speedEntity)} km/h")), true)
|
||||
|
||||
// driver.displayClientMessage(Component.literal("Speed: ").withStyle { it.withColor(ChatFormatting.GREEN) }.append(Component.literal("$lastSpeed b/t")), true)
|
||||
}
|
||||
|
||||
fun speed(entity: PokemonEntity, driver: Player): Float {
|
||||
@@ -91,6 +100,11 @@ data class RidingManager(val entity: PokemonEntity) {
|
||||
return controller.velocity(entity, driver, input)
|
||||
}
|
||||
|
||||
fun fuelBar(entity: PokemonEntity, driver: Player): Float {
|
||||
val controller = getController(entity) ?: return 0.0f
|
||||
return controller.fuelBar(entity, driver)
|
||||
}
|
||||
|
||||
fun canJump(entity: PokemonEntity, driver: Player): Boolean {
|
||||
val controller = getController(entity) ?: return false
|
||||
return controller.canJump(entity, driver)
|
||||
@@ -101,11 +115,24 @@ data class RidingManager(val entity: PokemonEntity) {
|
||||
return controller.jumpForce(entity, driver, jumpStrength)
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to supply the dela for the lerp() between velocity
|
||||
* vectors. Called inertia for now as the way it feels when
|
||||
* affecting the ride is somewhat akin to inertia.
|
||||
*/
|
||||
fun inertia(entity: PokemonEntity): Double {
|
||||
val controller = getController(entity) ?: return 0.5
|
||||
return controller.inertia(entity)
|
||||
}
|
||||
|
||||
//Can be accomplished through the velocity controls
|
||||
fun gravity(entity: PokemonEntity, regularGravity: Double): Double? {
|
||||
val controller = getController(entity) ?: return null
|
||||
return controller.gravity(entity, regularGravity)
|
||||
}
|
||||
|
||||
//Maybe should be changed to be a function that conveys:
|
||||
// "turn on use our camera system function"
|
||||
fun shouldRoll(entity: PokemonEntity): Boolean {
|
||||
val controller = getController(entity) ?: return false
|
||||
return controller.shouldRoll(entity)
|
||||
@@ -121,8 +148,50 @@ data class RidingManager(val entity: PokemonEntity) {
|
||||
return controller.shouldRotatePokemonHead()
|
||||
}
|
||||
|
||||
//FIXME: Make this not just be false for all controllers lol
|
||||
//this is called just as often as
|
||||
fun rotationOnMouseXY
|
||||
( entity: PokemonEntity,
|
||||
driver: Player,
|
||||
yMouse: Double,
|
||||
xMouse: Double,
|
||||
yMouseSmoother: SmoothDouble,
|
||||
xMouseSmoother: SmoothDouble,
|
||||
sensitivity: Double,
|
||||
deltaTime: Double ): Vec3
|
||||
{
|
||||
val controller = getController(entity) ?: return Vec3.ZERO
|
||||
return controller.rotationOnMouseXY( entity,
|
||||
driver,
|
||||
yMouse,
|
||||
xMouse,
|
||||
yMouseSmoother,
|
||||
xMouseSmoother,
|
||||
sensitivity,
|
||||
deltaTime )
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether mouse input will affect the rotation of
|
||||
* the rollable object. Need to remove this as it's not used anymore
|
||||
*/
|
||||
//I think this might better serve as a "use smoothing on angular velocity"useAngVelSmoothing
|
||||
fun useAngVelSmoothing(entity: PokemonEntity): Boolean {
|
||||
val controller = getController(entity) ?: return true
|
||||
return controller.useAngVelSmoothing(entity)
|
||||
}
|
||||
|
||||
fun turnOffOnGround(entity: PokemonEntity): Boolean {
|
||||
val controller = getController(entity) ?: return false
|
||||
return controller.turnOffOnGround(entity)
|
||||
}
|
||||
|
||||
fun angRollVel(entity: PokemonEntity, driver: Player, deltaTime: Double): Vec3 {
|
||||
val controller = getController(entity) ?: return Vec3(0.0, 0.0, 0.0)
|
||||
return controller.angRollVel(entity, driver, deltaTime)
|
||||
}
|
||||
|
||||
fun dismountOnShift(): Boolean {
|
||||
return false
|
||||
val controller = getController(entity) ?: return false
|
||||
return controller.dismountOnShift(entity)
|
||||
}
|
||||
}
|
||||
+40
@@ -8,6 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.riding.controller
|
||||
|
||||
import com.cobblemon.mod.common.Rollable
|
||||
import com.cobblemon.mod.common.api.net.Decodable
|
||||
import com.cobblemon.mod.common.api.net.Encodable
|
||||
import com.cobblemon.mod.common.api.riding.RidingState
|
||||
@@ -17,6 +18,7 @@ import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.writeIdentifier
|
||||
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
|
||||
@@ -71,6 +73,14 @@ interface RideController : Encodable, Decodable {
|
||||
*/
|
||||
fun rotation(entity: PokemonEntity, driver: LivingEntity) : Vec2
|
||||
|
||||
/**
|
||||
* Sets the change current change in rotation for that tick in three
|
||||
* dimensions
|
||||
*/
|
||||
fun angRollVel(entity: PokemonEntity, driver: Player, deltaTime: Double): Vec3 {
|
||||
return Vec3(0.0, 0.0, 0.0)
|
||||
}
|
||||
|
||||
fun clampPassengerRotation(entity: PokemonEntity, driver: LivingEntity) {}
|
||||
|
||||
fun updatePassengerRotation(entity: PokemonEntity, driver: LivingEntity) {
|
||||
@@ -84,13 +94,43 @@ interface RideController : Encodable, Decodable {
|
||||
*/
|
||||
fun velocity(entity: PokemonEntity, driver: Player, input: Vec3) : Vec3
|
||||
|
||||
fun fuelBar(entity: PokemonEntity, driver: Player): Float = 0.0f
|
||||
|
||||
fun canJump(entity: PokemonEntity, driver: Player) : Boolean
|
||||
|
||||
fun jumpForce(entity: PokemonEntity, driver: Player, jumpStrength: Int) : Vec3
|
||||
|
||||
fun gravity(entity: PokemonEntity, regularGravity: Double) : Double? = null
|
||||
|
||||
fun inertia(entity: PokemonEntity ) : Double = 0.5
|
||||
|
||||
fun shouldRoll(entity: PokemonEntity): Boolean = false
|
||||
|
||||
fun useAngVelSmoothing(entity: PokemonEntity): Boolean = false
|
||||
|
||||
//If function is not overwritten by controllers then just perform the defualt
|
||||
//rolling function which is roll on mousex and pitch on mousey
|
||||
fun rotationOnMouseXY
|
||||
(entity: PokemonEntity,
|
||||
driver: Player,
|
||||
yMouse: Double,
|
||||
xMouse: Double,
|
||||
yMouseSmoother: SmoothDouble,
|
||||
xMouseSmoother: SmoothDouble,
|
||||
sensitivity: Double,
|
||||
deltaTime: Double ): Vec3
|
||||
{
|
||||
if(driver !is Rollable) return Vec3.ZERO
|
||||
|
||||
//Might need to add the somothing here for default.
|
||||
val rollable = driver as Rollable
|
||||
return Vec3(0.0, yMouse, xMouse )
|
||||
}
|
||||
|
||||
fun turnOffOnGround(entity: PokemonEntity): Boolean = false
|
||||
|
||||
fun dismountOnShift(entity: PokemonEntity): Boolean = false
|
||||
|
||||
fun getRuntime(entity: PokemonEntity) = entity.riding.runtime
|
||||
|
||||
fun shouldRotatePokemonHead(): Boolean = false
|
||||
|
||||
-49
@@ -1,49 +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.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 WhiscashModel (root: ModelPart) : PokemonPosableModel(root) {
|
||||
override val rootPart = root.registerChildWithAllChildren("whiscash")
|
||||
|
||||
override var portraitScale = 0.8F
|
||||
override var portraitTranslation = Vec3(-0.35, 0.4, 0.0)
|
||||
|
||||
override var profileScale = 0.6F
|
||||
override var profileTranslation = Vec3(-0.1, 0.6, 0.0)
|
||||
|
||||
lateinit var standing: CobblemonPose
|
||||
lateinit var walk: CobblemonPose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("whiscash", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
|
||||
animations = arrayOf(
|
||||
bedrock("whiscash", "water_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walk = registerPose(
|
||||
poseName = "walk",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
animations = arrayOf(
|
||||
bedrock("whiscash", "water_idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
-1
@@ -533,7 +533,6 @@ object VaryingModelRepository {
|
||||
inbuilt("spewpa", ::SpewpaModel)
|
||||
inbuilt("vivillon", ::VivillonModel)
|
||||
inbuilt("barboach", ::BarboachModel)
|
||||
inbuilt("whiscash", ::WhiscashModel)
|
||||
inbuilt("combee", ::CombeeModel)
|
||||
inbuilt("vespiquen", ::VespiquenModel)
|
||||
inbuilt("lillipup", ::LillipupModel)
|
||||
|
||||
+3
-1
@@ -45,7 +45,8 @@ object MountedPlayerRenderer {
|
||||
val locatorOffset = locator.matrix.getTranslation(Vector3f())
|
||||
|
||||
val center = Vector3f(0f, entity.bbHeight/2, 0f)
|
||||
val locatorOffsetToCenter = locatorOffset.sub(center, Vector3f())
|
||||
var locatorOffsetToCenter = locatorOffset.sub(center, Vector3f())
|
||||
//locatorOffsetToCenter.y -= 0.5f
|
||||
|
||||
val transformationMatrix = Matrix4f()
|
||||
if (player is Rollable && player.shouldRoll()){
|
||||
@@ -113,6 +114,7 @@ object MountedPlayerRenderer {
|
||||
state.runtime.environment.setSimpleVariable("age_in_ticks", DoubleValue(ageInTicks.toDouble()))
|
||||
state.runtime.environment.setSimpleVariable("limb_swing", DoubleValue(limbSwing.toDouble()))
|
||||
state.runtime.environment.setSimpleVariable("limb_swing_amount", DoubleValue(limbSwingAmount.toDouble()))
|
||||
state.runtime.environment.setSimpleVariable("velocity", DoubleValue(pokemonEntity.deltaMovement.horizontalDistance()))
|
||||
|
||||
// TODO add the q.player reference, requires a cached thing or something on the client idk
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ enum class PoseType {
|
||||
FLY,
|
||||
FLOAT,
|
||||
SWIM,
|
||||
GLIDE,
|
||||
/** 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. */
|
||||
@@ -41,7 +42,7 @@ enum class PoseType {
|
||||
|
||||
companion object {
|
||||
val ALL_POSES = EnumSet.allOf(PoseType::class.java)
|
||||
val FLYING_POSES = EnumSet.of(FLY, HOVER)
|
||||
val FLYING_POSES = EnumSet.of(FLY, HOVER, GLIDE)
|
||||
val SWIMMING_POSES = EnumSet.of(SWIM, FLOAT)
|
||||
val STANDING_POSES = EnumSet.of(STAND, WALK)
|
||||
val SHOULDER_POSES = EnumSet.of(SHOULDER_LEFT, SHOULDER_RIGHT)
|
||||
|
||||
@@ -8,12 +8,8 @@
|
||||
|
||||
package com.cobblemon.mod.common.entity.pokemon
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonEntities
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.*
|
||||
import com.cobblemon.mod.common.CobblemonNetwork.sendPacket
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.Rollable
|
||||
import com.cobblemon.mod.common.api.drop.DropTable
|
||||
import com.cobblemon.mod.common.api.entity.Despawner
|
||||
import com.cobblemon.mod.common.api.entity.PokemonSender
|
||||
@@ -38,10 +34,10 @@ import com.cobblemon.mod.common.api.pokemon.feature.StringSpeciesFeature
|
||||
import com.cobblemon.mod.common.api.pokemon.status.Statuses
|
||||
import com.cobblemon.mod.common.api.reactive.ObservableSubscription
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.api.riding.Rideable
|
||||
import com.cobblemon.mod.common.api.riding.RidingManager
|
||||
import com.cobblemon.mod.common.api.riding.Seat
|
||||
import com.cobblemon.mod.common.api.riding.*
|
||||
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.stats.RidingStatDefinitions
|
||||
import com.cobblemon.mod.common.api.scheduling.Schedulable
|
||||
import com.cobblemon.mod.common.api.scheduling.SchedulingTracker
|
||||
import com.cobblemon.mod.common.api.scheduling.afterOnServer
|
||||
@@ -84,6 +80,8 @@ import com.cobblemon.mod.common.pokemon.ai.FormPokemonBehaviour
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.ItemInteractionEvolution
|
||||
import com.cobblemon.mod.common.pokemon.feature.StashHandler
|
||||
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
|
||||
import com.cobblemon.mod.common.pokemon.riding.controllers.JetAirController.Companion.MAXTOPSPEED
|
||||
import com.cobblemon.mod.common.pokemon.riding.controllers.JetAirController.Companion.MINTOPSPEED
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules
|
||||
@@ -123,15 +121,7 @@ import net.minecraft.world.InteractionResult
|
||||
import net.minecraft.world.damagesource.DamageSource
|
||||
import net.minecraft.world.damagesource.DamageTypes
|
||||
import net.minecraft.world.effect.MobEffects
|
||||
import net.minecraft.world.entity.AgeableMob
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.EntityDimensions
|
||||
import net.minecraft.world.entity.EntityType
|
||||
import net.minecraft.world.entity.EquipmentSlot
|
||||
import net.minecraft.world.entity.ExperienceOrb
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.Pose
|
||||
import net.minecraft.world.entity.Shearable
|
||||
import net.minecraft.world.entity.*
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeSupplier
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes
|
||||
import net.minecraft.world.entity.ai.control.MoveControl
|
||||
@@ -153,6 +143,7 @@ import net.minecraft.world.phys.Vec2
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import org.joml.Matrix3f
|
||||
import org.joml.Vector3f
|
||||
import java.util.*
|
||||
|
||||
@Suppress("unused")
|
||||
open class PokemonEntity(
|
||||
@@ -239,6 +230,10 @@ open class PokemonEntity(
|
||||
get() = entityData.get(FRIENDSHIP)
|
||||
val seats: List<Seat>
|
||||
get() = form.riding.seats
|
||||
val rideProp: RidingProperties
|
||||
get() = form.riding
|
||||
|
||||
|
||||
|
||||
var drops: DropTable? = null
|
||||
|
||||
@@ -1381,10 +1376,75 @@ open class PokemonEntity(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Converted to kotin from the same named private function in entity.
|
||||
private fun getInputVector(relative: Vec3, motionScaler: Float, facing: Float): Vec3 {
|
||||
val d = relative.lengthSqr()
|
||||
if (d < 1.0E-7) {
|
||||
return Vec3.ZERO
|
||||
}
|
||||
|
||||
// If the squared length is greater than 1, normalize; otherwise, use the vector as-is.
|
||||
// May not want to normalize this
|
||||
//val vec3 = (if (d > 1.0) relative.normalize() else relative).scale(motionScaler.toDouble())
|
||||
val vec3 = relative
|
||||
|
||||
// Convert the facing angle (in degrees) to radians using the factor 0.017453292F.
|
||||
val f = Mth.sin(facing * 0.017453292F)
|
||||
val g = Mth.cos(facing * 0.017453292F)
|
||||
|
||||
// Rotate the vector by the facing angle.
|
||||
return Vec3(
|
||||
vec3.x * g - vec3.z * f,
|
||||
vec3.y,
|
||||
vec3.z * g + vec3.x * f
|
||||
)
|
||||
}
|
||||
|
||||
//override fun moveRelative(amount: Float, relative: Vec3 ) {
|
||||
//super.moveRelative(amount, relative)
|
||||
//val v = this.getInputVector(relative, 1.0f, this.getYRot());
|
||||
//this.setDeltaMovement(v);
|
||||
//}
|
||||
|
||||
override fun handleRelativeFrictionAndCalculateMovement(deltaMovement: Vec3 , friction: Float ): Vec3 {
|
||||
val riders = this.passengers.filterIsInstance<LivingEntity>()
|
||||
if ( riders.isEmpty() ) {
|
||||
super.handleRelativeFrictionAndCalculateMovement(deltaMovement, friction)
|
||||
}
|
||||
//ignore this for now
|
||||
else if( false )
|
||||
{
|
||||
val v = this.getInputVector(deltaMovement, 1.0f, this.getYRot());
|
||||
//changing this will give the ride more or less inertia/handling/drift?
|
||||
//A bit of overlap with other things but.
|
||||
this.setDeltaMovement(this.deltaMovement.lerp(v, riding.inertia(this)));
|
||||
//this.setDeltaMovement(this.deltaMovement.scale(this.speed.toDouble()));
|
||||
|
||||
//maybe move this to the travel function. The jump below never gets used.
|
||||
this.move( MoverType.SELF, this.deltaMovement );
|
||||
}
|
||||
return this.deltaMovement
|
||||
}
|
||||
|
||||
override fun travel(movementInput: Vec3) {
|
||||
val prevBlockPos = this.blockPosition()
|
||||
if (beamMode != 3) { // Don't let Pokémon move during recall
|
||||
super.travel(movementInput)
|
||||
//this.deltaMovement = movementInput
|
||||
|
||||
//val riders = this.passengers.filterIsInstance<LivingEntity>()
|
||||
//if ( !riders.isEmpty() ) {
|
||||
//if ( false ) {
|
||||
//val v = this.handleRelativeFrictionAndCalculateMovement(movementInput, 0.6f)
|
||||
//this.moveRelative(this.speed, v);
|
||||
//}
|
||||
val riders = this.passengers.filterIsInstance<LivingEntity>()
|
||||
if ( riders.isEmpty() ) {
|
||||
super.travel(movementInput)
|
||||
}
|
||||
|
||||
//super.travel(movementInput)
|
||||
|
||||
this.updateBlocksTraveled(prevBlockPos)
|
||||
}
|
||||
if (isBattling && this.isInWater) {
|
||||
@@ -1618,6 +1678,17 @@ open class PokemonEntity(
|
||||
return platform == PlatformType.NONE && super.canRide(entity)
|
||||
}
|
||||
|
||||
// Takes in a requested stat type with a base minimum and base maximum and returns the interpolated
|
||||
// stat based on the boost of that pokemons stat
|
||||
fun getRideStat( stat: RidingStat, style: RidingStyle, baseMin: Double, baseMax: Double ): Double {
|
||||
//Currenlty zero boost since aprijuice isn't implemented yet
|
||||
val stat = this.rideProp.calculate(stat, style, 0 )
|
||||
|
||||
val statVal = (((baseMax - baseMin) / 100) * stat) + baseMin
|
||||
|
||||
return statVal
|
||||
}
|
||||
|
||||
override fun canAddPassenger(passenger: Entity): Boolean {
|
||||
return passengers.size < seats.size
|
||||
}
|
||||
@@ -1627,6 +1698,11 @@ open class PokemonEntity(
|
||||
jumping = value
|
||||
}
|
||||
|
||||
// override fun moveRelative(amount: Float, relative: Vec3) {
|
||||
// val vec3 = this.getInputVector(relative, amount, this.yRot)
|
||||
// this.deltaMovement = deltaMovement.add(vec3)
|
||||
// }
|
||||
|
||||
override fun tickRidden(driver: Player, movementInput: Vec3) {
|
||||
super.tickRidden(driver, movementInput)
|
||||
this.riding.tick(this, driver, movementInput)
|
||||
@@ -1636,6 +1712,23 @@ open class PokemonEntity(
|
||||
this.yBodyRot = this.yRot
|
||||
this.yRotO = this.yRot
|
||||
|
||||
val riders = this.passengers.filterIsInstance<LivingEntity>()
|
||||
|
||||
//These are the only functions that matter and I have isolated them.
|
||||
//I think using speed to scale the movement vector will not be working.
|
||||
|
||||
if ( !riders.isEmpty() ) {
|
||||
val v = this.getInputVector(riding.velocity(this, driver, Vec3.ZERO), 1.0f, this.getYRot());
|
||||
//changing this will give the ride more or less inertia/handling/drift?
|
||||
//A bit of overlap with other things but.
|
||||
this.setDeltaMovement(this.deltaMovement.lerp(v, riding.inertia(this)));
|
||||
//this.setDeltaMovement(this.deltaMovement.scale(this.speed.toDouble()));
|
||||
|
||||
//maybe move this to the travel function. The jump below never gets used.
|
||||
this.move( MoverType.SELF, this.deltaMovement );
|
||||
|
||||
}
|
||||
|
||||
if (this.riding.canJump(this, driver)) {
|
||||
if (this.onGround()) {
|
||||
if (this.jumpInputStrength > 0) {
|
||||
@@ -1788,8 +1881,45 @@ open class PokemonEntity(
|
||||
// Set back to land pose type?
|
||||
}
|
||||
|
||||
/*
|
||||
These two functions (fluids and ground) need to become riding configurable and
|
||||
dependent. Also, the onGround() function seems to affect quite a few spots in
|
||||
code and would likely need to be changed to be something more robust instead of
|
||||
just overriding this method.
|
||||
*/
|
||||
|
||||
override fun isAffectedByFluids(): Boolean {
|
||||
var fluidAffected = true
|
||||
|
||||
if( this.hasControllingPassenger() )
|
||||
{
|
||||
//Change this so it calls something from the controller to check
|
||||
//if the specific controller wants to ignore fluid physics since
|
||||
//not every single one will want to
|
||||
fluidAffected = false
|
||||
}
|
||||
|
||||
return fluidAffected
|
||||
}
|
||||
|
||||
|
||||
//this seems a bit hacky to me seeing as how many spots in the base classes its used.
|
||||
//However, there are odd interactions with the controllers when they are meant to be
|
||||
//flying or swimming but they are touching the ground and this needs to be prevented.
|
||||
//Having it be able to be turned off by the flying or swimming controllers is the
|
||||
//temp solution I have found.
|
||||
override fun onGround() : Boolean
|
||||
{
|
||||
if( riding.turnOffOnGround( this ) )
|
||||
{
|
||||
return false
|
||||
}
|
||||
return super.onGround()
|
||||
}
|
||||
|
||||
//I think already mentioned but should maybe be riding controller configurable
|
||||
override fun dismountsUnderwater(): Boolean {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getDefaultGravity(): Double {
|
||||
|
||||
+279
-19
@@ -11,28 +11,43 @@ package com.cobblemon.mod.common.pokemon.riding.controllers
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.cobblemon.mod.common.Rollable
|
||||
import com.cobblemon.mod.common.api.riding.RidingStyle
|
||||
import com.cobblemon.mod.common.api.riding.controller.RideController
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseOption
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseProvider
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readString
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.util.toVec3d
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.cobblemon.mod.common.util.writeString
|
||||
import com.cobblemon.mod.common.pokemon.riding.controllers.HelicopterAirController.Companion.ROTATION_LIMIT
|
||||
import com.cobblemon.mod.common.pokemon.riding.controllers.JetAirController.Companion
|
||||
import com.cobblemon.mod.common.pokemon.riding.controllers.JetAirController.Companion.MAXTOPSPEED
|
||||
import com.cobblemon.mod.common.pokemon.riding.controllers.JetAirController.Companion.MINSPEED
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
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 kotlin.math.*
|
||||
|
||||
class BirdAirController : RideController {
|
||||
override val key = KEY
|
||||
override val poseProvider = PoseProvider(PoseType.HOVER)
|
||||
.with(PoseOption(PoseType.FLY) { it.deltaMovement.horizontalDistance() > 0.1 })
|
||||
.with(PoseOption(PoseType.GLIDE) {
|
||||
val player = it.passengers.firstOrNull() as? Player ?: return@PoseOption false
|
||||
player.zza == 0.0f && it.deltaMovement.length() > 0.3 })
|
||||
.with(PoseOption(PoseType.FLY) {
|
||||
val player = it.passengers.firstOrNull() as? Player ?: return@PoseOption false
|
||||
player.zza > 0.0f // Checks if the player is actively controlling movement // Checks if the player is actively controlling movement
|
||||
})
|
||||
|
||||
//.with(PoseOption(PoseType.FLY) { entity ->
|
||||
// val player = entity.passengers.firstOrNull() as? Player ?: false
|
||||
// player.// This is the `zza` value })
|
||||
//.with(PoseOption(PoseType.GLIDE) { it.deltaMovement.length() > 0.51 })
|
||||
//.with(PoseOption(PoseType.FLY) { it.deltaMovement.length() > 0.1 && it.deltaMovement.length() <= 0.51 })
|
||||
|
||||
override val condition: (PokemonEntity) -> Boolean = { true }
|
||||
|
||||
var jumpVector = listOf("0".asExpression(), "0.3".asExpression(), "0".asExpression())
|
||||
@@ -45,9 +60,70 @@ class BirdAirController : RideController {
|
||||
private set
|
||||
var speed: Expression = "1.0".asExpression()
|
||||
private set
|
||||
var lastVelocity = Vec3(0.0,0.0,0.0)
|
||||
private set
|
||||
|
||||
var currSpeed = 0.0
|
||||
private set
|
||||
|
||||
var lastPitch = 0.0f
|
||||
private set
|
||||
|
||||
//This function might just be good for syncing the ridecontroller speed
|
||||
//with the entity speed?
|
||||
override fun speed(entity: PokemonEntity, driver: Player): Float {
|
||||
return getRuntime(entity).resolveFloat(speed)
|
||||
//Set the speed since this will need to be done to transfer speed between rides?
|
||||
//maxSpeed = entity.speed.toDouble()
|
||||
|
||||
|
||||
//retrieve stats
|
||||
val topSpeed = entity.getRideStat( RidingStat.SPEED, RidingStyle.AIR, MINTOPSPEED, MAXTOPSPEED )
|
||||
val accel = entity.getRideStat( RidingStat.ACCELERATION, RidingStyle.AIR, MINACCEL, MAXACCEL )
|
||||
|
||||
val maxGlideSpeed = topSpeed * 2
|
||||
var glideSpeedChange = 0.00
|
||||
|
||||
//speed up and slow down based on input
|
||||
if( driver.zza > 0.0 && currSpeed < topSpeed)
|
||||
{
|
||||
currSpeed = min( currSpeed + accel , topSpeed)
|
||||
}
|
||||
else if ( driver.zza < 0.0 && currSpeed > 0.0)
|
||||
{
|
||||
//Decelerate is now always a constant half of max acceleration.
|
||||
currSpeed = max( currSpeed - (MAXACCEL / 2) , 0.0)
|
||||
}
|
||||
|
||||
val rollable = driver as? Rollable
|
||||
if ( rollable != null )
|
||||
{
|
||||
glideSpeedChange = sin(Math.toRadians( rollable.pitch.toDouble() ))
|
||||
glideSpeedChange = glideSpeedChange.pow(3)
|
||||
|
||||
//TODO: Possibly create a deadzone around parallel where speed isn't taken away from?
|
||||
if( glideSpeedChange <= 0.0 )
|
||||
{
|
||||
//Ensures that a propelling force is still able to be applied when
|
||||
//climbing in height
|
||||
if( driver.zza <= 0 )
|
||||
{
|
||||
//speed decrease should be 2x speed increase?
|
||||
currSpeed = max( currSpeed + (MAXACCEL) * glideSpeedChange , 0.0 )
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// only add to the speed if it hasn't exceeded the current
|
||||
//glide angles maximum amount of speed that it can give.
|
||||
currSpeed = min( currSpeed + ((MAXACCEL * 2) * glideSpeedChange) , topSpeed * 2)
|
||||
}
|
||||
}
|
||||
|
||||
//air resistance
|
||||
currSpeed = max( currSpeed - 0.005, 0.0)
|
||||
|
||||
println(currSpeed)
|
||||
return 0.0f
|
||||
}
|
||||
|
||||
override fun rotation(entity: PokemonEntity, driver: LivingEntity): Vec2 {
|
||||
@@ -55,12 +131,33 @@ class BirdAirController : RideController {
|
||||
}
|
||||
|
||||
override fun velocity(entity: PokemonEntity, driver: Player, input: Vec3): Vec3 {
|
||||
val f = driver.xxa * 0.2f
|
||||
var g = driver.zza
|
||||
if (g <= 0.0f) {
|
||||
g *= 0.25f
|
||||
|
||||
var yVel = 0.0
|
||||
var leftForce = 0.0
|
||||
var upForce = 0.0
|
||||
var forwardForce = 0.0
|
||||
val rollable = driver as? Rollable
|
||||
if( rollable != null ) {
|
||||
|
||||
|
||||
//yVel = sin(Math.toRadians(rollable.pitch.toDouble() - lastPitch ))*-10
|
||||
|
||||
|
||||
|
||||
lastPitch = rollable.pitch
|
||||
|
||||
//Need to deadzone this when straight up or down
|
||||
leftForce = -1.0 * sin(Math.toRadians( rollable.roll.toDouble() ) )
|
||||
|
||||
upForce = -1.0 * sin(Math.toRadians( rollable.pitch.toDouble() ))
|
||||
|
||||
forwardForce = cos(Math.toRadians( rollable.pitch.toDouble() ))
|
||||
}
|
||||
|
||||
//TODO: Add in an upwards and downwards force when pressing space maybe?
|
||||
|
||||
//Leave out tap to flap right now
|
||||
/*
|
||||
var jumpVector = Vec3.ZERO
|
||||
if (entity.jumpInputStrength > 0) {
|
||||
val runtime = getRuntime(entity)
|
||||
@@ -71,12 +168,152 @@ class BirdAirController : RideController {
|
||||
entity.jumpInputStrength = 0
|
||||
entity.addDeltaMovement(jumpVector)
|
||||
}
|
||||
*/
|
||||
|
||||
val velocity = Vec3(f.toDouble(), 0.0, g.toDouble())
|
||||
val velocity = Vec3(0.0 , upForce * currSpeed, forwardForce * currSpeed)
|
||||
|
||||
return velocity
|
||||
}
|
||||
|
||||
override fun angRollVel(entity: PokemonEntity, driver: Player, deltaTime: Double): Vec3 {
|
||||
|
||||
val rollable = driver as? Rollable
|
||||
|
||||
|
||||
val handling = entity.getRideStat( RidingStat.SKILL, RidingStyle.AIR, MINHANDLING, MAXHANDLING)
|
||||
val rotationChangeRate = 10.0
|
||||
|
||||
if( rollable != null )
|
||||
{
|
||||
var yawForce = rotationChangeRate * sin( Math.toRadians( rollable.roll.toDouble() ))
|
||||
//for a bit of correction on the rolls limit it to a quarter the amount
|
||||
var pitchForce = -0.25 * rotationChangeRate * abs(sin( Math.toRadians( rollable.roll.toDouble() )))
|
||||
|
||||
//limit rotation modulation when pitched up heavily or pitched down heavily
|
||||
yawForce *= abs(cos( Math.toRadians( rollable.pitch.toDouble() )))
|
||||
pitchForce *= abs(cos( Math.toRadians( rollable.pitch.toDouble() ))) * 1.5
|
||||
|
||||
//Create a deadzone for easier leveling out
|
||||
if( rollable.roll <= 0.0 && rollable.roll >= -0.0)
|
||||
{
|
||||
yawForce = 0.0
|
||||
pitchForce = 0.0
|
||||
}
|
||||
return Vec3( yawForce, pitchForce, 0.0)
|
||||
}
|
||||
|
||||
/*
|
||||
val rotLimit = 15.0
|
||||
|
||||
var rollForce = -1.0 * driver.xxa * rotationChangeRate
|
||||
|
||||
//TODO: Fix accumulated movement causing pitch and roll out of set bounds
|
||||
if( rollable != null ) {
|
||||
//If the roll or pitch have exceeded the limit then do not modulate that
|
||||
//rotation in that direction further
|
||||
|
||||
val rotLim = 30.0
|
||||
|
||||
rollForce *= 1.0.pow(-1.0 * (abs(rollable.roll.toDouble()) / rotLimit))
|
||||
|
||||
|
||||
if( rollable.roll >= rotLimit && rollForce > 0.0)
|
||||
{
|
||||
rollForce = 0.0;
|
||||
}
|
||||
if( rollable.roll <= -rotLimit && rollForce < 0.0)
|
||||
{
|
||||
rollForce = 0.0;
|
||||
}
|
||||
|
||||
//Ignore x,y,z its angular velocity:
|
||||
//yaw, pitch, roll
|
||||
return Vec3( 0.0, 0.0, rollForce)
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
return Vec3(0.0, 0.0, 0.0)
|
||||
}
|
||||
|
||||
override fun rotationOnMouseXY
|
||||
(entity: PokemonEntity,
|
||||
driver: Player,
|
||||
yMouse: Double,
|
||||
xMouse: Double,
|
||||
yMouseSmoother: SmoothDouble,
|
||||
xMouseSmoother: SmoothDouble,
|
||||
sensitivity: Double,
|
||||
deltaTime: Double ): Vec3
|
||||
{
|
||||
if(driver !is Rollable) return Vec3.ZERO
|
||||
|
||||
val rollable = driver as Rollable
|
||||
|
||||
val handling = entity.getRideStat( RidingStat.SKILL, RidingStyle.AIR, MINHANDLING, MAXHANDLING)
|
||||
|
||||
//var yMouse = yMouseSmoother.getNewDeltaValue(angVecMouse.y * 0.15f, d);
|
||||
//var xMouse = xMouseSmoother.getNewDeltaValue(cursorDeltaX * 0.15f, d);
|
||||
|
||||
var xInput = xMouseSmoother.getNewDeltaValue(xMouse * 0.1, deltaTime * 4);
|
||||
val YInput = yMouseSmoother.getNewDeltaValue(yMouse * 0.1, deltaTime * 4);
|
||||
|
||||
//limit rolling based on healing
|
||||
val rotLimit = handling * 1.5
|
||||
|
||||
if( abs( rollable.roll + xInput ) < rotLimit )
|
||||
{
|
||||
if( sign(xInput) == sign( rollable.roll ).toDouble() ) {
|
||||
val s = sign(rollable.roll)
|
||||
val d = abs(abs(rollable.roll) - rotLimit)
|
||||
xInput *= (d.pow(2)) / (rotLimit.pow(2))
|
||||
}
|
||||
}
|
||||
|
||||
//if( abs(rollable.roll) > rotLimit )
|
||||
else
|
||||
{
|
||||
val s = sign(rollable.roll)
|
||||
val d = abs(rollable.roll) - rotLimit
|
||||
if( sign(xInput) == sign( rollable.roll ).toDouble() ) {
|
||||
xInput = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if( xMouse > 0 )
|
||||
{
|
||||
if( rollable.roll > rotLimit )
|
||||
{
|
||||
//val adjustedX = 0.5* xMouse * ( (rotLimit - rollable.roll) / ( rotLimit) )
|
||||
return Vec3(0.0, YInput, 0.0 )
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return Vec3(0.0, YInput, xInput * -0.1 )
|
||||
}
|
||||
|
||||
}else{
|
||||
if( rollable.roll < -1.0 * rotLimit )
|
||||
{
|
||||
//val adjustedX = 0.5* xMouse * ( (rotLimit + rollable.roll) / ( rotLimit) )
|
||||
return Vec3(0.0, YInput, 0.0 )
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return Vec3(0.0, YInput, xInput * -0.1 )
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
//Ignore x,y,z its angular velocity:
|
||||
//yaw, pitch, roll
|
||||
return Vec3(0.0, YInput, xInput )
|
||||
}
|
||||
|
||||
override fun canJump(
|
||||
entity: PokemonEntity,
|
||||
driver: Player
|
||||
@@ -92,21 +329,24 @@ class BirdAirController : RideController {
|
||||
return Vec3.ZERO
|
||||
}
|
||||
|
||||
override fun gravity(entity: PokemonEntity, regularGravity: Double): Double? {
|
||||
return getRuntime(entity)
|
||||
.withQueryValue("gravity", DoubleValue(regularGravity))
|
||||
.resolveFloat(gravity)
|
||||
.toDouble()
|
||||
//Going to use my own gravity calculations for now.
|
||||
override fun gravity(entity: PokemonEntity, regularGravity: Double): Double {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
override fun shouldRoll(entity: PokemonEntity) = true
|
||||
|
||||
override fun useAngVelSmoothing(entity: PokemonEntity): Boolean = false
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
super.encode(buffer)
|
||||
buffer.writeString(gravity.toString())
|
||||
buffer.writeString(horizontalAcceleration.toString())
|
||||
buffer.writeString(verticalAcceleration.toString())
|
||||
buffer.writeString(speed.toString())
|
||||
buffer.writeDouble(this.lastVelocity.x)
|
||||
buffer.writeDouble(this.lastVelocity.y)
|
||||
buffer.writeDouble(this.lastVelocity.z)
|
||||
}
|
||||
|
||||
override fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
@@ -114,10 +354,30 @@ class BirdAirController : RideController {
|
||||
horizontalAcceleration = buffer.readString().asExpression()
|
||||
verticalAcceleration = buffer.readString().asExpression()
|
||||
speed = buffer.readString().asExpression()
|
||||
val x = buffer.readDouble()
|
||||
val y = buffer.readDouble()
|
||||
val z = buffer.readDouble()
|
||||
this.lastVelocity = Vec3(x, y, z)
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
val KEY = cobblemonResource("air/bird")
|
||||
|
||||
val MAXTOPSPEED = 1.0 // 20 bl/s
|
||||
val MINTOPSPEED = 0.35 // 7 bl/s
|
||||
//val MINSPEED = 0.25 // 5 bl/s
|
||||
|
||||
//Accel will lie between 1.0 second and 5.0 seconds
|
||||
val MAXACCEL = (MAXTOPSPEED ) / (20*3) //3.0 second to max speed
|
||||
val MINACCEL = (MAXTOPSPEED ) / (20*8) // 8 seconds to max speed
|
||||
|
||||
//Can rotate 90 degrees
|
||||
val MAXHANDLING = 90.0
|
||||
val MINHANDLING = 30.0
|
||||
|
||||
|
||||
val MAXYAWHANDLING = 16.0
|
||||
val MINYAWHANDLING = 8.0
|
||||
}
|
||||
}
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.pokemon.riding.controllers
|
||||
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.cobblemon.mod.common.Rollable
|
||||
import com.cobblemon.mod.common.api.riding.controller.RideController
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseOption
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseProvider
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
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
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class DolphinController : RideController {
|
||||
companion object {
|
||||
val KEY: ResourceLocation = cobblemonResource("swim/dolphin")
|
||||
}
|
||||
|
||||
var canJump = "true".asExpression()
|
||||
private set
|
||||
var jumpVector = listOf("0".asExpression(), "0.3".asExpression(), "0".asExpression())
|
||||
private set
|
||||
var speed = "1.0".asExpression()
|
||||
private set
|
||||
var driveFactor = "1.0".asExpression()
|
||||
private set
|
||||
var reverseDriveFactor = "0.25".asExpression()
|
||||
private set
|
||||
var strafeFactor = "0.2".asExpression()
|
||||
private set
|
||||
var lastVelocity = Vec3(0.0,0.0,0.0)
|
||||
private set
|
||||
|
||||
private val rollSmoother = SmoothDouble()
|
||||
|
||||
override val key: ResourceLocation = KEY
|
||||
override val poseProvider: PoseProvider = PoseProvider(PoseType.FLOAT)
|
||||
.with(PoseOption(PoseType.SWIM) { it.deltaMovement.length() >= 0.05 })
|
||||
override val condition: (PokemonEntity) -> Boolean = { entity ->
|
||||
|
||||
//If there are only fluid blocks or air block below the ride
|
||||
//or if the entity is in water then activate the controller
|
||||
Shapes.create(entity.boundingBox).blockPositionsAsListRounded().any {
|
||||
if (it.y.toDouble() == (entity.position().y)) {
|
||||
val blockState = entity.level().getBlockState(it.below())
|
||||
return@any (blockState.isAir || !blockState.fluidState.isEmpty ) ||
|
||||
(entity.isInWater || entity.isUnderWater)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun speed(entity: PokemonEntity, driver: Player): Float {
|
||||
return getRuntime(entity).resolveFloat(speed)
|
||||
}
|
||||
|
||||
override fun rotation(entity: PokemonEntity, driver: LivingEntity): Vec2 {
|
||||
return Vec2(driver.xRot * 0.5f, driver.yRot )
|
||||
}
|
||||
|
||||
override fun gravity(entity: PokemonEntity, regularGravity: Double): Double? {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
override fun inertia(entity: PokemonEntity ): Double
|
||||
{
|
||||
return 0.05
|
||||
}
|
||||
|
||||
override fun velocity(entity: PokemonEntity, driver: Player, input: Vec3): Vec3 {
|
||||
val runtime = getRuntime(entity)
|
||||
|
||||
if (!entity.isInWater && !entity.isUnderWater)
|
||||
{
|
||||
lastVelocity = Vec3(lastVelocity.x, lastVelocity.y - 0.035, lastVelocity.z)
|
||||
return lastVelocity
|
||||
}
|
||||
|
||||
val driveFactor = runtime.resolveFloat(this.driveFactor)
|
||||
val strafeFactor = runtime.resolveFloat(this.strafeFactor)
|
||||
val f = driver.xxa * strafeFactor
|
||||
var g = driver.zza * driveFactor
|
||||
if (g <= 0.0f) {
|
||||
g *= runtime.resolveFloat(this.reverseDriveFactor)
|
||||
}
|
||||
|
||||
var yComp = 0.0
|
||||
|
||||
//Get roll to add a left and right strafe during roll
|
||||
//Not sure if this is desired? Will need to mess around with this
|
||||
//a bit more
|
||||
var zComp = 0.0
|
||||
val rollable = driver as? Rollable
|
||||
if (rollable != null)
|
||||
{
|
||||
//Can be used again if I better figure out how to deadzone it near the tops?
|
||||
zComp = -1.0 * g.toDouble() * sin(Math.toRadians( rollable.roll.toDouble() ) )
|
||||
yComp = -1.0 * g.toDouble() * sin(Math.toRadians( rollable.pitch.toDouble() ) )
|
||||
}
|
||||
|
||||
val currVelocity = Vec3(0.0, yComp , g.toDouble())
|
||||
lastVelocity = currVelocity
|
||||
return currVelocity
|
||||
}
|
||||
|
||||
override fun angRollVel(entity: PokemonEntity, driver: Player, deltaTime: Double): Vec3 {
|
||||
|
||||
if (!entity.isInWater && !entity.isUnderWater)
|
||||
{
|
||||
return Vec3(0.0, 0.0, 0.0)
|
||||
}
|
||||
|
||||
val rollable = driver as? Rollable
|
||||
|
||||
//this should be changed to be speed maybe?
|
||||
val movingForce = driver.zza
|
||||
if( rollable != null ) {
|
||||
var yawAngVel = 3 * sin(Math.toRadians(rollable.roll.toDouble())).toFloat()
|
||||
var pitchAngVel = -1 * Math.abs(sin(Math.toRadians(rollable.roll.toDouble())).toFloat())
|
||||
|
||||
//limit rotation modulation when pitched up heavily or pitched down heavily
|
||||
yawAngVel *= (abs(cos(Math.toRadians(rollable.pitch.toDouble())))).toFloat()
|
||||
pitchAngVel *= (abs(cos(Math.toRadians(rollable.pitch.toDouble())))).toFloat()
|
||||
//if you are not pressing forward then don't turn
|
||||
//yawAngVel *= movingForce
|
||||
//Ignore x,y,z its angular velocity:
|
||||
//yaw, pitch, roll
|
||||
return Vec3(yawAngVel.toDouble(), pitchAngVel.toDouble(), 0.0)
|
||||
}
|
||||
|
||||
return Vec3(0.0, 0.0, 0.0)
|
||||
}
|
||||
|
||||
override fun canJump(entity: PokemonEntity, driver: Player) = getRuntime(entity).resolveBoolean(canJump)
|
||||
|
||||
override fun jumpForce(entity: PokemonEntity, driver: Player, jumpStrength: Int): Vec3 {
|
||||
val runtime = getRuntime(entity)
|
||||
runtime.environment.query.addFunction("jump_strength") { DoubleValue(jumpStrength.toDouble()) }
|
||||
val jumpVector = jumpVector.map { runtime.resolveFloat(it) }
|
||||
return Vec3(jumpVector[0].toDouble(), jumpVector[1].toDouble(), jumpVector[2].toDouble())
|
||||
}
|
||||
|
||||
override fun shouldRoll(entity: PokemonEntity) = true
|
||||
|
||||
override fun turnOffOnGround(entity: PokemonEntity): Boolean = true
|
||||
|
||||
override fun dismountOnShift(entity: PokemonEntity): Boolean = false
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
super.encode(buffer)
|
||||
buffer.writeString(this.speed.getString())
|
||||
buffer.writeString(this.canJump.getString())
|
||||
buffer.writeString(this.jumpVector[0].getString())
|
||||
buffer.writeString(this.jumpVector[1].getString())
|
||||
buffer.writeString(this.jumpVector[2].getString())
|
||||
buffer.writeString(this.driveFactor.getString())
|
||||
buffer.writeString(this.reverseDriveFactor.getString())
|
||||
buffer.writeString(this.strafeFactor.getString())
|
||||
buffer.writeDouble(this.lastVelocity.x)
|
||||
buffer.writeDouble(this.lastVelocity.y)
|
||||
buffer.writeDouble(this.lastVelocity.z)
|
||||
}
|
||||
|
||||
|
||||
override fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
this.speed = buffer.readString().asExpression()
|
||||
this.canJump = buffer.readString().asExpression()
|
||||
this.jumpVector = listOf(
|
||||
buffer.readString().asExpression(),
|
||||
buffer.readString().asExpression(),
|
||||
buffer.readString().asExpression()
|
||||
)
|
||||
this.driveFactor = buffer.readString().asExpression()
|
||||
this.reverseDriveFactor = buffer.readString().asExpression()
|
||||
this.strafeFactor = buffer.readString().asExpression()
|
||||
this.strafeFactor = buffer.readString().asExpression()
|
||||
val x = buffer.readDouble()
|
||||
val y = buffer.readDouble()
|
||||
val z = buffer.readDouble()
|
||||
this.lastVelocity = Vec3(x, y, z)
|
||||
}
|
||||
}
|
||||
+11
-3
@@ -74,7 +74,7 @@ class GenericLandController : RideController {
|
||||
}
|
||||
|
||||
override fun speed(entity: PokemonEntity, driver: Player): Float {
|
||||
return getRuntime(entity).resolveFloat(speed)
|
||||
return 0.0f
|
||||
}
|
||||
|
||||
override fun rotation(entity: PokemonEntity, driver: LivingEntity): Vec2 {
|
||||
@@ -82,6 +82,8 @@ class GenericLandController : RideController {
|
||||
}
|
||||
|
||||
override fun velocity(entity: PokemonEntity, driver: Player, input: Vec3): Vec3 {
|
||||
val currSpeed = 1.0
|
||||
|
||||
val runtime = getRuntime(entity)
|
||||
val driveFactor = runtime.resolveFloat(this.driveFactor)
|
||||
val strafeFactor = runtime.resolveFloat(this.strafeFactor)
|
||||
@@ -90,8 +92,8 @@ class GenericLandController : RideController {
|
||||
if (g <= 0.0f) {
|
||||
g *= runtime.resolveFloat(this.reverseDriveFactor)
|
||||
}
|
||||
|
||||
val velocity = Vec3(f.toDouble(), 0.0, g.toDouble())
|
||||
val gravity = -0.8
|
||||
val velocity = Vec3(f.toDouble() * currSpeed, gravity, g.toDouble()*0.7 * currSpeed)
|
||||
|
||||
return velocity
|
||||
}
|
||||
@@ -105,6 +107,12 @@ class GenericLandController : RideController {
|
||||
return Vec3(jumpVector[0].toDouble(), jumpVector[1].toDouble(), jumpVector[2].toDouble())
|
||||
}
|
||||
|
||||
override fun gravity(entity: PokemonEntity, regularGravity: Double): Double {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
override fun inertia(entity: PokemonEntity ): Double = 0.3
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
super.encode(buffer)
|
||||
buffer.writeString(this.speed.getString())
|
||||
|
||||
+3
@@ -9,9 +9,11 @@
|
||||
package com.cobblemon.mod.common.pokemon.riding.controllers
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.cobblemon.mod.common.api.riding.RidingStyle
|
||||
import com.cobblemon.mod.common.api.riding.controller.RideController
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseOption
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseProvider
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
@@ -54,6 +56,7 @@ class GliderAirController : RideController {
|
||||
val xVector = if (getRuntime(entity).resolveBoolean(canStrafe)) driver.xxa.toDouble() else 0.0
|
||||
val yVector = -getRuntime(entity).resolveDouble(glideSpeed)
|
||||
val zVector = driver.zza.toDouble()
|
||||
val statSpeed = entity.rideProp.calculate(RidingStat.SPEED, RidingStyle.AIR, 0 )
|
||||
|
||||
return Vec3(xVector, yVector, zVector)
|
||||
}
|
||||
|
||||
+131
-21
@@ -9,35 +9,48 @@
|
||||
package com.cobblemon.mod.common.pokemon.riding.controllers
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.cobblemon.mod.common.Rollable
|
||||
import com.cobblemon.mod.common.api.riding.controller.RideController
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseOption
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseProvider
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readString
|
||||
import com.cobblemon.mod.common.util.resolveDouble
|
||||
import com.cobblemon.mod.common.util.resolveFloat
|
||||
import com.cobblemon.mod.common.util.writeString
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
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 java.lang.Math.pow
|
||||
import kotlin.math.*
|
||||
|
||||
/**
|
||||
* Allows for flight like a bird controller, except you don't have to do any "flapping" motion,
|
||||
* you can just go up and down like creative
|
||||
*
|
||||
* @author Apion
|
||||
* @author Apion/Jackowes
|
||||
* @since January 1, 2025
|
||||
*/
|
||||
class HelicopterAirController : RideController {
|
||||
override val key = KEY
|
||||
override val poseProvider = PoseProvider(PoseType.HOVER)
|
||||
.with(PoseOption(PoseType.FLY) { it.deltaMovement.horizontalDistance() > 0.1 })
|
||||
override val condition: (PokemonEntity) -> Boolean = { true }
|
||||
|
||||
//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
|
||||
override val condition: (PokemonEntity) -> Boolean = { entity ->
|
||||
Shapes.create(entity.boundingBox).blockPositionsAsListRounded().any {
|
||||
if (it.y.toDouble() == (entity.position().y)) {
|
||||
val blockState = entity.level().getBlockState(it.below())
|
||||
return@any (blockState.isAir || !blockState.fluidState.isEmpty )
|
||||
}
|
||||
true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var gravity: Expression = "1.0".asExpression()
|
||||
private set
|
||||
@@ -48,8 +61,12 @@ class HelicopterAirController : RideController {
|
||||
var speed: Expression = "1.0".asExpression()
|
||||
private set
|
||||
|
||||
|
||||
override fun speed(entity: PokemonEntity, driver: Player): Float {
|
||||
return getRuntime(entity).resolveFloat(speed)
|
||||
//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
|
||||
return 2.0f
|
||||
}
|
||||
|
||||
override fun rotation(entity: PokemonEntity, driver: LivingEntity): Vec2 {
|
||||
@@ -58,21 +75,90 @@ class HelicopterAirController : RideController {
|
||||
|
||||
override fun velocity(entity: PokemonEntity, driver: Player, input: Vec3): Vec3 {
|
||||
val runtime = getRuntime(entity)
|
||||
val f = driver.xxa * 0.2f
|
||||
var g = driver.zza
|
||||
if (g <= 0.0f) {
|
||||
g *= 0.25f
|
||||
|
||||
//If the player is not modulating height then hover
|
||||
var yVel = if (driver.jumping) runtime.resolveDouble(verticalVelocity)
|
||||
else if (driver.isShiftKeyDown) -runtime.resolveDouble(verticalVelocity)
|
||||
else (0.0)
|
||||
|
||||
yVel *= 0.25
|
||||
var xVel = 0.0
|
||||
var zVel = 0.0
|
||||
|
||||
val rollable = driver as? Rollable
|
||||
|
||||
//Horizontal velocity is based on pitch and roll
|
||||
if( rollable != null ) {
|
||||
xVel = -1.0 * sin(Math.toRadians(rollable.roll.toDouble()))
|
||||
zVel = sin(Math.toRadians(rollable.pitch.toDouble()))
|
||||
}
|
||||
|
||||
val yVel = if (driver.jumping) runtime.resolveDouble(verticalVelocity)
|
||||
else if (driver.isShiftKeyDown) -runtime.resolveDouble(verticalVelocity)
|
||||
else (entity.gravity)
|
||||
|
||||
val velocity = Vec3(f.toDouble(), yVel, g.toDouble())
|
||||
|
||||
return velocity
|
||||
return Vec3(xVel, yVel, zVel)
|
||||
}
|
||||
|
||||
|
||||
override fun angRollVel(entity: PokemonEntity, driver: Player, deltaTime: Double): Vec3 {
|
||||
|
||||
val rollable = driver as? Rollable
|
||||
|
||||
//In degrees per second? It was supposed to be I think but
|
||||
//I have messed something up
|
||||
val rotationChangeRate = 2.0
|
||||
val rotLimit = 30.0
|
||||
|
||||
var pitchForce = driver.zza * rotationChangeRate
|
||||
var rollForce = -1.0 * driver.xxa * rotationChangeRate
|
||||
|
||||
|
||||
//TODO: Fix accumulated movement causing pitch and roll out of set bounds
|
||||
if( rollable != null ) {
|
||||
//If the roll or pitch have exceeded the limit then do not modulate that
|
||||
//rotation in that direction further
|
||||
|
||||
//modulate the forces so that they trend towards 0 as they approach rotation limit.
|
||||
//The current function has it drop off very quickly which may not be ideal.
|
||||
//Prev function:
|
||||
// pitchForce = pitchForce * max(rotLim - abs( rollable.pitch.toDouble() ), 0.0)
|
||||
|
||||
//The three denotes that the force will be 1/3 what it would have been at
|
||||
//the rotation limit
|
||||
rollForce *= 2.0.pow(-1.0 * (abs(rollable.roll.toDouble()) / ROTATION_LIMIT))
|
||||
|
||||
pitchForce *= 2.0.pow(-1.0 * (abs(rollable.pitch.toDouble()) / ROTATION_LIMIT))
|
||||
|
||||
if( rollable.roll >= ROTATION_LIMIT && rollForce > 0.0)
|
||||
{
|
||||
rollForce = 0.0;
|
||||
}
|
||||
if( rollable.roll <= -ROTATION_LIMIT && rollForce < 0.0)
|
||||
{
|
||||
rollForce = 0.0;
|
||||
}
|
||||
if( rollable.pitch >= ROTATION_LIMIT && pitchForce > 0.0 )
|
||||
{
|
||||
pitchForce = 0.0;
|
||||
}
|
||||
if( rollable.pitch <= -ROTATION_LIMIT && pitchForce < 0.0 )
|
||||
{
|
||||
pitchForce = 0.0;
|
||||
}
|
||||
|
||||
//Ignore x,y,z its angular velocity:
|
||||
//yaw, pitch, roll
|
||||
return Vec3( 0.0, pitchForce.toDouble(), rollForce)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return Vec3(0.0, 0.0, 0.0)
|
||||
}
|
||||
|
||||
override fun useAngVelSmoothing(entity: PokemonEntity): Boolean = true
|
||||
|
||||
|
||||
override fun inertia(entity: PokemonEntity ): Double = 0.1
|
||||
|
||||
override fun canJump(
|
||||
entity: PokemonEntity,
|
||||
driver: Player
|
||||
@@ -88,10 +174,33 @@ class HelicopterAirController : RideController {
|
||||
return Vec3.ZERO
|
||||
}
|
||||
|
||||
override fun gravity(entity: PokemonEntity, regularGravity: Double): Double? {
|
||||
override fun shouldRoll(entity: PokemonEntity): Boolean = true
|
||||
|
||||
override fun rotationOnMouseXY
|
||||
(entity: PokemonEntity,
|
||||
driver: Player,
|
||||
yMouse: Double,
|
||||
xMouse: Double,
|
||||
yMouseSmoother: SmoothDouble,
|
||||
xMouseSmoother: SmoothDouble,
|
||||
sensitivity: Double,
|
||||
deltaTime: Double ): Vec3
|
||||
{
|
||||
if(driver !is Rollable) return Vec3.ZERO
|
||||
|
||||
val rollable = driver as Rollable
|
||||
//Ignore x,y,z its angular velocity:
|
||||
//yaw, pitch, roll
|
||||
return Vec3(xMouse, 0.0, 0.0 )
|
||||
}
|
||||
|
||||
override fun gravity(entity: PokemonEntity, regularGravity: Double): Double {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
//Need to ensure that crouching lowers altitude and doesn't eject the player
|
||||
override fun dismountOnShift(entity: PokemonEntity): Boolean = false
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
super.encode(buffer)
|
||||
buffer.writeString(gravity.toString())
|
||||
@@ -110,5 +219,6 @@ class HelicopterAirController : RideController {
|
||||
|
||||
companion object {
|
||||
val KEY = cobblemonResource("air/helicopter")
|
||||
val ROTATION_LIMIT = 30.0f
|
||||
}
|
||||
}
|
||||
+300
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.pokemon.riding.controllers
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.cobblemon.mod.common.Rollable
|
||||
import com.cobblemon.mod.common.api.riding.RidingStyle
|
||||
import com.cobblemon.mod.common.api.riding.controller.RideController
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseOption
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseProvider
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokemon.riding.controllers.HelicopterAirController.Companion.ROTATION_LIMIT
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
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 kotlin.math.*
|
||||
|
||||
class JetAirController : RideController {
|
||||
override val key = KEY
|
||||
override val poseProvider = PoseProvider(PoseType.HOVER)
|
||||
.with(PoseOption(PoseType.FLY) { it.deltaMovement.length() > 0 })
|
||||
|
||||
override val condition: (PokemonEntity) -> Boolean = { true }
|
||||
|
||||
var jumpVector = listOf("0".asExpression(), "0.3".asExpression(), "0".asExpression())
|
||||
private set
|
||||
var gravity: Expression = "0".asExpression()
|
||||
private set
|
||||
var horizontalAcceleration: Expression = "0.1".asExpression()
|
||||
private set
|
||||
var verticalAcceleration: Expression = "0.1".asExpression()
|
||||
private set
|
||||
var speed: Expression = "1.0".asExpression()
|
||||
private set
|
||||
var lastVelocity = Vec3(0.0,0.0,0.0)
|
||||
private set
|
||||
var maxSpeed = 0.4
|
||||
private set
|
||||
|
||||
var lastPitch = 0.0f
|
||||
private set
|
||||
|
||||
var currSpeed = MINSPEED
|
||||
private set
|
||||
|
||||
var currMouseXForce = 0.0
|
||||
private set
|
||||
|
||||
var currMouseYForce = 0.0
|
||||
private set
|
||||
|
||||
override fun speed(entity: PokemonEntity, driver: Player): Float {
|
||||
//0 boost so just the base value.
|
||||
//This should be a function in pokemonEntity.kt so it can easily be called.
|
||||
val speedStat = entity.rideProp.calculate(RidingStat.SPEED, RidingStyle.AIR, 0 )
|
||||
//now calculate the true top speed value using the speed stat
|
||||
val topSpeed = (((MAXTOPSPEED - MINTOPSPEED) / 100) * speedStat) + MINTOPSPEED
|
||||
|
||||
val accelStat = entity.rideProp.calculate(RidingStat.ACCELERATION, RidingStyle.AIR, 0 )
|
||||
val accel = (((MAXACCEL - MINACCEL) / 100) * accelStat) + MINACCEL
|
||||
|
||||
val drivingForce = if ( Minecraft.getInstance().options.keySprint.isDown() ) 1.0
|
||||
else if (driver.isShiftKeyDown) -1.0
|
||||
else(0.0)
|
||||
|
||||
//speed up and slow down based on input
|
||||
if( driver.zza > 0.0 && currSpeed < topSpeed)
|
||||
{
|
||||
currSpeed = min( currSpeed + accel , topSpeed)
|
||||
}
|
||||
else if ( driver.zza < 0.0 && currSpeed > MINSPEED)
|
||||
{
|
||||
//Decelerate is now always a constant half of max acceleration.
|
||||
currSpeed = max( currSpeed - (MAXACCEL / 2) , MINSPEED)
|
||||
}
|
||||
|
||||
return currSpeed.toFloat()
|
||||
}
|
||||
|
||||
override fun rotation(entity: PokemonEntity, driver: LivingEntity): Vec2 {
|
||||
return Vec2(driver.xRot * 0.5f, driver.yRot)
|
||||
}
|
||||
|
||||
override fun velocity(entity: PokemonEntity, driver: Player, input: Vec3): Vec3 {
|
||||
|
||||
var yVel = 0.0
|
||||
var leftForce = 0.0
|
||||
var upForce = 0.0
|
||||
var forwardForce = 0.0
|
||||
val rollable = driver as? Rollable
|
||||
if( rollable != null ) {
|
||||
|
||||
|
||||
yVel = sin(Math.toRadians(rollable.pitch.toDouble() - lastPitch ))*-10
|
||||
|
||||
lastPitch = rollable.pitch
|
||||
|
||||
leftForce = -1.0 * sin(Math.toRadians( rollable.roll.toDouble() ) )
|
||||
|
||||
upForce = -1.0 * sin(Math.toRadians( rollable.pitch.toDouble() ))
|
||||
//limit how fast you can descend?
|
||||
upForce *= 1.0
|
||||
forwardForce = cos(Math.toRadians( rollable.pitch.toDouble() ))
|
||||
}
|
||||
val velocity = Vec3(0.0 , (upForce)* currSpeed, forwardForce * currSpeed)
|
||||
|
||||
//entity.setDeltaMovement(velocity)
|
||||
|
||||
return velocity
|
||||
}
|
||||
|
||||
override fun useAngVelSmoothing(entity: PokemonEntity): Boolean = true
|
||||
|
||||
override fun angRollVel(entity: PokemonEntity, driver: Player, deltaTime: Double): Vec3 {
|
||||
|
||||
//Get handling in degrees per second
|
||||
val handlingStat = entity.rideProp.calculate(RidingStat.SKILL, RidingStyle.AIR, 0 )
|
||||
//var handling = (((MAXHANDLING - MINHANDLING) / 100) * handlingStat) + MINHANDLING
|
||||
var handlingYaw = (((MAXYAWHANDLING - MINYAWHANDLING) / 100) * handlingStat) + MINYAWHANDLING
|
||||
|
||||
//convert it to partial ticks
|
||||
handlingYaw *= (deltaTime)
|
||||
|
||||
//A+D to yaw
|
||||
val yawForce = -2.0 * driver.xxa * handlingYaw
|
||||
|
||||
return Vec3( yawForce, 0.0, 0.0)
|
||||
}
|
||||
|
||||
override fun rotationOnMouseXY
|
||||
(entity: PokemonEntity,
|
||||
driver: Player,
|
||||
yMouse: Double,
|
||||
xMouse: Double,
|
||||
yMouseSmoother: SmoothDouble,
|
||||
xMouseSmoother: SmoothDouble,
|
||||
sensitivity: Double,
|
||||
deltaTime: Double ): Vec3
|
||||
{
|
||||
if(driver !is Rollable) return Vec3.ZERO
|
||||
|
||||
//Cap at a rate of 5fps so frame skips dont lead to huge jumps
|
||||
val cappedDeltaTime = min( deltaTime, 0.2)
|
||||
|
||||
|
||||
// Accumulate the mouse input
|
||||
currMouseXForce = (currMouseXForce + ( 0.0015 * xMouse )).coerceIn(-1.0, 1.0)
|
||||
currMouseYForce = (currMouseYForce + ( 0.0015 * yMouse )).coerceIn(-1.0, 1.0)
|
||||
|
||||
//Get handling in degrees per second
|
||||
val handlingStat = entity.rideProp.calculate(RidingStat.SKILL, RidingStyle.AIR, 0 )
|
||||
var handling = (((MAXHANDLING - MINHANDLING) / 100) * handlingStat) + MINHANDLING
|
||||
|
||||
//convert it to partial ticks
|
||||
handling *= (deltaTime)
|
||||
|
||||
val poke = driver.vehicle as? PokemonEntity
|
||||
|
||||
|
||||
|
||||
//val pitchRot = min( handling, max(-handling, yMouse ) )
|
||||
|
||||
//increase on an amount.
|
||||
|
||||
//if its below 0.2 it should be zero force.
|
||||
// And then between 0.2-1.0 it should map to a value between 0.0 and 1.0
|
||||
//val yInput = if(currMouseYForce < 0.2) 0.0 else ( ( currMouseYForce - 0.2 ) / 0.8)
|
||||
//val xInput = if(currMouseXForce < 0.2) 0.0 else ( ( currMouseXForce - 0.2 ) / 0.8)
|
||||
|
||||
//create deadzones for the constant input values.
|
||||
val xInput = remapWithDeadzone(currMouseXForce, 0.025, 1.0)
|
||||
val yInput = remapWithDeadzone(currMouseYForce, 0.025, 1.0)
|
||||
|
||||
val pitchRot = handling * currMouseYForce
|
||||
//double roll
|
||||
val rollRot = handling * 1.5 * currMouseXForce
|
||||
|
||||
//mult by 2 so you can roll twice as fast as you can pitch.
|
||||
//val rollRot = min( handling*2, max(-handling*2, xMouse ) )
|
||||
|
||||
//Ignore x,y,z its angular velocity:
|
||||
//yaw, pitch, roll
|
||||
return Vec3(0.0, pitchRot, rollRot)
|
||||
}
|
||||
|
||||
override fun fuelBar(entity: PokemonEntity, driver: Player): Float {
|
||||
return 0.5f
|
||||
}
|
||||
|
||||
override fun canJump(
|
||||
entity: PokemonEntity,
|
||||
driver: Player
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun jumpForce(
|
||||
entity: PokemonEntity,
|
||||
driver: Player,
|
||||
jumpStrength: Int
|
||||
): Vec3 {
|
||||
return Vec3.ZERO
|
||||
}
|
||||
|
||||
//Going to use my own gravity calculations for now.
|
||||
override fun gravity(entity: PokemonEntity, regularGravity: Double): Double {
|
||||
|
||||
var grav = 0.0
|
||||
|
||||
if( maxSpeed <= 0.5 ) grav = 0.5 - maxSpeed
|
||||
|
||||
return grav
|
||||
}
|
||||
|
||||
|
||||
override fun shouldRoll(entity: PokemonEntity) = true
|
||||
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
super.encode(buffer)
|
||||
buffer.writeString(gravity.toString())
|
||||
buffer.writeString(horizontalAcceleration.toString())
|
||||
buffer.writeString(verticalAcceleration.toString())
|
||||
buffer.writeString(speed.toString())
|
||||
buffer.writeDouble(maxSpeed)
|
||||
buffer.writeDouble(this.lastVelocity.x)
|
||||
buffer.writeDouble(this.lastVelocity.y)
|
||||
buffer.writeDouble(this.lastVelocity.z)
|
||||
}
|
||||
|
||||
override fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
gravity = buffer.readString().asExpression()
|
||||
horizontalAcceleration = buffer.readString().asExpression()
|
||||
verticalAcceleration = buffer.readString().asExpression()
|
||||
speed = buffer.readString().asExpression()
|
||||
this.maxSpeed = buffer.readDouble()
|
||||
val x = buffer.readDouble()
|
||||
val y = buffer.readDouble()
|
||||
val z = buffer.readDouble()
|
||||
this.lastVelocity = Vec3(x, y, z)
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
val KEY = cobblemonResource("air/jet")
|
||||
//I need a top and a bottom for the speed stat
|
||||
// I need a minimum speed stat for this ride specifically so that it caps
|
||||
// at this or slows below it and falls
|
||||
// 32 bl/s and 8 bl/s
|
||||
// min is 4 bl/s
|
||||
val MAXTOPSPEED = 2.5 // 50 bl/s
|
||||
val MINTOPSPEED = 0.35 // 7 bl/s
|
||||
val MINSPEED = 0.25 // 5 bl/s
|
||||
|
||||
//Accel will lie between 1.0 second and 5.0 seconds
|
||||
val MAXACCEL = (MAXTOPSPEED - MINSPEED) / 20 //1.0 second to max speed
|
||||
val MINACCEL = (MAXTOPSPEED - MINSPEED) / (20*5) // 5 seconds to max speed
|
||||
|
||||
//full 180 in 1 second.
|
||||
//30 degrees in 1 second.
|
||||
val MAXHANDLING = 140.0
|
||||
val MINHANDLING = 20.0
|
||||
|
||||
|
||||
val MAXYAWHANDLING = 16.0
|
||||
val MINYAWHANDLING = 8.0
|
||||
|
||||
//Fuel measured by seconds at full throttle.
|
||||
//minimum speed will consume a quarter of the fuel.
|
||||
//val MAXSTAMINA =
|
||||
}
|
||||
|
||||
//helper functions
|
||||
|
||||
//Creates a deadzone around zero that extends out to deadzoneLow in both +- and then remaps
|
||||
//the value linearly between -1.0 and 1.0 outside of the deadzone
|
||||
fun remapWithDeadzone(value: Double, deadzoneLow: Double = 0.2, deadzoneHigh: Double = 1.0): Double {
|
||||
// If the absolute value is below the deadzone, return 0.
|
||||
if (kotlin.math.abs(value) < deadzoneLow) return 0.0
|
||||
// Otherwise, subtract the deadzone and remap the remaining range to 0-1 (preserving the sign).
|
||||
val sign = kotlin.math.sign(value)
|
||||
val adjusted = (kotlin.math.abs(value) - deadzoneLow) / (deadzoneHigh - deadzoneLow)
|
||||
//Attach the sign back to the vale
|
||||
return adjusted * sign
|
||||
}
|
||||
}
|
||||
+36
-1
@@ -24,6 +24,7 @@ import com.cobblemon.mod.common.util.readString
|
||||
import com.cobblemon.mod.common.util.resolveInt
|
||||
import com.cobblemon.mod.common.util.writeString
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.util.SmoothDouble
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.phys.Vec2
|
||||
@@ -90,7 +91,13 @@ class RunUpToFlightCompositeController : RideController {
|
||||
return getActiveController(entity).velocity(entity, driver, input)
|
||||
}
|
||||
|
||||
override fun canJump(entity: PokemonEntity, driver: Player) = true
|
||||
override fun angRollVel(entity: PokemonEntity, driver: Player, deltaTime: Double): Vec3 {
|
||||
return getActiveController(entity).angRollVel(entity, driver, deltaTime)
|
||||
}
|
||||
|
||||
override fun canJump(entity: PokemonEntity, driver: Player): Boolean {
|
||||
return getActiveController(entity).canJump(entity, driver)
|
||||
}
|
||||
|
||||
override fun jumpForce(
|
||||
entity: PokemonEntity,
|
||||
@@ -112,8 +119,36 @@ class RunUpToFlightCompositeController : RideController {
|
||||
return getActiveController(entity).gravity(entity, regularGravity)
|
||||
}
|
||||
|
||||
override fun inertia(entity: PokemonEntity): Double {
|
||||
return getActiveController(entity).inertia(entity)
|
||||
}
|
||||
|
||||
override fun shouldRoll(entity: PokemonEntity): Boolean = getActiveController(entity).shouldRoll(entity)
|
||||
|
||||
override fun useAngVelSmoothing(entity: PokemonEntity): Boolean = getActiveController(entity).useAngVelSmoothing(entity)
|
||||
|
||||
override fun rotationOnMouseXY
|
||||
(entity: PokemonEntity,
|
||||
driver: Player,
|
||||
yMouse: Double,
|
||||
xMouse: Double,
|
||||
yMouseSmoother: SmoothDouble,
|
||||
xMouseSmoother: SmoothDouble,
|
||||
sensitivity: Double,
|
||||
deltaTime: Double ): Vec3
|
||||
{
|
||||
return getActiveController(entity).rotationOnMouseXY(entity,
|
||||
driver,
|
||||
yMouse,
|
||||
xMouse,
|
||||
yMouseSmoother,
|
||||
xMouseSmoother,
|
||||
sensitivity,
|
||||
deltaTime )
|
||||
}
|
||||
|
||||
override fun dismountOnShift(entity: PokemonEntity): Boolean = getActiveController(entity).dismountOnShift(entity)
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
super.encode(buffer)
|
||||
buffer.writeString(minimumSpeed.getString())
|
||||
|
||||
+49
-3
@@ -9,11 +9,14 @@
|
||||
package com.cobblemon.mod.common.pokemon.riding.controllers
|
||||
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.cobblemon.mod.common.api.riding.RidingStyle
|
||||
import com.cobblemon.mod.common.api.riding.controller.RideController
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseOption
|
||||
import com.cobblemon.mod.common.api.riding.controller.posing.PoseProvider
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokemon.riding.controllers.BirdAirController.Companion
|
||||
import com.cobblemon.mod.common.util.asExpression
|
||||
import com.cobblemon.mod.common.util.blockPositionsAsListRounded
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
@@ -31,10 +34,28 @@ 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
|
||||
|
||||
class VehicleLandController : RideController {
|
||||
companion object {
|
||||
val KEY: ResourceLocation = cobblemonResource("land/vehicle")
|
||||
|
||||
val MAXTOPSPEED = 1.0 // 20 bl/s
|
||||
val MINTOPSPEED = 0.35 // 7 bl/s
|
||||
//val MINSPEED = 0.25 // 5 bl/s
|
||||
|
||||
//Accel will lie between 1.0 second and 5.0 seconds
|
||||
val MAXACCEL = (MAXTOPSPEED ) / (20*3) //3.0 second to max speed
|
||||
val MINACCEL = (MAXTOPSPEED ) / (20*8) // 8 seconds to max speed
|
||||
|
||||
//Can rotate 90 degrees
|
||||
val MAXHANDLING = 90.0
|
||||
val MINHANDLING = 30.0
|
||||
|
||||
|
||||
val MAXYAWHANDLING = 16.0
|
||||
val MINYAWHANDLING = 8.0
|
||||
}
|
||||
|
||||
var canJump = "true".asExpression()
|
||||
@@ -55,6 +76,9 @@ class VehicleLandController : RideController {
|
||||
var lookYawLimit = "101".asExpression()
|
||||
private set
|
||||
|
||||
var currSpeed = 0.0
|
||||
private set
|
||||
|
||||
@Transient
|
||||
override val key: ResourceLocation = KEY
|
||||
@Transient
|
||||
@@ -72,14 +96,36 @@ class VehicleLandController : RideController {
|
||||
//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() == (entity.position().y)) {
|
||||
val blockState = entity.level().getBlockState(it.below())
|
||||
return@any !blockState.isAir && blockState.fluidState.isEmpty
|
||||
return@any !(!blockState.isAir && blockState.fluidState.isEmpty)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun speed(entity: PokemonEntity, driver: Player): Float {
|
||||
return getRuntime(entity).resolveFloat(speed)
|
||||
|
||||
val topSpeed = entity.getRideStat( RidingStat.SPEED, RidingStyle.AIR,
|
||||
VehicleLandController.MINTOPSPEED,
|
||||
VehicleLandController.MAXTOPSPEED
|
||||
)
|
||||
val accel = entity.getRideStat( RidingStat.ACCELERATION, RidingStyle.AIR,
|
||||
VehicleLandController.MINACCEL,
|
||||
VehicleLandController.MAXACCEL
|
||||
)
|
||||
|
||||
//speed up and slow down based on input
|
||||
if( driver.zza > 0.0 && currSpeed < topSpeed)
|
||||
{
|
||||
currSpeed = min( currSpeed + accel , topSpeed)
|
||||
}
|
||||
else if ( driver.zza < 0.0 && currSpeed > 0.0)
|
||||
{
|
||||
//Decelerate is now always a constant half of max acceleration.
|
||||
currSpeed = max( currSpeed - (BirdAirController.MAXACCEL / 2) , 0.0)
|
||||
}
|
||||
|
||||
|
||||
return currSpeed.toFloat()
|
||||
}
|
||||
|
||||
override fun rotation(entity: PokemonEntity, driver: LivingEntity): Vec2 {
|
||||
@@ -97,7 +143,7 @@ class VehicleLandController : RideController {
|
||||
if (driver.xxa != 0F && g.absoluteValue < runtime.resolveFloat(this.minimumSpeedToTurn)) {
|
||||
driver.xxa = 0F
|
||||
}
|
||||
val velocity = Vec3(0.0 /* Maybe do drifting here later */, 0.0, g.toDouble())
|
||||
val velocity = Vec3(0.0 /* Maybe do drifting here later */, 0.0, g.toDouble() * currSpeed)
|
||||
|
||||
return velocity
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ object IntRangeAdapter : JsonSerializer<IntRange>, JsonDeserializer<IntRange> {
|
||||
}
|
||||
|
||||
override fun deserialize(json: JsonElement, type: Type, context: JsonDeserializationContext): IntRange {
|
||||
val value = json.asString
|
||||
println("Deserializing IntRange from: $value")
|
||||
val (start, end) = PATTERN.find(json.asString)!!.destructured
|
||||
return if (end.isEmpty()) {
|
||||
IntRange(start.toInt(), start.toInt())
|
||||
|
||||
+4
-1
@@ -33,7 +33,10 @@ object RideControllerAdapter : JsonDeserializer<RideController> {
|
||||
HelicopterAirController.KEY to HelicopterAirController::class.java,
|
||||
GliderAirController.KEY to GliderAirController::class.java,
|
||||
FallToFlightCompositeController.KEY to FallToFlightCompositeController::class.java,
|
||||
VehicleLandController.KEY to VehicleLandController::class.java
|
||||
VehicleLandController.KEY to VehicleLandController::class.java,
|
||||
DolphinController.KEY to DolphinController::class.java,
|
||||
JetAirController.KEY to JetAirController::class.java
|
||||
|
||||
)
|
||||
|
||||
override fun deserialize(element: JsonElement, type: Type, context: JsonDeserializationContext): RideController {
|
||||
|
||||
+34
-13
@@ -6,26 +6,32 @@
|
||||
"bones": {
|
||||
"arm_left": {
|
||||
"rotation": [
|
||||
"math.r2d(-math.cos(v.limb_swing * 38.17) * v.limb_swing_amount - math.sin(v.age_in_ticks * 5.16) * 0.05)",
|
||||
0,
|
||||
"-math.r2d(math.cos(v.age_in_ticks * 5.16) * 0.05 + 0.05)"
|
||||
"-23.2941+math.r2d(-math.cos(v.limb_swing * 38.17) * v.limb_swing_amount - math.sin(v.age_in_ticks * 5.16) * 0.05)",
|
||||
3.57079,
|
||||
"6.5998-math.r2d(math.cos(v.age_in_ticks * 5.16) * 0.05 + 0.05)"
|
||||
]
|
||||
},
|
||||
"arm_right": {
|
||||
"rotation": [
|
||||
"math.r2d(math.cos(v.limb_swing * 38.17) * v.limb_swing_amount + math.sin(v.age_in_ticks * 5.16) * 0.05)",
|
||||
0,
|
||||
"math.r2d(math.cos(v.age_in_ticks * 5.16) * 0.05 + 0.05)"
|
||||
"-20.8359+math.r2d(math.cos(v.limb_swing * 38.17) * v.limb_swing_amount + math.sin(v.age_in_ticks * 5.16) * 0.05)",
|
||||
-2.68108,
|
||||
"-7.007+math.r2d(math.cos(v.age_in_ticks * 5.16) * 0.05 + 0.05)"
|
||||
]
|
||||
},
|
||||
"pokeball": {
|
||||
"scale": 0
|
||||
},
|
||||
"leg_right": {
|
||||
"rotation": ["math.r2d(math.cos(v.limb_swing * 38.17 + 180) * v.limb_swing_amount * 1.4)", 0, 0]
|
||||
"rotation": ["-87.8218+math.r2d(math.cos(v.limb_swing * 38.17 + 180) * v.limb_swing_amount * 1.4)", 8.11827, 0.65893]
|
||||
},
|
||||
"leg_left": {
|
||||
"rotation": ["math.r2d(math.cos(v.limb_swing * 38.17) * v.limb_swing_amount * 1.4)", 0, 0]
|
||||
"rotation": ["-88.8357+math.r2d(math.cos(v.limb_swing * 38.17) * v.limb_swing_amount * 1.4)", -8.23239, 1.90829]
|
||||
},
|
||||
"body": {
|
||||
"rotation": [0, 0, 0]
|
||||
},
|
||||
"head": {
|
||||
"rotation": ["7.5-v.velocity*10", 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -124,8 +130,14 @@
|
||||
},
|
||||
"pokeball": {
|
||||
"scale": {
|
||||
"0.4583": {"pre": [0, 0, 0], "post": [0.3, 0.3, 0.3]},
|
||||
"0.5417": {"pre": [0.3, 0.3, 0.3], "post": [0.3, 0.3, 0.3]},
|
||||
"0.4583": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.3, 0.3, 0.3]
|
||||
},
|
||||
"0.5417": {
|
||||
"pre": [0.3, 0.3, 0.3],
|
||||
"post": [0.3, 0.3, 0.3]
|
||||
},
|
||||
"0.7083": [1, 1, 1]
|
||||
}
|
||||
},
|
||||
@@ -622,12 +634,21 @@
|
||||
},
|
||||
"pokeball": {
|
||||
"scale": {
|
||||
"0.9375": {"pre": [0, 0, 0], "post": [0.3, 0.3, 0.3]},
|
||||
"1.0": {"pre": [0.3, 0.3, 0.3], "post": [0.3, 0.3, 0.3]},
|
||||
"0.9375": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.3, 0.3, 0.3]
|
||||
},
|
||||
"1.0": {
|
||||
"pre": [0.3, 0.3, 0.3],
|
||||
"post": [0.3, 0.3, 0.3]
|
||||
},
|
||||
"1.1875": [1, 1, 1],
|
||||
"3.0625": [1, 1, 1],
|
||||
"3.25": [0.4, 0.4, 0.4],
|
||||
"3.375": {"pre": [0.4, 0.4, 0.4], "post": [0, 0, 0]}
|
||||
"3.375": {
|
||||
"pre": [0.4, 0.4, 0.4],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"leg_right": {
|
||||
|
||||
+364
-91
@@ -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": {
|
||||
@@ -19097,23 +19235,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 +22632,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 +26306,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 +29598,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 +29941,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": {
|
||||
@@ -32994,19 +33237,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 +34699,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]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-7
@@ -105,7 +105,7 @@
|
||||
},
|
||||
"animation.pidgeot.air_idle": {
|
||||
"loop": true,
|
||||
"animation_length": 1.33333,
|
||||
"animation_length": 1.3333,
|
||||
"bones": {
|
||||
"body": {
|
||||
"rotation": ["-10+math.sin(q.anim_time*90*3-60)*-1", 0, 0],
|
||||
@@ -116,7 +116,8 @@
|
||||
},
|
||||
"wing_closed_left": {
|
||||
"rotation": [-93.47882, -7.48957, -87.29442],
|
||||
"position": [0, -1, 6]
|
||||
"position": [-3.8, -1, 6],
|
||||
"scale": 0.1
|
||||
},
|
||||
"wing_closed_left2": {
|
||||
"rotation": [5.08957, -4.43385, -2.31336]
|
||||
@@ -381,7 +382,8 @@
|
||||
},
|
||||
"wing_closed_right": {
|
||||
"rotation": [-93.47882, 7.48957, 87.29442],
|
||||
"position": [0, -1, 6]
|
||||
"position": [3.8, -1, 6],
|
||||
"scale": 0.1
|
||||
},
|
||||
"wing_closed_right2": {
|
||||
"rotation": [5.08957, 4.43385, 2.31336]
|
||||
@@ -548,8 +550,9 @@
|
||||
"rotation": ["-17.5+math.sin(q.anim_time*90*0.8-90)*-1", 0, "0+math.sin(q.anim_time*90*0.5-120)*1"]
|
||||
},
|
||||
"wing_closed_left": {
|
||||
"rotation": [-92.46677, -7.8791, -94.85228],
|
||||
"position": [0, -1, 6]
|
||||
"rotation": [-93.47882, -7.48957, -87.29442],
|
||||
"position": [-3.8, -1, 6],
|
||||
"scale": 0.1
|
||||
},
|
||||
"wing_closed_left2": {
|
||||
"rotation": [5.08145, 3.03671, -1.64897]
|
||||
@@ -687,8 +690,9 @@
|
||||
"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"]
|
||||
},
|
||||
"wing_closed_right": {
|
||||
"rotation": [-92.46677, 7.8791, 94.85228],
|
||||
"position": [0, -1, 6]
|
||||
"rotation": [-93.47882, 7.48957, 87.29442],
|
||||
"position": [3.8, -1, 6],
|
||||
"scale": 0.1
|
||||
},
|
||||
"wing_closed_right2": {
|
||||
"rotation": [5.08145, -3.03671, 1.64897]
|
||||
|
||||
+8
-8
@@ -1152,13 +1152,13 @@
|
||||
"rotation": [-7.32417, 1.61888, "12.3963+math.sin(q.anim_time*90*1-120)*6"]
|
||||
},
|
||||
"tail1": {
|
||||
"rotation": [-47.5, "0-math.sin(q.anim_time*90*2-40)*4", 0]
|
||||
"rotation": [-52.5, "-math.sin(q.anim_time*90*2-40)*4", 0]
|
||||
},
|
||||
"tail2": {
|
||||
"rotation": ["5+math.sin(q.anim_time*90*2-200)*2", "0-math.sin(q.anim_time*90*2-80)*4", 0]
|
||||
"rotation": ["math.sin(q.anim_time*90*2-200)*2", "-math.sin(q.anim_time*90*2-80)*4", 0]
|
||||
},
|
||||
"tail3": {
|
||||
"rotation": ["10+math.sin(q.anim_time*90*2-240)*2", "-math.sin(q.anim_time*90*2-120)*4", 0]
|
||||
"rotation": ["7.5+math.sin(q.anim_time*90*2-240)*2", "-math.sin(q.anim_time*90*2-120)*4", 0]
|
||||
},
|
||||
"tail4": {
|
||||
"rotation": ["-2.5+math.sin(q.anim_time*90*2-280)*2", "0-math.sin(q.anim_time*90*2-160)*8", 0]
|
||||
@@ -1207,16 +1207,16 @@
|
||||
"rotation": [-7.32417, -1.61888, "-12.3963-math.sin(q.anim_time*90*1-120)*6"]
|
||||
},
|
||||
"wing_left2": {
|
||||
"rotation": [0, "27.5+math.sin(q.anim_time*90*2-60)*40", 0]
|
||||
"rotation": [0, "27.5+math.sin(q.anim_time*90*2-60)*10", 0]
|
||||
},
|
||||
"wing_right2": {
|
||||
"rotation": [0, "-27.5-math.sin(q.anim_time*90*2-60)*40", 0]
|
||||
"rotation": [0, "-27.5+math.sin(q.anim_time*90*2-60)*-10", 0]
|
||||
},
|
||||
"wing_left": {
|
||||
"rotation": ["0.1201+math.cos(q.anim_time*90*2+60)*20", "-19.9232+math.sin(q.anim_time*90*2+60)*40", 4.11867]
|
||||
"rotation": ["0.1201+math.cos(q.anim_time*90*2+60)*5", "-19.9232+math.sin(q.anim_time*90*2+60)*10", 4.11867]
|
||||
},
|
||||
"wing_right": {
|
||||
"rotation": ["0.1201+math.cos(q.anim_time*90*2+60)*20", "19.9232-math.sin(q.anim_time*90*2+60)*40", -4.11867]
|
||||
"rotation": ["0.1201+math.cos(q.anim_time*90*2+60)*5", "19.9232+math.sin(q.anim_time*90*2+60)*-10", -4.11867]
|
||||
},
|
||||
"neck": {
|
||||
"rotation": ["-5+math.sin(q.anim_time*90*2-160)*3", 0, 0]
|
||||
@@ -1234,7 +1234,7 @@
|
||||
"rotation": [0, 0, "math.sin(q.anim_time*90*1-360)*9"]
|
||||
},
|
||||
"body": {
|
||||
"rotation": ["-math.sin(q.anim_time*90*2-120)*4", 0, 0],
|
||||
"rotation": ["15-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]
|
||||
}
|
||||
}
|
||||
|
||||
+1595
-64
File diff suppressed because it is too large
Load Diff
+4
-1
@@ -26,7 +26,10 @@
|
||||
"pivot": [0, 7.75, -0.5],
|
||||
"cubes": [
|
||||
{"origin": [-4, 4.25, -4], "size": [8, 8, 7], "uv": [0, 44]}
|
||||
]
|
||||
],
|
||||
"locators": {
|
||||
"seat_1": [0, 12, -4]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "upper_torso",
|
||||
|
||||
+5
-3
@@ -6,7 +6,7 @@
|
||||
"identifier": "geometry.dragonite",
|
||||
"texture_width": 256,
|
||||
"texture_height": 128,
|
||||
"visible_bounds_width": 8,
|
||||
"visible_bounds_width": 9,
|
||||
"visible_bounds_height": 5.5,
|
||||
"visible_bounds_offset": [0, 2.25, 0]
|
||||
},
|
||||
@@ -34,7 +34,10 @@
|
||||
"pivot": [0, 21, -0.5],
|
||||
"cubes": [
|
||||
{"origin": [-8, 19.5, -8], "size": [16, 9, 15], "inflate": 0.01, "uv": [33, 35]}
|
||||
]
|
||||
],
|
||||
"locators": {
|
||||
"seat_1": [0, 26, 7]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "chest2",
|
||||
@@ -196,7 +199,6 @@
|
||||
"name": "head",
|
||||
"parent": "neck",
|
||||
"pivot": [0, 46, 1],
|
||||
"rotation": [0, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [-5, 41, -6], "size": [10, 11, 11], "inflate": 0.01, "uv": [0, 0]}
|
||||
]
|
||||
|
||||
+6
-5
@@ -7,8 +7,8 @@
|
||||
"texture_width": 128,
|
||||
"texture_height": 128,
|
||||
"visible_bounds_width": 9,
|
||||
"visible_bounds_height": 2.5,
|
||||
"visible_bounds_offset": [0, 0.75, 0]
|
||||
"visible_bounds_height": 3,
|
||||
"visible_bounds_offset": [0, 0.5, 0]
|
||||
},
|
||||
"bones": [
|
||||
{
|
||||
@@ -27,7 +27,10 @@
|
||||
"cubes": [
|
||||
{"origin": [-12, 0, -20], "size": [24, 16, 23], "uv": [0, 0]},
|
||||
{"origin": [-11, 6, -22.5], "size": [22, 2, 3], "inflate": 0.01, "uv": [50, 44]}
|
||||
]
|
||||
],
|
||||
"locators": {
|
||||
"seat_1": [0, 16, -11]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "whisker_right",
|
||||
@@ -236,7 +239,6 @@
|
||||
"name": "tail",
|
||||
"parent": "torso",
|
||||
"pivot": [0, 6, 1],
|
||||
"rotation": [0, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [-8, 0.5, 1], "size": [16, 11, 9], "uv": [0, 39]}
|
||||
]
|
||||
@@ -261,7 +263,6 @@
|
||||
"name": "tail4",
|
||||
"parent": "tail3",
|
||||
"pivot": [0, 5, 18],
|
||||
"rotation": [0, 0, 0],
|
||||
"cubes": [
|
||||
{"origin": [-6.5, 5, 17], "size": [13, 0, 8], "uv": [42, 49]}
|
||||
]
|
||||
|
||||
+4
-1
@@ -34,7 +34,10 @@
|
||||
"pivot": [0, 26.2, 0],
|
||||
"cubes": [
|
||||
{"origin": [-5, 25.2, -4], "size": [10, 7, 8], "inflate": 0.01, "uv": [26, 32]}
|
||||
]
|
||||
],
|
||||
"locators": {
|
||||
"seat_1": [0, 29, 2]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "fin",
|
||||
|
||||
+4
-1
@@ -34,7 +34,10 @@
|
||||
"pivot": [0, 26.2, 0],
|
||||
"cubes": [
|
||||
{"origin": [-5, 25.2, -4], "size": [10, 7, 8], "inflate": 0.01, "uv": [26, 32]}
|
||||
]
|
||||
],
|
||||
"locators": {
|
||||
"seat_1": [0, 29, 2]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "fin",
|
||||
|
||||
+3
-3
@@ -31,7 +31,8 @@
|
||||
"locators": {
|
||||
"sparks1": [11.5, 14.5, -4.5],
|
||||
"sparks2": [-8, 15.5, 8],
|
||||
"sparks3": [-1.5, 5.5, -11.5]
|
||||
"sparks3": [-1.5, 5.5, -11.5],
|
||||
"seat_1": [0, 18, 4]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -186,8 +187,7 @@
|
||||
{
|
||||
"name": "magnet_back",
|
||||
"parent": "body",
|
||||
"pivot": [0, 8, 12],
|
||||
"rotation": [0, 0, 0]
|
||||
"pivot": [0, 8, 12]
|
||||
},
|
||||
{
|
||||
"name": "magnet_back_rotation",
|
||||
|
||||
+9
@@ -92,6 +92,15 @@
|
||||
"q.bedrock_quirk('charizard', 'air_fly_quirk')"
|
||||
]
|
||||
},
|
||||
"glide": {
|
||||
"poseTypes": ["GLIDE"],
|
||||
"isBattle": false,
|
||||
"animations": ["q.look('head_ai')", "q.bedrock('charizard', 'air_glide_TEST')"],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('charizard', 'blink')",
|
||||
"q.bedrock_quirk('charizard', 'air_fly_quirk')"
|
||||
]
|
||||
},
|
||||
"surface_idle": {
|
||||
"poseTypes": ["STAND", "FLOAT"],
|
||||
"isTouchingWater": true,
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"portraitScale": 1.14,
|
||||
"portraitTranslation": [-0.66, 1.91, 0],
|
||||
"profileScale": 0.48,
|
||||
"profileTranslation": [0, 0.99, 0],
|
||||
"rootBone": "whiscash",
|
||||
"animations": {
|
||||
"cry": "q.bedrock_stateful('whiscash', 'cry')",
|
||||
"recoil": "q.bedrock_stateful('whiscash', 'recoil')"
|
||||
},
|
||||
"poses": {
|
||||
"battle-standing": {
|
||||
"poseTypes": ["STAND"],
|
||||
"isBattle": true,
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.bedrock('whiscash', 'ground_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('whiscash', 'blink')"]
|
||||
},
|
||||
"underwater-battle-standing": {
|
||||
"poseTypes": ["FLOAT"],
|
||||
"isBattle": true,
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": ["q.bedrock('whiscash', 'water_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('whiscash', 'blink')"]
|
||||
},
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
|
||||
"isBattle": false,
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.look('head')", "q.bedrock('whiscash', 'ground_idle')"],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('whiscash', 'blink')"
|
||||
]
|
||||
},
|
||||
"walking": {
|
||||
"poseTypes": ["WALK"],
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.bedrock('whiscash', 'ground_walk')"],
|
||||
"quirks": ["q.bedrock_quirk('whiscash', 'blink')"]
|
||||
},
|
||||
"swim": {
|
||||
"poseTypes": ["SWIM"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": ["q.bedrock('whiscash', 'water_swim')"],
|
||||
"quirks": ["q.bedrock_quirk('whiscash', 'blink')"]
|
||||
},
|
||||
"sleep": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.bedrock('whiscash', 'ground_sleep')"]
|
||||
},
|
||||
"underwater-sleep": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
"poseName": ["water-sleep"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": ["q.bedrock('whiscash', 'water_sleep')"]
|
||||
}
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"portraitScale": 1.14,
|
||||
"portraitTranslation": [-0.66, 1.91, 0],
|
||||
"profileScale": 0.48,
|
||||
"profileTranslation": [0, 0.99, 0],
|
||||
"rootBone": "whiscash_nero",
|
||||
"animations": {
|
||||
"cry": "q.bedrock_stateful('whiscash_nero', 'cry')",
|
||||
"recoil": "q.bedrock_stateful('whiscash_nero', 'recoil')"
|
||||
},
|
||||
"poses": {
|
||||
"battle-standing": {
|
||||
"poseTypes": ["STAND"],
|
||||
"isBattle": true,
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.bedrock('whiscash_nero', 'ground_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('whiscash_nero', 'blink')"]
|
||||
},
|
||||
"underwater-battle-standing": {
|
||||
"poseTypes": ["FLOAT"],
|
||||
"isBattle": true,
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": ["q.bedrock('whiscash_nero', 'water_battle_idle')"],
|
||||
"quirks": ["q.bedrock_quirk('whiscash_nero', 'blink')"]
|
||||
},
|
||||
"standing": {
|
||||
"poseTypes": ["STAND", "NONE", "PORTRAIT", "PROFILE"],
|
||||
"isBattle": false,
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.look('head')", "q.bedrock('whiscash_nero', 'ground_idle')"],
|
||||
"quirks": [
|
||||
"q.bedrock_quirk('whiscash_nero', 'blink')"
|
||||
]
|
||||
},
|
||||
"walking": {
|
||||
"poseTypes": ["WALK"],
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.bedrock('whiscash_nero', 'ground_walk')"],
|
||||
"quirks": ["q.bedrock_quirk('whiscash_nero', 'blink')"]
|
||||
},
|
||||
"swim": {
|
||||
"poseTypes": ["SWIM"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": ["q.bedrock('whiscash_nero', 'water_swim')"],
|
||||
"quirks": ["q.bedrock_quirk('whiscash_nero', 'blink')"]
|
||||
},
|
||||
"sleep": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
"isTouchingWater": false,
|
||||
"animations": ["q.bedrock('whiscash_nero', 'ground_sleep')"]
|
||||
},
|
||||
"underwater-sleep": {
|
||||
"poseTypes": ["SLEEP"],
|
||||
"poseName": ["water-sleep"],
|
||||
"isTouchingWater": true,
|
||||
"isUnderWater": true,
|
||||
"animations": ["q.bedrock('whiscash_nero', 'water_sleep')"]
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -11,6 +11,7 @@
|
||||
},
|
||||
{
|
||||
"aspects": ["whiscash_nero"],
|
||||
"poser": "cobblemon:whiscash",
|
||||
"model": "cobblemon:whiscash_nero.geo",
|
||||
"texture": "cobblemon:textures/pokemon/0340_whiscash/whiscash_nero.png"
|
||||
},
|
||||
|
||||
@@ -51,6 +51,48 @@
|
||||
"fixed": false
|
||||
},
|
||||
"riding": {
|
||||
"stats": {
|
||||
"SPEED": {
|
||||
"displayName": "Speed",
|
||||
"description": "Its top speed",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "10-100"
|
||||
}
|
||||
},
|
||||
"ACCELERATION": {
|
||||
"displayName": "Acceleration",
|
||||
"description": "How fast it can speed up",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "10-100"
|
||||
}
|
||||
},
|
||||
"SKILL": {
|
||||
"displayName": "Handling",
|
||||
"description": "How fast it can turn",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "10-100"
|
||||
}
|
||||
},
|
||||
"JUMP": {
|
||||
"displayName": "Altitude",
|
||||
"description": "How high it can fly",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "10-100"
|
||||
}
|
||||
},
|
||||
"STAMINA": {
|
||||
"displayName": "Fuel/Stamina",
|
||||
"description": "How long it can stay off the ground",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "10-100"
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller": {
|
||||
"key": "cobblemon:composite/run_up_to_flight",
|
||||
"minimumSpeed": "0.2",
|
||||
@@ -61,17 +103,18 @@
|
||||
"jumpVector": [0, "0.3*q.jump_strength/50", "-1 * 0.5*q.jump_strength/50"]
|
||||
},
|
||||
"flightController": {
|
||||
"key": "cobblemon:air/helicopter",
|
||||
"key": "cobblemon:air/bird",
|
||||
"gravity": "q.gravity * (0.1 + (q.passenger_count - 1) * 0.1)",
|
||||
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.33, 0, 1)"
|
||||
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.33, 0, 1)",
|
||||
"jumpVector": [0, "0.3*q.jump_strength/50", 0]
|
||||
}
|
||||
},
|
||||
"seats": [
|
||||
{
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 1.5,
|
||||
"z": -0.5
|
||||
"y": 0.0,
|
||||
"z": 0
|
||||
},
|
||||
"poseOffsets": [
|
||||
{
|
||||
@@ -80,8 +123,8 @@
|
||||
],
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0.7,
|
||||
"z": 1
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -90,8 +133,8 @@
|
||||
],
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0.2,
|
||||
"z": 1
|
||||
"y": 0.0,
|
||||
"z": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -110,7 +153,7 @@
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0.4,
|
||||
"z": 1
|
||||
"z": -1
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -120,7 +163,7 @@
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0.2,
|
||||
"z": 0.2
|
||||
"z": -0.2
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -50,6 +50,48 @@
|
||||
"fixed": false
|
||||
},
|
||||
"riding": {
|
||||
"stats": {
|
||||
"SPEED": {
|
||||
"displayName": "Speed",
|
||||
"description": "Its top speed",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "100-101"
|
||||
}
|
||||
},
|
||||
"ACCELERATION": {
|
||||
"displayName": "Acceleration",
|
||||
"description": "How fast it can speed up",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "100-101"
|
||||
}
|
||||
},
|
||||
"SKILL": {
|
||||
"displayName": "Handling",
|
||||
"description": "How fast it can turn",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "100-101"
|
||||
}
|
||||
},
|
||||
"JUMP": {
|
||||
"displayName": "Altitude",
|
||||
"description": "How high it can fly",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "100-101"
|
||||
}
|
||||
},
|
||||
"STAMINA": {
|
||||
"displayName": "Fuel/Stamina",
|
||||
"description": "How long it can stay off the ground",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "100-101"
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller": {
|
||||
"key": "cobblemon:composite/run_up_to_flight",
|
||||
"minimumSpeed": "0.2",
|
||||
@@ -70,8 +112,8 @@
|
||||
{
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 1.5,
|
||||
"z": -0.5
|
||||
"y": 0.0,
|
||||
"z": 0
|
||||
},
|
||||
"poseOffsets": [
|
||||
{
|
||||
@@ -80,8 +122,8 @@
|
||||
],
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0.7,
|
||||
"z": -1
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -90,8 +132,8 @@
|
||||
],
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0.2,
|
||||
"z": -1
|
||||
"y": 0.0,
|
||||
"z": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -50,6 +50,87 @@
|
||||
"height": 3.2,
|
||||
"fixed": false
|
||||
},
|
||||
"riding": {
|
||||
"stats": {
|
||||
"SPEED": {
|
||||
"displayName": "Speed",
|
||||
"description": "Its top speed",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "10-70"
|
||||
}
|
||||
},
|
||||
"ACCELERATION": {
|
||||
"displayName": "Acceleration",
|
||||
"description": "How fast it can speed up",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "10-70"
|
||||
}
|
||||
},
|
||||
"SKILL": {
|
||||
"displayName": "Handling",
|
||||
"description": "How fast it can turn",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "10-70"
|
||||
}
|
||||
},
|
||||
"JUMP": {
|
||||
"displayName": "Altitude",
|
||||
"description": "How high it can fly",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "10-70"
|
||||
}
|
||||
},
|
||||
"STAMINA": {
|
||||
"displayName": "Fuel/Stamina",
|
||||
"description": "How long it can stay off the ground",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "10-70"
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller": {
|
||||
"key": "cobblemon:composite/run_up_to_flight",
|
||||
"minimumSpeed": "0.2",
|
||||
"minimumJump": "80",
|
||||
"landController": {
|
||||
"key": "cobblemon:land/generic",
|
||||
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.33, 0, 1)",
|
||||
"jumpVector": [0, "0.3*q.jump_strength/50", "-1 * 0.5*q.jump_strength/50"]
|
||||
},
|
||||
"flightController": {
|
||||
"key": "cobblemon:air/jet",
|
||||
"gravity": "q.gravity * (0.1 + (q.passenger_count - 1) * 0.1)",
|
||||
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.33, 0, 1)",
|
||||
"jumpVector": [0, "0.3*q.jump_strength/50", 0]
|
||||
}
|
||||
},
|
||||
"seats": [
|
||||
{
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0.0,
|
||||
"z": 0
|
||||
},
|
||||
"poseOffsets": [
|
||||
{
|
||||
"poseTypes": [
|
||||
"FLY"
|
||||
],
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0.0,
|
||||
"z": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"behaviour": {
|
||||
"moving": {
|
||||
"swim": {
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
},
|
||||
"riding": {
|
||||
"controller": {
|
||||
"key": "cobblemon:swim/generic",
|
||||
"key": "cobblemon:land/generic",
|
||||
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.07, 0, 0.08)",
|
||||
"jumpVector": [0, "0.3*q.jump_strength/50", "-1 * 0.5*q.jump_strength/50"]
|
||||
},
|
||||
|
||||
@@ -49,6 +49,39 @@
|
||||
"height": 1,
|
||||
"fixed": false
|
||||
},
|
||||
"riding": {
|
||||
"controller": {
|
||||
"key": "cobblemon:swim/dolphin",
|
||||
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.5, 0, 3)",
|
||||
"jumpVector": [0, "0.3*q.jump_strength/50", "-1 * 0.5*q.jump_strength/50"]
|
||||
},
|
||||
"seats": [
|
||||
{
|
||||
"offset": {
|
||||
"x": 0.0,
|
||||
"y": 0.4,
|
||||
"z": 0.0
|
||||
},
|
||||
"poseAnimations": [
|
||||
{
|
||||
"animations": [
|
||||
{
|
||||
"fileName": "trainer_generic",
|
||||
"animationName": "animation.trainer_generic.idle"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"offset": {
|
||||
"x": 0.0,
|
||||
"y": 0.7,
|
||||
"z": -1.0
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"behaviour": {
|
||||
"moving": {
|
||||
"walk": {
|
||||
|
||||
@@ -50,6 +50,87 @@
|
||||
"height": 2.3,
|
||||
"fixed": false
|
||||
},
|
||||
"riding": {
|
||||
"stats": {
|
||||
"SPEED": {
|
||||
"displayName": "Speed",
|
||||
"description": "Its top speed",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "100-101"
|
||||
}
|
||||
},
|
||||
"ACCELERATION": {
|
||||
"displayName": "Acceleration",
|
||||
"description": "How fast it can speed up",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "100-101"
|
||||
}
|
||||
},
|
||||
"SKILL": {
|
||||
"displayName": "Handling",
|
||||
"description": "How fast it can turn",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "100-101"
|
||||
}
|
||||
},
|
||||
"JUMP": {
|
||||
"displayName": "Altitude",
|
||||
"description": "How high it can fly",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "100-101"
|
||||
}
|
||||
},
|
||||
"STAMINA": {
|
||||
"displayName": "Fuel/Stamina",
|
||||
"description": "How long it can stay off the ground",
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "100-101"
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller": {
|
||||
"key": "cobblemon:composite/run_up_to_flight",
|
||||
"minimumSpeed": "0.2",
|
||||
"minimumJump": "80",
|
||||
"landController": {
|
||||
"key": "cobblemon:land/generic",
|
||||
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.33, 0, 1)",
|
||||
"jumpVector": [0, "0.3*q.jump_strength/50", "-1 * 0.5*q.jump_strength/50"]
|
||||
},
|
||||
"flightController": {
|
||||
"key": "cobblemon:air/jet",
|
||||
"gravity": "q.gravity * (0.1 + (q.passenger_count - 1) * 0.1)",
|
||||
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.33, 0, 1)",
|
||||
"jumpVector": [0, "0.3*q.jump_strength/50", 0]
|
||||
}
|
||||
},
|
||||
"seats": [
|
||||
{
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0.4,
|
||||
"z": 0
|
||||
},
|
||||
"poseOffsets": [
|
||||
{
|
||||
"poseTypes": [
|
||||
"FLY"
|
||||
],
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0.0,
|
||||
"z": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"behaviour": {
|
||||
"moving": {
|
||||
"walk": {
|
||||
|
||||
@@ -49,15 +49,9 @@
|
||||
"SPEED": {
|
||||
"displayName": "Running",
|
||||
"description": "How fast Gliscor zoom zooms",
|
||||
"baseStats": {
|
||||
"LAND": {
|
||||
"min": 10,
|
||||
"max": 2
|
||||
},
|
||||
"AIR": {
|
||||
"min": 50,
|
||||
"max": 90
|
||||
}
|
||||
"ranges": {
|
||||
"LAND": "2-10",
|
||||
"AIR": "50-90"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -49,6 +49,54 @@
|
||||
"height": 1.6,
|
||||
"fixed": false
|
||||
},
|
||||
"riding": {
|
||||
"controller": {
|
||||
"key": "cobblemon:composite/run_up_to_flight",
|
||||
"minimumSpeed": "0.2",
|
||||
"minimumJump": "80",
|
||||
"landController": {
|
||||
"key": "cobblemon:land/generic",
|
||||
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.33, 0, 1)",
|
||||
"jumpVector": [0, "0.3*q.jump_strength/50", "-1 * 0.5*q.jump_strength/50"]
|
||||
},
|
||||
"flightController": {
|
||||
"key": "cobblemon:air/helicopter",
|
||||
"gravity": "q.gravity * (0.1 + (q.passenger_count - 1) * 0.1)",
|
||||
"speed": "Math.clamp(q.entity.velocity.horizontal_magnitude + 0.33, 0, 1)"
|
||||
}
|
||||
},
|
||||
"seats": [
|
||||
{
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0.5,
|
||||
"z": -0.5
|
||||
},
|
||||
"poseOffsets": [
|
||||
{
|
||||
"poseTypes": [
|
||||
"HOVER"
|
||||
],
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"poseTypes": [
|
||||
"FLY"
|
||||
],
|
||||
"offset": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"behaviour": {
|
||||
"moving": {
|
||||
"fly": {
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"ItemStackComponentizationFixMixin",
|
||||
"LecternBlockMixin",
|
||||
"LivingEntityMixin",
|
||||
"LocalPlayerMixin",
|
||||
"MinecraftDedicatedServerMixin",
|
||||
"NbtUtilsMixin",
|
||||
"PiglinBarterMixin",
|
||||
|
||||
Reference in New Issue
Block a user