Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1817322fa |
No files matched your search
+996
-27
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,61 +0,0 @@
|
||||
# Changelog
|
||||
## [1.7.1 (November 29th, 2025)](#1-7-1)
|
||||
|
||||
### Additions
|
||||
- Added trades for Saccharine Saplings, Hearty Grains, Chipped Pot, and Masterpiece Teacup to the Wandering Trader.
|
||||
- Added brewing recipe for Throat Spray.
|
||||
- Added vanilla sprinting's field of view change to Pokémon land mounts.
|
||||
- Added a customizable keybind for the riding freelook button.
|
||||
- Added double tap to sprint on land mounts.
|
||||
|
||||
### Changes
|
||||
- Made Jet pitch turning 1.5x faster across all Pokémon.
|
||||
- Party Pokémon now attack only mobs that are attacking their owner, instead of randomly targeting unrelated mobs and getting themselves hurt.
|
||||
- Reduced the cost of the Vivichoke Seed trade with the Wandering Trader.
|
||||
|
||||
### Fixes
|
||||
- Fixed incorrect camera pivot on Bird, Jet, and Dolphin mounts, leading to some disorienting riding.
|
||||
- Fixed players suffocating while on vanilla mounts.
|
||||
- Fixed a graphics crash that could occur on some machines when campfire pots were nearby.
|
||||
- Fixed ride controls overlay being displayed to passengers. The passengers probably don't need to know about those.
|
||||
- Fixed mount jumping so that it doesn't switch back to ground animations.
|
||||
- Fixed ridden Pokémon land collision and some issues around stepping up blocks. Land mounts are smoother overall now.
|
||||
- Fixed Furfrou's pink and magenta trims being swapped. Only a man could make that mistake.
|
||||
- Fixed friendship being reset to the default value when evolving a Pokémon.
|
||||
- Fixed Combees not depositing honey upon leaving a hive if they entered it with nectar.
|
||||
- Fixed pastured Combees not moving during the night or in rain.
|
||||
- Fixed a case in which a Combee might try to path to a flower that no longer exists.
|
||||
- Fixed Combees attempting to enter a full hive.
|
||||
- Fixed a crash involving Combees and hives. 500 bee bugs. Bugged bees? We can be bees. Mark, this is good news.
|
||||
- Fixed a crash related to NPC navigation.
|
||||
- Fixed a crash when opening a PC box with certain wallpapers while using *VulkanMod*.
|
||||
- Fixed a crash when you place a block in the way of hearty grains 2nd block.
|
||||
- Fixed passengers hearing the shiny noise of a ridden shiny Pokémon.
|
||||
- Ponigiri can no longer be eaten at full hunger.
|
||||
- Fixed Poké Snack spawning sounds not coming from the block.
|
||||
- Medicinal Brew's Campfire Pot recipe now correctly displays that it can be made using an empty glass bottle or a filled bottle.
|
||||
- Fixed glass bottle not being returned when slathering honey on a saccharine leaf block.
|
||||
- Fixed saccharine hanging signs sometimes dropping their oak wood counterpart when being broken.
|
||||
- Fixed a bunch of incompatibilities with NeoForge mods.
|
||||
- Fixed a bug where wind charges hitting pasture blocks would recall all Pokémon in it.
|
||||
- Fixed the Home on the Range advancement triggering when opening the Pokémon interaction wheel.
|
||||
- Fixed recipes that use concrete not working on NeoForge.
|
||||
- Fixed Boltund's model.
|
||||
- Fixed Cyclizar's textures.
|
||||
|
||||
### Developer
|
||||
|
||||
### Molang & Datapacks
|
||||
- Removed automatic generation of PC wallpaper screen glow if no asset is provided; it is now optional.
|
||||
- This is because there's no practical way to do this without blowing up things like *VulkanMod*.
|
||||
|
||||
### Particles
|
||||
|
||||
### Localization
|
||||
- Updated translations for:
|
||||
- French
|
||||
- Japanese
|
||||
- Korean
|
||||
- Brazilian Portuguese
|
||||
- Simplified Chinese
|
||||
- Traditional Chinese
|
||||
@@ -17,7 +17,6 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.ai.memory.MemoryStatus;
|
||||
import net.minecraft.world.item.component.CustomData;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.BeehiveBlock;
|
||||
@@ -53,9 +52,7 @@ public abstract class BeeOccupantMixin {
|
||||
var facing = state.getValue(HorizontalDirectionalBlock.FACING);
|
||||
newPos = pos.relative(facing).getCenter();
|
||||
newYaw = facing.toYRot();
|
||||
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
|
||||
brain.setMemory(CobblemonMemories.HIVE_LOCATION, pos); // This needs to be set in the case that the hive was picked up and moved.
|
||||
}
|
||||
brain.setMemory(CobblemonMemories.HIVE_LOCATION, pos); // This needs to be set in the case that the hive was picked up and moved.
|
||||
} else {
|
||||
// Block has likely been destroyed
|
||||
var center = pos.getCenter();
|
||||
@@ -65,31 +62,25 @@ public abstract class BeeOccupantMixin {
|
||||
center.z + level.random.nextFloat() * 0.6 - 0.3
|
||||
);
|
||||
newYaw = level.random.nextFloat() * 360F;
|
||||
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
|
||||
brain.eraseMemory(CobblemonMemories.HIVE_LOCATION);
|
||||
}
|
||||
brain.eraseMemory(CobblemonMemories.HIVE_LOCATION);
|
||||
}
|
||||
entity.yRotO = newYaw;
|
||||
entity.setPos(newPos);
|
||||
// Do honey logic
|
||||
if (brain.checkMemory(CobblemonMemories.HAS_NECTAR, MemoryStatus.REGISTERED)) {
|
||||
var hasNectar = brain.getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
if (hasNectar) {
|
||||
// Remove nectar and reset got to hive cooldown
|
||||
brain.eraseMemory(CobblemonMemories.HAS_NECTAR);
|
||||
if (brain.checkMemory(CobblemonMemories.HIVE_LOCATION, MemoryStatus.REGISTERED)) {
|
||||
brain.setMemoryWithExpiry(CobblemonMemories.HIVE_COOLDOWN, true, PathToBeeHiveTaskConfig.STAY_OUT_OF_HIVE_COOLDOWN);
|
||||
}
|
||||
// Increment honey level of the hive
|
||||
if (state.is(BlockTags.BEEHIVES, (blockStateBase) -> blockStateBase.hasProperty(BeehiveBlock.HONEY_LEVEL))) {
|
||||
int i = state.getValue(BeehiveBlock.HONEY_LEVEL);
|
||||
if (i < 5) {
|
||||
int j = level.random.nextInt(100) == 0 ? 2 : 1;
|
||||
if (i + j > 5) {
|
||||
--j;
|
||||
}
|
||||
level.setBlockAndUpdate(pos, state.setValue(BeehiveBlock.HONEY_LEVEL, i + j));
|
||||
var hasNectar = brain.getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
if (hasNectar) {
|
||||
// Remove nectar and reset got to hive cooldown
|
||||
brain.eraseMemory(CobblemonMemories.HAS_NECTAR);
|
||||
brain.setMemoryWithExpiry(CobblemonMemories.HIVE_COOLDOWN, true, PathToBeeHiveTaskConfig.STAY_OUT_OF_HIVE_COOLDOWN);
|
||||
// Increment honey level of the hive
|
||||
if (state.is(BlockTags.BEEHIVES, (blockStateBase) -> blockStateBase.hasProperty(BeehiveBlock.HONEY_LEVEL))) {
|
||||
int i = state.getValue(BeehiveBlock.HONEY_LEVEL);
|
||||
if (i < 5) {
|
||||
int j = level.random.nextInt(100) == 0 ? 2 : 1;
|
||||
if (i + j > 5) {
|
||||
--j;
|
||||
}
|
||||
level.setBlockAndUpdate(pos, state.setValue(BeehiveBlock.HONEY_LEVEL, i + j));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,13 +92,12 @@ public abstract class BeeOccupantMixin {
|
||||
@Inject(method = "of", at = @At("HEAD"), cancellable = true)
|
||||
private static void cobblemon$of(Entity entity, CallbackInfoReturnable<BeehiveBlockEntity.Occupant> cir) {
|
||||
if (entity instanceof PokemonEntity pokemonEntity) {
|
||||
List<String> IGNORED_BEE_TAGS = Arrays.asList("Air", "ArmorDropChances", "ArmorItems", "CanPickUpLoot", "DeathTime", "FallDistance", "FallFlying", "Fire", "HandDropChances", "HandItems", "HurtByTimestamp", "HurtTime", "LeftHanded", "Motion", "NoGravity", "OnGround", "PortalCooldown", "Pos", "Rotation", "Passengers", "leash", "UUID");
|
||||
List<String> IGNORED_BEE_TAGS = Arrays.asList("Air", "ArmorDropChances", "ArmorItems", "Brain", "CanPickUpLoot", "DeathTime", "FallDistance", "FallFlying", "Fire", "HandDropChances", "HandItems", "HurtByTimestamp", "HurtTime", "LeftHanded", "Motion", "NoGravity", "OnGround", "PortalCooldown", "Pos", "Rotation", "Passengers", "leash", "UUID");
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
entity.save(compoundTag);
|
||||
Objects.requireNonNull(compoundTag);
|
||||
IGNORED_BEE_TAGS.forEach(compoundTag::remove);
|
||||
boolean hasNectar = pokemonEntity.getBrain().checkMemory(CobblemonMemories.HAS_NECTAR, MemoryStatus.REGISTERED)
|
||||
&& pokemonEntity.getBrain().getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
Boolean hasNectar = pokemonEntity.getBrain().getMemory(CobblemonMemories.HAS_NECTAR).orElse(false);
|
||||
cir.setReturnValue(new BeehiveBlockEntity.Occupant(CustomData.of(compoundTag), 0, hasNectar ? 2400 : 600));
|
||||
cir.cancel();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.block.PreEmptsExplosion;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(value = Explosion.class)
|
||||
public class ExplosionMixin {
|
||||
|
||||
@Redirect(
|
||||
method = "finalizeExplosion",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;",
|
||||
ordinal = 0
|
||||
)
|
||||
)
|
||||
public BlockState cobblemon$whenExploded(Level world, BlockPos pos) {
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
if(blockState.getBlock() instanceof PreEmptsExplosion preExplosionBlock) {
|
||||
preExplosionBlock.whenExploded(world, blockState, pos);
|
||||
}
|
||||
return blockState;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import net.minecraft.stats.RecipeBookSettings;
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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.CallbackInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(RecipeBookSettings.class)
|
||||
public class RecipeBookSettingsMixin {
|
||||
|
||||
|
||||
@Shadow @Final public Map<RecipeBookType, RecipeBookSettings.TypeSettings> states;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void cobblemon$init(CallbackInfo ci) {
|
||||
states.put(RecipeBookType.valueOf("COOKING_POT"), new RecipeBookSettings.TypeSettings(true, true));
|
||||
}
|
||||
}
|
||||
+2
-5
@@ -6,9 +6,8 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.fabric.mixin;
|
||||
package com.cobblemon.mod.common.mixin;
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonRecipeBookTypes;
|
||||
import net.minecraft.world.inventory.RecipeBookType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -41,9 +40,7 @@ public class RecipeBookTypeMixin {
|
||||
)
|
||||
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
|
||||
ArrayList<RecipeBookType> types = new ArrayList<>(List.of($VALUES));
|
||||
// if you change or add any of these, neoforge uses a separate mechanism
|
||||
// check enumextensions.json and `CobblemonEnumExtensions`
|
||||
types.add(cobblemon$createBookType(CobblemonRecipeBookTypes.COOKING_POT_NAME, $VALUES.length));
|
||||
types.add(cobblemon$createBookType("COOKING_POT", $VALUES.length));
|
||||
$VALUES = types.toArray(RecipeBookType[]::new);
|
||||
}
|
||||
}
|
||||
@@ -11,15 +11,11 @@ package com.cobblemon.mod.common.mixin;
|
||||
import com.cobblemon.mod.common.Cobblemon;
|
||||
import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.PlayerSpawnerAccessor;
|
||||
import com.cobblemon.mod.common.api.riding.RidingStyle;
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawner;
|
||||
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawnerFactory;
|
||||
import com.cobblemon.mod.common.api.stats.CobblemonStats;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
|
||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -93,32 +89,4 @@ public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
|
||||
private boolean cobblemon$cancelSavingPokemonMounts(boolean original, @Local(ordinal=0) Entity entity) {
|
||||
return original && !(entity instanceof PokemonEntity);
|
||||
}
|
||||
|
||||
@WrapOperation(method = "checkRidingStatistics", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;getVehicle()Lnet/minecraft/world/entity/Entity;"))
|
||||
public Entity cobblemon$checkRidingStatistics(ServerPlayer player, Operation<Entity> original, @Local int distance) {
|
||||
var entity = original.call(player);
|
||||
if (!(entity instanceof PokemonEntity pokemonEntity)) {
|
||||
return entity;
|
||||
}
|
||||
|
||||
var ridingController = pokemonEntity.getRidingController();
|
||||
if (ridingController == null) return entity;
|
||||
|
||||
var activeContext = ridingController.getContext();
|
||||
if (activeContext == null) return entity;
|
||||
|
||||
var ridingStyle = activeContext.getStyle();
|
||||
CobblemonStats.CobblemonStat stat = switch (ridingStyle) {
|
||||
case RidingStyle.LAND -> CobblemonStats.RIDING_LAND;
|
||||
case RidingStyle.AIR -> CobblemonStats.RIDING_AIR;
|
||||
case RidingStyle.LIQUID -> CobblemonStats.RIDING_LIQUID;
|
||||
default -> null;
|
||||
};
|
||||
|
||||
if (stat != null) {
|
||||
player.awardStat(CobblemonStats.getStat(stat), distance);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -33,7 +33,7 @@ public class AbstractClientPlayerMixin {
|
||||
cir.setReturnValue(usageContext.getFovMultiplier());
|
||||
} else {
|
||||
// Only modify fov through riding if the pokedex is not open
|
||||
AbstractClientPlayer player = (AbstractClientPlayer) (Object) this;
|
||||
LocalPlayer player = (LocalPlayer) (Object) this;
|
||||
// Only modify fov for the driver and not the passengers
|
||||
if (player != null && player.isPassenger() && player.getVehicle() instanceof PokemonEntity && player.getVehicle().getControllingPassenger() == player) {
|
||||
PokemonEntity ride = (PokemonEntity) player.getVehicle();
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.api.orientation.OrientationController;
|
||||
import com.cobblemon.mod.common.client.CobblemonClient;
|
||||
import com.cobblemon.mod.common.client.keybind.keybinds.PartySendBinding;
|
||||
import com.cobblemon.mod.common.client.keybind.keybinds.RidingFreelookBinding;
|
||||
import com.cobblemon.mod.common.duck.RidePassenger;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.pokedex.scanner.PokedexUsageContext;
|
||||
@@ -157,7 +156,7 @@ public abstract class MouseHandlerMixin {
|
||||
}
|
||||
|
||||
var vehicleController = controllableVehicle.getOrientationController();
|
||||
var freeLooking = RidingFreelookBinding.INSTANCE.isDown();
|
||||
var lookaroundButtonPressed = Minecraft.getInstance().mouseHandler.isMiddlePressed();
|
||||
Pair<Boolean, Boolean> mouseShouldModifyDriver = ((PokemonEntity) vehicle).ifRidingAvailableSupply(new Pair(false, false), (behaviour, settings, state) -> {
|
||||
return behaviour.mouseModifiesDriverRotation(
|
||||
settings,
|
||||
@@ -171,7 +170,7 @@ public abstract class MouseHandlerMixin {
|
||||
// affect the vehicle orientation when looking around.
|
||||
// If the client is a passenger it will modify these rotations and return
|
||||
//-------------------------------------------------------------------------
|
||||
if (freeLooking || player.getControlledVehicle() == null) {
|
||||
if (lookaroundButtonPressed || player.getControlledVehicle() == null) {
|
||||
// Modify driver rotations
|
||||
cobblemon$setDriverRotations(player, cursorDeltaX, cursorDeltaY);
|
||||
|
||||
@@ -193,10 +192,10 @@ public abstract class MouseHandlerMixin {
|
||||
// Smoothly return driver rotations to zero when needed
|
||||
//-------------------------------------------------------------------------
|
||||
var playerRotater = (RidePassenger)player;
|
||||
if( !freeLooking && !mouseShouldModifyDriver.getFirst()){
|
||||
if( !lookaroundButtonPressed && !mouseShouldModifyDriver.getFirst()){
|
||||
playerRotater.cobblemon$setRideYRot(lerp(min(5.0f * (float)movementTime, 1.0f), Mth.wrapDegrees(playerRotater.cobblemon$getRideYRot()), 0.0f));
|
||||
}
|
||||
if( !freeLooking && !mouseShouldModifyDriver.getSecond()) {
|
||||
if( !lookaroundButtonPressed && !mouseShouldModifyDriver.getSecond()) {
|
||||
playerRotater.cobblemon$setRideXRot(lerp(min(5.0f * (float)movementTime, 1.0f), Mth.wrapDegrees(playerRotater.cobblemon$getRideXRot()), 0.0f));
|
||||
}
|
||||
|
||||
|
||||
+7
-10
@@ -6,11 +6,10 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.fabric.mixin;
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItems;
|
||||
import com.cobblemon.mod.common.CobblemonRecipeBookTypes;
|
||||
import com.cobblemon.mod.common.CobblemonRecipeCategories;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.RecipeBookCategories;
|
||||
@@ -50,19 +49,17 @@ public class RecipeBookCategoriesMixin {
|
||||
)
|
||||
private static void cobblemon$addRecipeBookType(CallbackInfo ci) {
|
||||
ArrayList<RecipeBookCategories> types = new ArrayList<>(List.of($VALUES));
|
||||
// if you change or add any of these, neoforge uses a separate mechanism
|
||||
// check enumextensions.json and `CobblemonEnumExtensions`
|
||||
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_SEARCH", $VALUES.length, new ItemStack(Items.COMPASS)));
|
||||
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_FOODS", $VALUES.length + 1, new ItemStack(CobblemonItems.LEEK_AND_POTATO_STEW)));
|
||||
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_MEDICINES", $VALUES.length + 2, new ItemStack(CobblemonItems.POTION)));
|
||||
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_COMPLEX_DISHES", $VALUES.length + 3, new ItemStack(CobblemonItems.APRIJUICE_RED)));
|
||||
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_MISC", $VALUES.length + 4, new ItemStack(CobblemonItems.PROTEIN)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_SEARCH", $VALUES.length, new ItemStack(Items.COMPASS)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_FOODS", $VALUES.length + 1, new ItemStack(CobblemonItems.LEEK_AND_POTATO_STEW)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_MEDICINES", $VALUES.length + 2, new ItemStack(CobblemonItems.POTION)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_COMPLEX_DISHES", $VALUES.length + 3, new ItemStack(CobblemonItems.APRIJUICE_RED)));
|
||||
types.add(cobblemon$createCategory("COOKING_POT_MISC", $VALUES.length + 4, new ItemStack(CobblemonItems.PROTEIN)));
|
||||
$VALUES = types.toArray(RecipeBookCategories[]::new);
|
||||
}
|
||||
|
||||
@Inject(method = "getCategories", at = @At("HEAD"), cancellable = true)
|
||||
private static void modifyCategories(RecipeBookType recipeBookType, CallbackInfoReturnable<List<RecipeBookCategories>> cir) {
|
||||
if (recipeBookType == CobblemonRecipeBookTypes.INSTANCE.getCOOKING_POT()) {
|
||||
if (recipeBookType == RecipeBookType.valueOf("COOKING_POT")) {
|
||||
List var10000 = ImmutableList.of(
|
||||
CobblemonRecipeCategories.COOKING_POT_SEARCH.toVanillaCategory(),
|
||||
CobblemonRecipeCategories.COOKING_POT_FOODS.toVanillaCategory(),
|
||||
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.mixin.entity;
|
||||
import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.duck.RidePassenger;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
@@ -24,7 +23,6 @@ import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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.callback.CallbackInfo;
|
||||
@@ -50,8 +48,16 @@ public abstract class EntityMixin {
|
||||
)
|
||||
)
|
||||
public boolean cobblemon$forceOnGroundForStepUp(Entity entity, Operation<Boolean> original) {
|
||||
if (entity instanceof PokemonEntity vehicle && entity.hasControllingPassenger()) {
|
||||
return true;
|
||||
if (entity instanceof PokemonEntity && entity.hasControllingPassenger()) {
|
||||
BlockPos below = entity.blockPosition().below();
|
||||
Level level = entity.level();
|
||||
var blockStateBelow = level.getBlockState(below);
|
||||
boolean isAirOrLiquid = blockStateBelow.isAir() || !blockStateBelow.getFluidState().isEmpty();
|
||||
boolean canSupportEntity = blockStateBelow.isFaceSturdy(level, below, Direction.UP);
|
||||
boolean standingOnSolid = canSupportEntity && !isAirOrLiquid;
|
||||
if (standingOnSolid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return original.call(entity);
|
||||
}
|
||||
@@ -62,7 +68,18 @@ public abstract class EntityMixin {
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$modifyEyePosition_partial(float partialTicks, CallbackInfoReturnable<Vec3> cir) {
|
||||
cobblemon$getCustomEyePos(cir);
|
||||
var entity = (Entity)(Object)this;
|
||||
if (entity.level().isClientSide) return;
|
||||
if (!(entity instanceof Player player)) return;
|
||||
if (!(player instanceof RidePassenger ridePassenger)) return;
|
||||
if (!(player.getVehicle() instanceof OrientationControllable vehicle)) return;
|
||||
var vehicleController = vehicle.getOrientationController();
|
||||
if (vehicleController == null) return;
|
||||
|
||||
|
||||
// TODO: Determine if it needs partialtick involved.
|
||||
Vec3 customEyePos = ridePassenger.cobblemon$getRideEyePos();
|
||||
cir.setReturnValue(customEyePos);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -71,20 +88,15 @@ public abstract class EntityMixin {
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$modifyEyePosition_noPartial(CallbackInfoReturnable<Vec3> cir) {
|
||||
cobblemon$getCustomEyePos(cir);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void cobblemon$getCustomEyePos(CallbackInfoReturnable<Vec3> cir) {
|
||||
var entity = (Entity)(Object)this;
|
||||
if (entity.level().isClientSide) return;
|
||||
if (!(entity instanceof Player player)) return;
|
||||
if (!(player instanceof RidePassenger ridePassenger)) return;
|
||||
if (!(player.getVehicle() instanceof OrientationControllable vehicle)) return;
|
||||
if (!(vehicle instanceof PokemonEntity)) return;
|
||||
var vehicleController = vehicle.getOrientationController();
|
||||
if (vehicleController == null) return;
|
||||
|
||||
// TODO: Determine if it needs partialtick involved.
|
||||
Vec3 customEyePos = ridePassenger.cobblemon$getRideEyePos();
|
||||
cir.setReturnValue(customEyePos);
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ import com.cobblemon.mod.common.api.scheduling.ServerRealTimeTaskTracker
|
||||
import com.cobblemon.mod.common.api.scheduling.ServerTaskTracker
|
||||
import com.cobblemon.mod.common.api.spawning.BestSpawner
|
||||
import com.cobblemon.mod.common.api.spawning.CobblemonSpawningZoneGenerator
|
||||
import com.cobblemon.mod.common.api.spawning.SpawningZoneGenerator
|
||||
import com.cobblemon.mod.common.api.spawning.position.AreaSpawnablePositionResolver
|
||||
import com.cobblemon.mod.common.api.spawning.SpawningZoneGenerator
|
||||
import com.cobblemon.mod.common.api.starter.StarterHandler
|
||||
import com.cobblemon.mod.common.api.stats.CobblemonStats
|
||||
import com.cobblemon.mod.common.api.storage.PokemonStoreManager
|
||||
@@ -76,7 +76,12 @@ import com.cobblemon.mod.common.config.LastChangedVersion
|
||||
import com.cobblemon.mod.common.config.constraint.IntConstraint
|
||||
import com.cobblemon.mod.common.config.starter.StarterConfig
|
||||
import com.cobblemon.mod.common.data.CobblemonDataProvider
|
||||
import com.cobblemon.mod.common.events.*
|
||||
import com.cobblemon.mod.common.events.AdvancementHandler
|
||||
import com.cobblemon.mod.common.events.EntityCallbackHandler
|
||||
import com.cobblemon.mod.common.events.CallbackHandler
|
||||
import com.cobblemon.mod.common.events.PokedexHandler
|
||||
import com.cobblemon.mod.common.events.ServerTickHandler
|
||||
import com.cobblemon.mod.common.events.StatHandler
|
||||
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
|
||||
import com.cobblemon.mod.common.permission.LaxPermissionValidator
|
||||
import com.cobblemon.mod.common.platform.events.PlatformEvents
|
||||
|
||||
@@ -215,7 +215,7 @@ object CobblemonBlocks : PlatformRegistry<Registry<Block>, ResourceKey<Registry<
|
||||
@JvmField
|
||||
val SACCHARINE_WALL_SIGN = this.create("saccharine_wall_sign", CobblemonWallSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
val SACCHARINE_HANGING_SIGN = this.create("saccharine_hanging_sign", CobblemonHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_WALL_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
val SACCHARINE_WALL_HANGING_SIGN = this.create("saccharine_wall_hanging_sign", CobblemonWallHangingSignBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_HANGING_SIGN), SACCHARINE_WOOD_TYPE))
|
||||
@JvmField
|
||||
|
||||
@@ -21,12 +21,15 @@ import com.cobblemon.mod.common.client.net.callback.partymove.OpenPartyMoveCallb
|
||||
import com.cobblemon.mod.common.client.net.cooking.ToggleCookingPotLidHandler
|
||||
import com.cobblemon.mod.common.client.net.data.CobblemonMechanicsSyncHandler
|
||||
import com.cobblemon.mod.common.client.net.data.DataRegistrySyncPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.data.PokemonInteractionsSyncHandler
|
||||
import com.cobblemon.mod.common.client.net.data.RideSettingsSyncHandler
|
||||
import com.cobblemon.mod.common.client.net.debug.OpenRidingStatsDebugGUIHandler
|
||||
import com.cobblemon.mod.common.client.net.dialogue.DialogueClosedHandler
|
||||
import com.cobblemon.mod.common.client.net.dialogue.DialogueOpenedHandler
|
||||
import com.cobblemon.mod.common.client.net.effect.*
|
||||
import com.cobblemon.mod.common.client.net.effect.PokeSnackBlockParticlesHandler
|
||||
import com.cobblemon.mod.common.client.net.effect.RunPosableMoLangHandler
|
||||
import com.cobblemon.mod.common.client.net.effect.SaccharineLogBlockParticlesHandler
|
||||
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormEntityParticleHandler
|
||||
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormParticleHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.ExpGainedDataPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.InteractPokemonUIPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.gui.PokedexUIPacketHandler
|
||||
@@ -34,7 +37,11 @@ import com.cobblemon.mod.common.client.net.gui.SummaryUIPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.npc.CloseNPCEditorHandler
|
||||
import com.cobblemon.mod.common.client.net.npc.OpenNPCEditorHandler
|
||||
import com.cobblemon.mod.common.client.net.orientation.ClientboundUpdateOrientationHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.*
|
||||
import com.cobblemon.mod.common.client.net.pasture.ClosePastureHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.OpenPastureHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.PokemonPasturedHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.PokemonUnpasturedHandler
|
||||
import com.cobblemon.mod.common.client.net.pasture.UpdatePastureConflictFlagHandler
|
||||
import com.cobblemon.mod.common.client.net.pokedex.ServerConfirmedRegisterHandler
|
||||
import com.cobblemon.mod.common.client.net.pokemon.update.ClientboundUpdateRidingStateHandler
|
||||
import com.cobblemon.mod.common.client.net.pokemon.update.PokemonUpdatePacketHandler
|
||||
@@ -52,7 +59,14 @@ import com.cobblemon.mod.common.client.net.storage.party.SetPartyPokemonHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.party.SetPartyReferenceHandler
|
||||
import com.cobblemon.mod.common.client.net.storage.pc.*
|
||||
import com.cobblemon.mod.common.client.net.toast.ToastPacketHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.*
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeAcceptanceChangedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeCancelledHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeCompletedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeOfferExpiredHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeOfferNotificationHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeProcessStartedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeStartedHandler
|
||||
import com.cobblemon.mod.common.client.net.trade.TradeUpdatedHandler
|
||||
import com.cobblemon.mod.common.net.PacketRegisterInfo
|
||||
import com.cobblemon.mod.common.net.messages.client.CalculateSeatPositionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.OpenBehaviourEditorPacket
|
||||
@@ -69,12 +83,20 @@ import com.cobblemon.mod.common.net.messages.client.data.*
|
||||
import com.cobblemon.mod.common.net.messages.client.debug.RequestOpenRidingStatsDebugGUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueClosedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueOpenedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.*
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.PokeSnackBlockParticlesPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SaccharineLogBlockParticlesPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.npc.CloseNPCEditorPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.npc.OpenNPCEditorPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.orientation.ClientboundUpdateDriverInputPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.orientation.ClientboundUpdateOrientationPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.*
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.ClosePasturePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.OpenPasturePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonPasturedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonUnpasturedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pasture.UpdatePastureConflictFlagPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pokedex.ServerConfirmedRegisterPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.*
|
||||
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.AddEvolutionPacket
|
||||
@@ -94,19 +116,43 @@ import com.cobblemon.mod.common.net.messages.client.storage.party.InitializePart
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.party.MoveClientPartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyReferencePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.*
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.ClosePCPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.InitializePCPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.MoveClientPCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.OpenPCPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.RenamePCBoxPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCBoxPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.ChangePCBoxWallpaperPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.RequestPCBoxWallpapersPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.SetPCBoxWallpapersPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.UnlockPCBoxWallpaperPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.toast.ToastPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.*
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeAcceptanceChangedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeCancelledPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeCompletedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferExpiredPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferNotificationPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeProcessStartedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.trade.TradeUpdatedPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.ExpGainedDataPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.PokedexUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.*
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.*
|
||||
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.BattleChallengeResponsePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.BenchMovePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.RequestMoveSwapPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.RequestPlayerInteractionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.SelectStarterPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.SendOutPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleSelectActionsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamLeavePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamRequestPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamResponsePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.behaviour.DamageOnCollisionPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.behaviour.SetEntityBehaviourPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.block.AdjustBlockEntityViewerCountPacket
|
||||
@@ -131,7 +177,11 @@ import com.cobblemon.mod.common.net.messages.server.pasture.UnpasturePokemonPack
|
||||
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.FinishScanningPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.StartScanningPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.interact.InteractPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.*
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.ServerboundUpdateRidingStatePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetActiveMarkPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetItemHiddenPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetMarkingsPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetNicknamePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.evolution.AcceptEvolutionPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.riding.DismountPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdateDriverInputPacket
|
||||
@@ -142,11 +192,21 @@ import com.cobblemon.mod.common.net.messages.server.storage.party.MovePartyPokem
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.party.ReleasePartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.party.SwapPartyPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.*
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.*
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.AcceptTradeRequestPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.CancelTradePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.ChangeTradeAcceptancePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.PerformTradePacket
|
||||
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
|
||||
import com.cobblemon.mod.common.net.serverhandling.ChallengeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.ChallengeResponseHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.RequestInteractionsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.*
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.BattleSelectActionsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.RemoveSpectatorHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.SpectateBattleHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamLeaveHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestResponseHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.behaviour.DamageOnCollisionPacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.behaviour.SetEntityBehaviourHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.block.AdjustBlockEntityViewerCountHandler
|
||||
@@ -172,7 +232,11 @@ import com.cobblemon.mod.common.net.serverhandling.pasture.UnpasturePokemonHandl
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.FinishScanningHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.StartScanningHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.interact.InteractPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.*
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.ServerboundUpdateRidingStateHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetActiveMarkHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetItemHiddenHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetMarkingsHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetNicknameHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.riding.DismountPokemonPacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.riding.DriverInputPacketHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.riding.ServerboundUpdateRiderRotationHandler
|
||||
@@ -186,7 +250,12 @@ import com.cobblemon.mod.common.net.serverhandling.storage.party.MovePartyPokemo
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.party.ReleasePCPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.party.SwapPartyPokemonHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.storage.pc.*
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.*
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.AcceptTradeRequestHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.CancelTradeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.ChangeTradeAcceptanceHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.OfferTradeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.PerformTradeHandler
|
||||
import com.cobblemon.mod.common.net.serverhandling.trade.UpdateTradeOfferHandler
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
|
||||
@@ -332,7 +401,6 @@ object CobblemonNetwork {
|
||||
// Data registries
|
||||
list.add(PacketRegisterInfo(AbilityRegistrySyncPacket.ID, AbilityRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(CobblemonMechanicsSyncPacket.ID, CobblemonMechanicsSyncPacket::decode, CobblemonMechanicsSyncHandler))
|
||||
list.add(PacketRegisterInfo(PokemonInteractionsSyncPacket.ID, PokemonInteractionsSyncPacket::decode, PokemonInteractionsSyncHandler))
|
||||
list.add(PacketRegisterInfo(MovesRegistrySyncPacket.ID, MovesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(BerryRegistrySyncPacket.ID, BerryRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(SpeciesRegistrySyncPacket.ID, SpeciesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
|
||||
@@ -9,15 +9,14 @@
|
||||
package com.cobblemon.mod.common
|
||||
|
||||
import net.minecraft.client.RecipeBookCategories
|
||||
import net.minecraft.world.inventory.RecipeBookType
|
||||
|
||||
enum class CobblemonRecipeCategories {
|
||||
|
||||
COOKING_POT_SEARCH("COBBLEMON_COOKING_POT_SEARCH"),
|
||||
COOKING_POT_FOODS("COBBLEMON_COOKING_POT_FOODS"),
|
||||
COOKING_POT_MEDICINES("COBBLEMON_COOKING_POT_MEDICINES"),
|
||||
COOKING_POT_COMPLEX_DISHES("COBBLEMON_COOKING_POT_COMPLEX_DISHES"),
|
||||
COOKING_POT_MISC("COBBLEMON_COOKING_POT_MISC");
|
||||
COOKING_POT_SEARCH("COOKING_POT_SEARCH"),
|
||||
COOKING_POT_FOODS("COOKING_POT_FOODS"),
|
||||
COOKING_POT_MEDICINES("COOKING_POT_MEDICINES"),
|
||||
COOKING_POT_COMPLEX_DISHES("COOKING_POT_COMPLEX_DISHES"),
|
||||
COOKING_POT_MISC("COOKING_POT_MISC");
|
||||
|
||||
companion object {
|
||||
val customAggregateCategories: Map<RecipeBookCategories, List<RecipeBookCategories>> = mapOf(
|
||||
@@ -36,9 +35,6 @@ enum class CobblemonRecipeCategories {
|
||||
fun toVanillaCategory(): RecipeBookCategories {
|
||||
return RecipeBookCategories.valueOf(this.id)
|
||||
}
|
||||
}
|
||||
|
||||
object CobblemonRecipeBookTypes {
|
||||
const val COOKING_POT_NAME = "COBBLEMON_COOKING_POT"
|
||||
val COOKING_POT: RecipeBookType = RecipeBookType.valueOf(COOKING_POT_NAME)
|
||||
|
||||
}
|
||||
@@ -89,14 +89,7 @@ object CobblemonTradeOffers {
|
||||
* @return The resulting list.
|
||||
*/
|
||||
fun resolveWanderingTradeOffers(): List<WandererTradeOffer> = listOf(
|
||||
WandererTradeOffer(false, listOf(
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.VIVICHOKE_SEEDS, 6, 1, 1, 6),
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.SACCHARINE_SAPLING, 5, 1, 4, 1),
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.HEARTY_GRAINS, 1, 1, 12, 1),
|
||||
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.CHIPPED_POT, 5, 1, 1, 2),
|
||||
VillagerTrades.ItemsForEmeralds(CobblemonItems.MASTERPIECE_TEACUP, 5, 1, 1, 2)
|
||||
))
|
||||
WandererTradeOffer(false, listOf(VillagerTrades.ItemsForEmeralds(CobblemonItems.VIVICHOKE_SEEDS, 24, 1, 1, 6)))
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.ai.config.task
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.api.ai.BehaviourConfigurationContext
|
||||
import com.cobblemon.mod.common.api.ai.WrapperLivingEntityTask
|
||||
import com.cobblemon.mod.common.api.npc.configuration.MoLangConfigVariable
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.ai.tasks.DefendOwnerTask
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.BehaviorControl
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
|
||||
class DefendOwnerTaskConfig : SingleTaskConfig {
|
||||
|
||||
override fun getVariables(
|
||||
entity: LivingEntity,
|
||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||
): List<MoLangConfigVariable> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun createTask(
|
||||
entity: LivingEntity,
|
||||
behaviourConfigurationContext: BehaviourConfigurationContext
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
behaviourConfigurationContext.addMemories(
|
||||
MemoryModuleType.ATTACK_TARGET,
|
||||
CobblemonMemories.NEAREST_VISIBLE_ATTACKER,
|
||||
)
|
||||
|
||||
return WrapperLivingEntityTask(
|
||||
DefendOwnerTask.create(),
|
||||
PokemonEntity::class.java
|
||||
)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -109,7 +109,7 @@ class PollinateFlowerTaskConfig : SingleTaskConfig {
|
||||
}
|
||||
|
||||
override fun stop(level: ServerLevel, entity: LivingEntity, gameTime: Long) {
|
||||
hoverPos = null
|
||||
|
||||
if (successfulPollinationTicks > REQUIRED_SUCCESSFUL_POLLINATION_TICKS) {
|
||||
entity.brain.setMemory(CobblemonMemories.HAS_NECTAR, true)
|
||||
}
|
||||
|
||||
@@ -105,7 +105,6 @@ interface TaskConfig {
|
||||
cobblemonResource("go_to_land") to GoToLandTaskConfig::class.java,
|
||||
cobblemonResource("manage_flight_in_battle") to ManageFlightInBattleTaskConfig::class.java,
|
||||
cobblemonResource("attack_hostile_mobs") to AttackHostileMobsTaskConfig::class.java,
|
||||
cobblemonResource("defend_owner") to DefendOwnerTaskConfig::class.java,
|
||||
cobblemonResource("move_to_sweet_berry_bush") to MoveToSweetBerryBushTaskConfig::class.java,
|
||||
cobblemonResource("stop_moving_to_sweet_berry_bush") to StopTryingToReachSweetBerryBushTaskConfig::class.java,
|
||||
cobblemonResource("harvest_sweet_berry_bush") to HarvestSweetBerryBushTaskConfig::class.java,
|
||||
|
||||
+109
-36
@@ -9,8 +9,13 @@
|
||||
package com.cobblemon.mod.common.api.cooking
|
||||
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.util.math.geometry.toDegrees
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import net.minecraft.util.FastColor
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
private val colourMap = mapOf(
|
||||
Flavour.SPICY to 0xFEB37D,
|
||||
@@ -29,30 +34,27 @@ private val bubbleColourMap = mapOf(
|
||||
)
|
||||
|
||||
fun getColourMixFromSeasonings(seasonings: List<ItemStack>, forBubbles: Boolean = false): Int? {
|
||||
val flavourValues = mutableMapOf<Flavour, Int>()
|
||||
for (seasoning in seasonings) {
|
||||
val flavours = Seasonings.getFlavoursFromItemStack(seasoning) ?: continue
|
||||
for ((flavour, value) in flavours.entries) {
|
||||
flavourValues[flavour] = (flavourValues[flavour] ?: 0) + value
|
||||
}
|
||||
}
|
||||
val flavors = seasonings
|
||||
.mapNotNull { Seasonings.getFlavoursFromItemStack(it) }
|
||||
.flatMap { it.entries }
|
||||
.groupingBy { it.key }
|
||||
.fold(0) { acc, entry -> acc + entry.value }
|
||||
|
||||
if (flavourValues.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
if (flavors.isEmpty()) return null
|
||||
|
||||
val maxFlavorValue = flavourValues.values.maxOrNull()
|
||||
val dominantFlavours = flavourValues.filter { it.value == maxFlavorValue }.map { it.key }
|
||||
val maxFlavorValue = flavors.values.maxOrNull()
|
||||
val dominantFlavors = flavors.filter { it.value == maxFlavorValue }.map { it.key }
|
||||
|
||||
return getColourMixFromFlavours(dominantFlavours, forBubbles)
|
||||
return getColourMixFromFlavours(dominantFlavors, forBubbles)
|
||||
}
|
||||
|
||||
fun getColourMixFromFlavours(dominantFlavours: List<Flavour>, forBubbles: Boolean = false): Int? {
|
||||
val colors =
|
||||
dominantFlavours
|
||||
.mapNotNull { if (forBubbles) bubbleColourMap[it] else colourMap[it] }
|
||||
dominantFlavours.mapNotNull { if (forBubbles) bubbleColourMap[it] else colourMap[it] }
|
||||
.map { FastColor.ARGB32.opaque(it) }
|
||||
|
||||
if (colors.isEmpty()) return null
|
||||
|
||||
return getColourMixFromColors(colors)
|
||||
}
|
||||
|
||||
@@ -60,33 +62,104 @@ fun getColourMixFromRideStatBoosts(dominantBoosts: Iterable<RidingStat>, forBubb
|
||||
return getColourMixFromFlavours(dominantBoosts.map { it.flavour }, forBubbles)
|
||||
}
|
||||
|
||||
// Mixing RGB colors directly often gives poor results
|
||||
// Converting them to HSL and averaging hues circularly produces more natural blends
|
||||
fun getColourMixFromColors(colors: List<Int>): Int? {
|
||||
if (colors.isEmpty()) return null
|
||||
if (colors.size == 1) return colors[0]
|
||||
|
||||
val firstWeight = 0.7f
|
||||
val otherWeightTotal = 1f - firstWeight
|
||||
val otherWeight = otherWeightTotal / (colors.size - 1)
|
||||
val hslColors = colors.map {
|
||||
val red = FastColor.ARGB32.red(it)
|
||||
val green = FastColor.ARGB32.green(it)
|
||||
val blue = FastColor.ARGB32.blue(it)
|
||||
|
||||
var alphaSum = 0f
|
||||
var redSum = 0f
|
||||
var greenSum = 0f
|
||||
var blueSum = 0f
|
||||
|
||||
for (i in colors.indices) {
|
||||
val weight = if (i == 0) firstWeight else otherWeight
|
||||
val color = colors[i]
|
||||
|
||||
alphaSum += FastColor.ARGB32.alpha(color) * weight
|
||||
redSum += FastColor.ARGB32.red(color) * weight
|
||||
greenSum += FastColor.ARGB32.green(color) * weight
|
||||
blueSum += FastColor.ARGB32.blue(color) * weight
|
||||
rgbToHsl(red, green, blue)
|
||||
}
|
||||
|
||||
return FastColor.ARGB32.color(
|
||||
alphaSum.toInt(),
|
||||
redSum.toInt(),
|
||||
greenSum.toInt(),
|
||||
blueSum.toInt()
|
||||
val hues = hslColors.map { it.h.toDouble() }
|
||||
val huesAverage = hueAverage(hues).toFloat()
|
||||
val saturations = hslColors.map { it.s }
|
||||
val saturationsAverage = average(saturations)
|
||||
val lightness = hslColors.map { it.l }
|
||||
val lightnessAverage = average(lightness)
|
||||
|
||||
val rgbColor = hslToRgb(huesAverage, saturationsAverage, lightnessAverage)
|
||||
|
||||
return FastColor.ARGB32.color(rgbColor.r, rgbColor.g, rgbColor.b)
|
||||
}
|
||||
|
||||
// Based on https://iter.ca/post/hue-avg
|
||||
fun hueAverage(hues: List<Double>): Float {
|
||||
val points = hues.map { hue ->
|
||||
val rad = hue.toRadians()
|
||||
Pair(cos(rad), sin(rad))
|
||||
}
|
||||
|
||||
val avgX = points.sumOf { it.first.toDouble() } / points.size
|
||||
val avgY = points.sumOf { it.second.toDouble() } / points.size
|
||||
|
||||
var degrees = atan2(avgY, avgX).toDegrees()
|
||||
if (degrees < 0) {
|
||||
degrees += 360f
|
||||
} else if (degrees > 360) {
|
||||
degrees -= 360f
|
||||
}
|
||||
|
||||
return degrees
|
||||
}
|
||||
|
||||
fun average(values: List<Float>): Float {
|
||||
if (values.isEmpty()) return 0f
|
||||
return values.sum() / values.size
|
||||
}
|
||||
|
||||
data class HSL(val h: Float, val s: Float, val l: Float)
|
||||
|
||||
fun rgbToHsl(r: Int, g: Int, b: Int): HSL {
|
||||
val rf = r / 255f
|
||||
val gf = g / 255f
|
||||
val bf = b / 255f
|
||||
|
||||
val max = maxOf(rf, gf, bf)
|
||||
val min = minOf(rf, gf, bf)
|
||||
val delta = max - min
|
||||
|
||||
var h = 0f
|
||||
val l = (max + min) / 2f
|
||||
val s = if (delta == 0f) 0f else delta / (1f - kotlin.math.abs(2f * l - 1f))
|
||||
|
||||
if (delta != 0f) {
|
||||
h = when (max) {
|
||||
rf -> ((gf - bf) / delta) % 6f
|
||||
gf -> ((bf - rf) / delta) + 2f
|
||||
else -> ((rf - gf) / delta) + 4f
|
||||
}
|
||||
h *= 60f
|
||||
if (h < 0) h += 360f
|
||||
}
|
||||
|
||||
return HSL(h, s, l)
|
||||
}
|
||||
|
||||
data class RGB(val r: Int, val g: Int, val b: Int)
|
||||
|
||||
fun hslToRgb(h: Float, s: Float, l: Float): RGB {
|
||||
val c = (1f - kotlin.math.abs(2f * l - 1f)) * s
|
||||
val x = c * (1f - kotlin.math.abs((h / 60f) % 2f - 1f))
|
||||
val m = l - c / 2f
|
||||
|
||||
val (rf, gf, bf) = when {
|
||||
h < 60f -> Triple(c, x, 0f)
|
||||
h < 120f -> Triple(x, c, 0f)
|
||||
h < 180f -> Triple(0f, c, x)
|
||||
h < 240f -> Triple(0f, x, c)
|
||||
h < 300f -> Triple(x, 0f, c)
|
||||
else -> Triple(c, 0f, x)
|
||||
}
|
||||
|
||||
return RGB(
|
||||
((rf + m) * 255).toInt().coerceIn(0, 255),
|
||||
((gf + m) * 255).toInt().coerceIn(0, 255),
|
||||
((bf + m) * 255).toInt().coerceIn(0, 255)
|
||||
)
|
||||
}
|
||||
@@ -37,6 +37,8 @@ import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.FormattedCharSequence
|
||||
import org.joml.Matrix4f
|
||||
import org.joml.Vector3f
|
||||
import org.lwjgl.opengl.GL30
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
@JvmOverloads
|
||||
fun blitk(
|
||||
@@ -355,10 +357,10 @@ fun renderSprite(matrixStack: PoseStack, sprite: ResourceLocation) {
|
||||
val matrix: PoseStack.Pose = matrixStack.last()
|
||||
matrix.pose().translate(-1f, 0f, 0f)
|
||||
|
||||
RenderSystem.setShaderTexture(0, sprite)
|
||||
RenderSystem.setShaderTexture(0, sprite);
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader)
|
||||
|
||||
val buffer = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX)
|
||||
var buffer = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX)
|
||||
|
||||
buffer.addVertex(matrix, 2f, 0f, 0.0f).setUv(1f, 0f)
|
||||
buffer.addVertex(matrix, 0f, 0f, 0.0f).setUv(0f, 0f)
|
||||
@@ -367,3 +369,25 @@ fun renderSprite(matrixStack: PoseStack, sprite: ResourceLocation) {
|
||||
|
||||
BufferUploader.drawWithShader(buffer.buildOrThrow())
|
||||
}
|
||||
|
||||
fun getPixelRGB(x: Int, y: Int): Triple<Int, Int, Int> {
|
||||
val window = Minecraft.getInstance().window
|
||||
val scale = window.guiScale
|
||||
val buffer = ByteBuffer.allocateDirect(4)
|
||||
|
||||
RenderSystem.readPixels(
|
||||
(x * scale).toInt(),
|
||||
(window.height - y * scale - scale).toInt(),
|
||||
1,
|
||||
1,
|
||||
GL30.GL_RGBA,
|
||||
GL30.GL_UNSIGNED_BYTE,
|
||||
buffer
|
||||
)
|
||||
|
||||
return Triple(
|
||||
buffer[0].toInt() and 0xFF,
|
||||
buffer[1].toInt() and 0xFF,
|
||||
buffer[2].toInt() and 0xFF
|
||||
)
|
||||
}
|
||||
+2
-7
@@ -12,10 +12,10 @@ import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.OwnerQueryRequirement
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.net.messages.client.data.PokemonInteractionsSyncPacket
|
||||
import com.cobblemon.mod.common.pokemon.adapters.CobblemonRequirementAdapter
|
||||
import com.cobblemon.mod.common.pokemon.evolution.adapters.LegacyItemConditionWrapperAdapter
|
||||
import com.cobblemon.mod.common.pokemon.requirements.PokemonPropertiesRequirement
|
||||
@@ -51,12 +51,7 @@ object PokemonInteractions : JsonDataRegistry<PokemonInteractionSet> {
|
||||
val speciesInteractions = mutableListOf<PokemonInteractionSet>()
|
||||
val generalInteractions = mutableListOf<PokemonInteractionSet>()
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
PokemonInteractionsSyncPacket(
|
||||
speciesInteractions,
|
||||
generalInteractions,
|
||||
).sendToPlayer(player)
|
||||
}
|
||||
override fun sync(player: ServerPlayer) {}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, PokemonInteractionSet>) {
|
||||
speciesInteractions.clear()
|
||||
|
||||
+19
-88
@@ -15,10 +15,11 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
|
||||
import com.cobblemon.mod.common.pokemon.adapters.CobblemonRequirementAdapter
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.giveOrDropItemStack
|
||||
import com.cobblemon.mod.common.util.withPlayerValue
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundSource
|
||||
@@ -27,83 +28,30 @@ import net.minecraft.world.entity.EquipmentSlot
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
/**
|
||||
* A
|
||||
*/
|
||||
data class PokemonInteractionSet(
|
||||
val requirements: List<Requirement> = listOf(),
|
||||
val interactions: List<PokemonInteraction> = listOf(),
|
||||
) {
|
||||
fun encode(buffer: FriendlyByteBuf) {
|
||||
buffer.writeCollection(requirements) { it, requirement ->
|
||||
CobblemonRequirementAdapter.encode(requirement, it)
|
||||
}
|
||||
buffer.writeCollection(interactions) { it, interaction ->
|
||||
interaction.encode(it)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun decode(buffer: FriendlyByteBuf): PokemonInteractionSet {
|
||||
val requirements = buffer.readList { it ->
|
||||
CobblemonRequirementAdapter.decode(it)
|
||||
}
|
||||
val interactions = buffer.readList { it ->
|
||||
PokemonInteraction.decode(it)
|
||||
}
|
||||
|
||||
return PokemonInteractionSet(
|
||||
requirements,
|
||||
interactions,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val interactions: List<PokemonInteraction> = listOf()
|
||||
)
|
||||
data class PokemonInteraction(
|
||||
val grouping: ResourceLocation,
|
||||
val requirements: List<Requirement> = listOf(),
|
||||
val effects: List<InteractionEffect> = listOf(),
|
||||
val cooldown: ExpressionLike = "0".asExpressionLike()
|
||||
) {
|
||||
fun encode(buffer: FriendlyByteBuf) {
|
||||
buffer.writeResourceLocation(grouping)
|
||||
buffer.writeCollection(requirements) { it, requirement ->
|
||||
CobblemonRequirementAdapter.encode(requirement, it)
|
||||
}
|
||||
buffer.writeExpressionLike(cooldown)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun decode(buffer: FriendlyByteBuf): PokemonInteraction {
|
||||
val grouping = buffer.readResourceLocation()
|
||||
val requirements = buffer.readList { it ->
|
||||
CobblemonRequirementAdapter.decode(it)
|
||||
}
|
||||
|
||||
// No need to sync these for now
|
||||
val effects = emptyList<InteractionEffect>()
|
||||
val cooldown = buffer.readExpressionLike()
|
||||
|
||||
return PokemonInteraction(
|
||||
grouping,
|
||||
requirements,
|
||||
effects,
|
||||
cooldown,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
interface InteractionEffect {
|
||||
fun applyEffect(pokemon: PokemonEntity, player: ServerPlayer)
|
||||
}
|
||||
|
||||
class DropItemEffect(val item: ResourceLocation, val amount: IntRange?) : InteractionEffect {
|
||||
class DropItemEffect(val item: ResourceLocation, val amount: IntRange?): InteractionEffect {
|
||||
override fun applyEffect(
|
||||
pokemon: PokemonEntity,
|
||||
player: ServerPlayer
|
||||
) {
|
||||
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException(
|
||||
"Cannot load item with id: $item"
|
||||
)
|
||||
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException("Cannot load item with id: $item")
|
||||
val stack = ItemStack(item)
|
||||
stack.count = amount?.randomOrNull() ?: 1
|
||||
if (stack.isEmpty)
|
||||
@@ -120,14 +68,12 @@ class DropItemEffect(val item: ResourceLocation, val amount: IntRange?) : Intera
|
||||
}
|
||||
}
|
||||
|
||||
class GiveItemEffect(val item: ResourceLocation, val amount: IntRange?) : InteractionEffect {
|
||||
class GiveItemEffect(val item: ResourceLocation, val amount: IntRange?): InteractionEffect {
|
||||
override fun applyEffect(
|
||||
pokemon: PokemonEntity,
|
||||
player: ServerPlayer
|
||||
) {
|
||||
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException(
|
||||
"Cannot load item with id: $item"
|
||||
)
|
||||
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException("Cannot load item with id: $item")
|
||||
val stack = ItemStack(item)
|
||||
stack.count = amount?.randomOrNull() ?: 1
|
||||
if (stack.isEmpty)
|
||||
@@ -140,29 +86,14 @@ class GiveItemEffect(val item: ResourceLocation, val amount: IntRange?) : Intera
|
||||
}
|
||||
}
|
||||
|
||||
class PlaySoundEffect(
|
||||
val sound: ResourceLocation,
|
||||
val soundSource: SoundSource?,
|
||||
val playAround: Boolean = true,
|
||||
val distance: Double = 64.0,
|
||||
val volume: Float = 1.0F,
|
||||
val pitch: Float = 1.0F
|
||||
) : InteractionEffect {
|
||||
class PlaySoundEffect(val sound: ResourceLocation, val soundSource: SoundSource?, val playAround: Boolean = true, val distance: Double = 64.0, val volume: Float = 1.0F, val pitch: Float = 1.0F): InteractionEffect {
|
||||
override fun applyEffect(
|
||||
pokemon: PokemonEntity,
|
||||
player: ServerPlayer
|
||||
) {
|
||||
val packet = UnvalidatedPlaySoundS2CPacket(
|
||||
sound,
|
||||
soundSource ?: SoundSource.NEUTRAL,
|
||||
pokemon.x,
|
||||
pokemon.y,
|
||||
pokemon.z,
|
||||
volume,
|
||||
pitch
|
||||
)
|
||||
val packet = UnvalidatedPlaySoundS2CPacket(sound, soundSource ?: SoundSource.NEUTRAL, pokemon.x, pokemon.y, pokemon.z, volume, pitch)
|
||||
if (playAround) {
|
||||
packet.sendToPlayersAround(pokemon.x, pokemon.y, pokemon.z, distance, pokemon.level().dimension())
|
||||
packet.sendToPlayersAround( pokemon.x, pokemon.y, pokemon.z, distance, pokemon.level().dimension())
|
||||
} else {
|
||||
packet.sendToPlayer(player)
|
||||
}
|
||||
@@ -173,7 +104,7 @@ class PlaySoundEffect(
|
||||
}
|
||||
}
|
||||
|
||||
class ShrinkItemEffect(val amount: Int = 1) : InteractionEffect {
|
||||
class ShrinkItemEffect(val amount: Int = 1): InteractionEffect {
|
||||
override fun applyEffect(
|
||||
pokemon: PokemonEntity,
|
||||
player: ServerPlayer
|
||||
@@ -189,7 +120,7 @@ class ShrinkItemEffect(val amount: Int = 1) : InteractionEffect {
|
||||
}
|
||||
}
|
||||
|
||||
class ScriptEffect(val script: ExpressionLike) : InteractionEffect {
|
||||
class ScriptEffect(val script: ExpressionLike): InteractionEffect {
|
||||
override fun applyEffect(
|
||||
pokemon: PokemonEntity,
|
||||
player: ServerPlayer
|
||||
|
||||
+3
-7
@@ -92,17 +92,13 @@ interface PokemonAndMoveSelectingItem {
|
||||
}
|
||||
|
||||
fun canUseOnPokemon(stack: ItemStack, pokemon: Pokemon): Boolean {
|
||||
if (pokemon.entity == null && stack.`is`(CobblemonItemTags.POKE_FOOD) && pokemon.isFull()) {
|
||||
return false
|
||||
if (stack.`is`(CobblemonItemTags.POKE_FOOD)) {
|
||||
return !pokemon.isFull()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun canUseOnBattlePokemon(stack: ItemStack, battlePokemon: BattlePokemon): Boolean {
|
||||
return bagItem!!.canUse(stack, battlePokemon.actor.battle, battlePokemon)
|
||||
}
|
||||
|
||||
fun canUseOnBattlePokemon(stack: ItemStack, battlePokemon: BattlePokemon): Boolean = bagItem!!.canUse(stack, battlePokemon.actor.battle, battlePokemon)
|
||||
fun canUseOnMove(stack: ItemStack, pokemon: Pokemon, move: Move): Boolean = canUseOnMove(stack, move)
|
||||
fun canUseOnMove(stack: ItemStack, move: Move): Boolean
|
||||
|
||||
|
||||
@@ -107,16 +107,13 @@ interface PokemonSelectingItem {
|
||||
}
|
||||
|
||||
fun canUseOnPokemon(stack: ItemStack, pokemon: Pokemon): Boolean {
|
||||
if (pokemon.entity == null && stack.`is`(CobblemonItemTags.POKE_FOOD) && pokemon.isFull()) {
|
||||
return false
|
||||
if (stack.`is`(CobblemonItemTags.POKE_FOOD)) {
|
||||
return !pokemon.isFull()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun canUseOnBattlePokemon(stack: ItemStack, battlePokemon: BattlePokemon): Boolean {
|
||||
return bagItem!!.canUse(stack, battlePokemon.actor.battle, battlePokemon)
|
||||
}
|
||||
fun canUseOnBattlePokemon(stack: ItemStack, battlePokemon: BattlePokemon): Boolean = bagItem!!.canUse(stack, battlePokemon.actor.battle, battlePokemon)
|
||||
|
||||
fun interactWithSpecificBattle(player: ServerPlayer, stack: ItemStack, battlePokemon: BattlePokemon): InteractionResultHolder<ItemStack> {
|
||||
return if (canUseOnBattlePokemon(stack, battlePokemon)) {
|
||||
|
||||
@@ -779,20 +779,6 @@ object MoLangFunctions {
|
||||
battleStartResult.ifSuccessful { returnValue = it.struct }
|
||||
return@put returnValue
|
||||
}
|
||||
map.put("get_custom_stat") { params ->
|
||||
val statName = params.getString(0)
|
||||
|
||||
val resourceLocation = ResourceLocation.tryParse(statName) ?: return@put DoubleValue.ZERO
|
||||
val statResourceLocation = BuiltInRegistries.CUSTOM_STAT.get(resourceLocation) ?: return@put DoubleValue.ZERO
|
||||
|
||||
val exists = net.minecraft.stats.Stats.CUSTOM.contains(statResourceLocation)
|
||||
if (!exists) return@put DoubleValue.ZERO
|
||||
|
||||
val stat = net.minecraft.stats.Stats.CUSTOM.get(statResourceLocation)
|
||||
val value = player.stats.getValue(stat)
|
||||
|
||||
DoubleValue(value)
|
||||
}
|
||||
}
|
||||
map
|
||||
}
|
||||
@@ -1566,9 +1552,8 @@ object MoLangFunctions {
|
||||
}
|
||||
map.put("feed_pokemon") { params ->
|
||||
val amount = params.getDouble(0)
|
||||
val playSound = params.getBooleanOrNull(1) != false
|
||||
val playMoodParticles = params.getBooleanOrNull(2) != false
|
||||
return@put DoubleValue(pokemon.feedPokemon(amount.toInt(), playSound, playMoodParticles))
|
||||
val playSound = params.getBooleanOrNull(1) ?: true
|
||||
pokemon.feedPokemon(amount.toInt(), playSound)
|
||||
}
|
||||
map.put("behaviour") { pokemon.form.behaviour.struct }
|
||||
map.put("behavior") { pokemon.form.behaviour.struct } // Inferior
|
||||
@@ -1754,35 +1739,22 @@ object MoLangFunctions {
|
||||
pokemon.removeCosmeticItem()
|
||||
}
|
||||
map.put("add_marks") { params ->
|
||||
var appliedMark = false
|
||||
for (param in params.params) {
|
||||
val identifier = param.asString().asIdentifierDefaultingNamespace()
|
||||
val mark = Marks.getByIdentifier(identifier)
|
||||
if (mark != null) {
|
||||
pokemon.exchangeMark(mark, true)
|
||||
appliedMark = true
|
||||
}
|
||||
if (mark != null) pokemon.exchangeMark(mark, true)
|
||||
}
|
||||
|
||||
DoubleValue(appliedMark)
|
||||
}
|
||||
map.put("add_marks_with_chance") { params ->
|
||||
var appliedMark = false
|
||||
for (param in params.params) {
|
||||
val identifier = param.asString().asIdentifierDefaultingNamespace()
|
||||
val mark = Marks.getByIdentifier(identifier)
|
||||
|
||||
mark?.let {
|
||||
val probability = it.chance.coerceIn(0F, 1F) * 100
|
||||
val randomValue = Random.nextDouble(0.0, 100.0)
|
||||
if (randomValue < probability) {
|
||||
pokemon.exchangeMark(it, true)
|
||||
appliedMark = true
|
||||
}
|
||||
if (randomValue < probability) pokemon.exchangeMark(it, true)
|
||||
}
|
||||
}
|
||||
|
||||
DoubleValue(appliedMark)
|
||||
}
|
||||
map.put("add_potential_marks") { params ->
|
||||
for (param in params.params) {
|
||||
|
||||
@@ -409,7 +409,13 @@ open class PokemonProperties {
|
||||
shiny?.let { pokemon.shiny = it }
|
||||
gender?.let { pokemon.gender = it }
|
||||
level?.let { pokemon.level = it }
|
||||
friendship?.also { pokemon.setFriendship(it) }
|
||||
friendship.also {
|
||||
if (it != null) {
|
||||
pokemon.setFriendship(it)
|
||||
} else {
|
||||
pokemon.setFriendship(pokemon.form.baseFriendship)
|
||||
}
|
||||
}
|
||||
fullness?.let { pokemon.currentFullness = it }
|
||||
pokeball?.let { PokeBalls.getPokeBall(it.asIdentifierDefaultingNamespace())?.let { pokeball -> pokemon.caughtBall = pokeball } }
|
||||
nature?.let { Natures.getNature(it.asIdentifierDefaultingNamespace())?.let { nature -> pokemon.nature = nature } }
|
||||
|
||||
+4
-5
@@ -12,7 +12,6 @@ import com.cobblemon.mod.common.entity.npc.NPCEntity
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
|
||||
/**
|
||||
* A [Requirement] that expects a [LivingEntity] to be attached to the [Pokemon].
|
||||
@@ -27,7 +26,7 @@ interface OwnerQueryRequirement : Requirement {
|
||||
override fun check(pokemon: Pokemon): Boolean {
|
||||
val owner = pokemon.getOwnerEntity() ?: return false
|
||||
return when (owner) {
|
||||
is Player -> {
|
||||
is ServerPlayer -> {
|
||||
this.checkPlayer(pokemon, owner)
|
||||
}
|
||||
is NPCEntity -> {
|
||||
@@ -38,13 +37,13 @@ interface OwnerQueryRequirement : Requirement {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given [Pokemon] & [Player] satisfies the requirement.
|
||||
* Checks if the given [Pokemon] & [ServerPlayer] satisfies the requirement.
|
||||
*
|
||||
* @param pokemon The [Pokemon] being queried.
|
||||
* @param owner The [Player] that owns this [Pokemon].
|
||||
* @param owner The [ServerPlayer] that owns this [Pokemon].
|
||||
* @return If the requirement was satisfied.
|
||||
*/
|
||||
fun checkPlayer(pokemon: Pokemon, owner: Player): Boolean
|
||||
fun checkPlayer(pokemon: Pokemon, owner: ServerPlayer): Boolean
|
||||
|
||||
/**
|
||||
* Checks if the given [Pokemon] & [NPCEntity] satisfies the requirement.
|
||||
|
||||
+1
-1
@@ -322,7 +322,7 @@ class JetBehaviour : RidingBehaviour<JetSettings, JetState> {
|
||||
val pitchRot = handling * state.currMouseYForce.get()
|
||||
|
||||
// Roll
|
||||
val rollRot = handling * state.currMouseXForce.get()
|
||||
val rollRot = handling * 1.5 * state.currMouseXForce.get()
|
||||
|
||||
val mouseRotation = Vec3(0.0, pitchRot, rollRot)
|
||||
|
||||
|
||||
+19
-49
@@ -114,10 +114,10 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
|
||||
input: Vec3
|
||||
) {
|
||||
if (vehicle.level().isClientSide) {
|
||||
handleSprinting(state, driver)
|
||||
handleSprinting(state)
|
||||
inAirCheck(state, vehicle)
|
||||
tickStamina(settings, state, vehicle)
|
||||
state.walking.set(state.rideVelocity.get().horizontalDistance() > 0.01 || driver.zza != 0.0f)
|
||||
state.walking.set(state.rideVelocity.get().horizontalDistance() > 0.01)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,24 +139,9 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
|
||||
}
|
||||
|
||||
fun handleSprinting(
|
||||
state: HorseState,
|
||||
driver: Player
|
||||
state: HorseState
|
||||
) {
|
||||
val sprintTimerTickLength = 7 // Emulate vanillas tick timer length
|
||||
var hasDoubleTapped = false
|
||||
|
||||
// If you are not sprinting and you just pressed down and theres no
|
||||
if (!state.forwardHeldLastTick.get() && Minecraft.getInstance().options.keyUp.isDown() && !state.sprinting.get() && state.sprintTickTimer.get() == 0) {
|
||||
state.sprintTickTimer.set(sprintTimerTickLength)
|
||||
} else if (!state.forwardHeldLastTick.get() && Minecraft.getInstance().options.keyUp.isDown() && state.sprintTickTimer.get() != 0) { // If has double tapped
|
||||
hasDoubleTapped = true
|
||||
}else if(!state.sprinting.get() && state.sprintTickTimer.get() > 0) {
|
||||
state.sprintTickTimer.set(state.sprintTickTimer.get() - 1)
|
||||
} else {
|
||||
state.sprintTickTimer.set(0)
|
||||
}
|
||||
|
||||
val tryingToSprint = (Minecraft.getInstance().options.keySprint.isDown() && Minecraft.getInstance().options.keyUp.isDown()) || hasDoubleTapped
|
||||
val tryingToSprint = Minecraft.getInstance().options.keySprint.isDown() && Minecraft.getInstance().options.keyUp.isDown()
|
||||
|
||||
if (state.stamina.get() <= 0.0f || !Minecraft.getInstance().options.keyUp.isDown()) {
|
||||
// If stamina runs out or the player is not holding forward then stop sprinting
|
||||
@@ -171,9 +156,6 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
|
||||
// If you are trying to sprint and the toggle allows it then start sprinting and disable toggle
|
||||
state.sprinting.set(true)
|
||||
}
|
||||
|
||||
// Take not of whether forward was held last tick
|
||||
state.forwardHeldLastTick.set(Minecraft.getInstance().options.keyUp.isDown())
|
||||
}
|
||||
|
||||
fun tickStamina(
|
||||
@@ -245,7 +227,7 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
|
||||
|
||||
// Normalize the current rotation diff
|
||||
val rotDiff = Mth.wrapDegrees(driver.yRot - vehicle.yRot).coerceIn(-maxYawDiff,maxYawDiff)
|
||||
val rotDiffNorm = rotDiff / maxYawDiff//(rotDiff / maxYawDiff).coerceIn(-0.2f, 0.2f)
|
||||
val rotDiffNorm = rotDiff / maxYawDiff
|
||||
|
||||
// Take the square root so that the ride levels out quicker when at lower differences between entity
|
||||
// y and driver y
|
||||
@@ -258,7 +240,7 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
|
||||
val walkSpeed = getWalkSpeed(vehicle)
|
||||
val w = max(walkSpeed, vehicle.deltaMovement.horizontalDistance())
|
||||
val invRelSpeed = (RidingBehaviour.scaleToRange(w, walkSpeed, topSpeed ) - 1.0f) * -1.0f
|
||||
val turnRate = ((handling.toFloat() / 20.0f) * max(walkHandlingBoost * sqrt(abs(invRelSpeed)), 1.0)).toFloat()
|
||||
val turnRate = ((handling.toFloat() / 20.0f) * max(walkHandlingBoost * invRelSpeed, 1.0)).toFloat()
|
||||
|
||||
// Ensure you only ever rotate as much difference as there is between the angles.
|
||||
val turnSpeed = turnRate * rotDiffMod
|
||||
@@ -291,24 +273,30 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
|
||||
val rideTopSpeed = vehicle.runtime.resolveDouble(settings.speedExpr ?: globalHorse.speedExpr!!)
|
||||
val walkSpeed = getWalkSpeed(vehicle)
|
||||
val topSpeed = if(canSprint && state.sprinting.get()) rideTopSpeed else walkSpeed
|
||||
val accelTime = if(state.sprinting.get()) (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalHorse.accelerationExpr!!) * 20.0) else 0.5 * 20.0
|
||||
val accel = topSpeed / accelTime
|
||||
val accel = topSpeed / (vehicle.runtime.resolveDouble(settings.accelerationExpr ?: globalHorse.accelerationExpr!!) * 20.0)
|
||||
var activeInput = false
|
||||
|
||||
/******************************************************
|
||||
* Gather the previous velocity and check for horizontal
|
||||
* collisions
|
||||
*****************************************************/
|
||||
val dmSpeed = vehicle.deltaMovement.length()
|
||||
val rvSpeed = state.rideVelocity.get().length()
|
||||
var newVelocity = state.rideVelocity.get() //.normalize().scale(vehicle.deltaMovement.horizontalDistance())
|
||||
|
||||
/******************************************************
|
||||
* Gather the previous velocity and check for horizontal
|
||||
* collisions
|
||||
*****************************************************/
|
||||
// if (dmSpeed > rvSpeed) {
|
||||
// // align the velocity vector to be in local vehicle space
|
||||
// newVelocity = vehicle.deltaMovement
|
||||
// val yawAligned = Matrix3f().rotateY(-vehicle.yRot.toRadians())
|
||||
// newVelocity = (newVelocity.toVector3f().mul(yawAligned)).toVec3d()
|
||||
// }
|
||||
|
||||
if (vehicle.horizontalCollision) {
|
||||
var horizontalVec = Vec3(newVelocity.x, 0.0, newVelocity.z)
|
||||
horizontalVec = horizontalVec.normalize().scale(min(horizontalVec.length(), 0.3))
|
||||
newVelocity = Vec3(horizontalVec.x, newVelocity.y, horizontalVec.z)
|
||||
newVelocity = newVelocity.normalize().scale(vehicle.deltaMovement.length())
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
@@ -384,7 +372,7 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
|
||||
state.jumpTicks.set(state.jumpTicks.get() + 1)
|
||||
}
|
||||
|
||||
// Zero out lateral velocity possibly picked up from a controller transition
|
||||
//Zero out lateral velocity possibly picked up from a controller transition
|
||||
newVelocity = Vec3(0.0, newVelocity.y, newVelocity.z)
|
||||
|
||||
|
||||
@@ -473,7 +461,7 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
|
||||
vehicle: PokemonEntity,
|
||||
driver: Player
|
||||
): Float {
|
||||
return if (state.sprinting.get()) 1.15f else 1.0f
|
||||
return 1.0f
|
||||
}
|
||||
|
||||
override fun useAngVelSmoothing(
|
||||
@@ -532,14 +520,6 @@ class HorseBehaviour : RidingBehaviour<HorseSettings, HorseState> {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun maxUpStep(
|
||||
settings: HorseSettings,
|
||||
state: HorseState,
|
||||
vehicle: PokemonEntity
|
||||
): Float? {
|
||||
return if (state.inAir.get()) 0.0f else 1.2f
|
||||
}
|
||||
|
||||
override fun getRideSounds(
|
||||
settings: HorseSettings,
|
||||
state: HorseState,
|
||||
@@ -638,8 +618,6 @@ class HorseState : RidingBehaviourState() {
|
||||
var sprintToggleable = ridingState(false, Side.CLIENT)
|
||||
var inAir = ridingState(false, Side.CLIENT)
|
||||
var jumpTicks = ridingState(0, Side.CLIENT)
|
||||
var sprintTickTimer = ridingState(0, Side.CLIENT)
|
||||
var forwardHeldLastTick = ridingState(false, Side.CLIENT)
|
||||
|
||||
override fun encode(buffer: FriendlyByteBuf) {
|
||||
super.encode(buffer)
|
||||
@@ -648,8 +626,6 @@ class HorseState : RidingBehaviourState() {
|
||||
buffer.writeBoolean(sprintToggleable.get())
|
||||
buffer.writeBoolean(inAir.get())
|
||||
buffer.writeInt(jumpTicks.get())
|
||||
buffer.writeInt(sprintTickTimer.get())
|
||||
buffer.writeBoolean(forwardHeldLastTick.get())
|
||||
}
|
||||
|
||||
override fun decode(buffer: FriendlyByteBuf) {
|
||||
@@ -659,8 +635,6 @@ class HorseState : RidingBehaviourState() {
|
||||
sprintToggleable.set(buffer.readBoolean(), forced = true)
|
||||
inAir.set(buffer.readBoolean(), forced = true)
|
||||
jumpTicks.set(buffer.readInt(), forced = true)
|
||||
sprintTickTimer.set(buffer.readInt(), forced = true)
|
||||
forwardHeldLastTick.set(buffer.readBoolean(), forced = true)
|
||||
}
|
||||
|
||||
override fun reset() {
|
||||
@@ -670,8 +644,6 @@ class HorseState : RidingBehaviourState() {
|
||||
sprintToggleable.set(false, forced = true)
|
||||
inAir.set(false, forced = true)
|
||||
jumpTicks.set(0, forced = true)
|
||||
sprintTickTimer.set(0, forced = true)
|
||||
forwardHeldLastTick.set(false, forced = true)
|
||||
}
|
||||
|
||||
override fun copy() = HorseState().also {
|
||||
@@ -682,8 +654,6 @@ class HorseState : RidingBehaviourState() {
|
||||
it.sprintToggleable.set(this.sprintToggleable.get(), forced = true)
|
||||
it.inAir.set(this.inAir.get(), forced = true)
|
||||
it.jumpTicks.set(this.jumpTicks.get(), forced = true)
|
||||
it.sprintTickTimer.set(this.sprintTickTimer.get(), forced = true)
|
||||
it.forwardHeldLastTick.set(this.forwardHeldLastTick.get(), forced = true)
|
||||
}
|
||||
|
||||
override fun shouldSync(previous: RidingBehaviourState): Boolean {
|
||||
|
||||
@@ -12,7 +12,6 @@ package com.cobblemon.mod.common.api.riding.sound
|
||||
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeBehaviour
|
||||
import com.cobblemon.mod.common.api.riding.behaviour.types.composite.CompositeState
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.getIsSubmerged
|
||||
import com.cobblemon.mod.common.util.resolveDouble
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance
|
||||
@@ -66,21 +65,6 @@ class RideLoopSound(val ride: PokemonEntity, val soundSettings: RideSoundSetting
|
||||
return
|
||||
}
|
||||
|
||||
// Mute the sound if it's not meant to play for the passenger
|
||||
if (this.isPassenger && !this.soundSettings.playForPassengers) {
|
||||
this.volume = 0.0f
|
||||
return
|
||||
}
|
||||
|
||||
// Mute sounds when submerged unless they support underwater sounds, underwater sounds don't play above water
|
||||
if (this.ride.getIsSubmerged() && !this.soundSettings.submerged) {
|
||||
this.volume = 0.0f
|
||||
return
|
||||
} else if (!this.ride.getIsSubmerged() && this.soundSettings.submerged) {
|
||||
this.volume = 0.0f
|
||||
return
|
||||
}
|
||||
|
||||
// Perform data driven pitch and volume calculation
|
||||
this.volume = ((soundSettings.volumeExpr.let { ride.runtime.resolveDouble(it) })).toFloat()
|
||||
this.volume *= this.fade
|
||||
|
||||
-8
@@ -27,9 +27,7 @@ data class RideSoundSettings(
|
||||
val soundLocation: ResourceLocation,
|
||||
@SerializedName("volumeExpr") private val _volumeExpr: Expression? = "1.0".asExpression(),
|
||||
@SerializedName("pitchExpr") private val _pitchExpr: Expression? = "1.0".asExpression(),
|
||||
val playForPassengers: Boolean = true,
|
||||
val playForNonPassengers: Boolean = false,
|
||||
val submerged: Boolean = false,
|
||||
val muffleEnabled: Boolean = false,
|
||||
@SerializedName("attenuationModel") private val _attenuationModel: RideAttenuationModel? = RideAttenuationModel.NONE
|
||||
): Encodable {
|
||||
@@ -48,9 +46,7 @@ data class RideSoundSettings(
|
||||
buffer.writeResourceLocation(soundLocation)
|
||||
buffer.writeExpression(volumeExpr)
|
||||
buffer.writeExpression(pitchExpr)
|
||||
buffer.writeBoolean(playForPassengers)
|
||||
buffer.writeBoolean(playForNonPassengers)
|
||||
buffer.writeBoolean(submerged)
|
||||
buffer.writeBoolean(muffleEnabled)
|
||||
buffer.writeEnum(attenuationModel)
|
||||
}
|
||||
@@ -61,9 +57,7 @@ data class RideSoundSettings(
|
||||
val soundLocation = buffer.readResourceLocation()
|
||||
val volumeExpr = buffer.readExpression()
|
||||
val pitchExpr = buffer.readExpression()
|
||||
val playForPassengers = buffer.readBoolean()
|
||||
val playForNonPassengers = buffer.readBoolean()
|
||||
val submerged = buffer.readBoolean()
|
||||
val muffleEnabled = buffer.readBoolean()
|
||||
val attenuationModel = buffer.readEnum(RideAttenuationModel::class.java)
|
||||
|
||||
@@ -71,9 +65,7 @@ data class RideSoundSettings(
|
||||
soundLocation,
|
||||
volumeExpr,
|
||||
pitchExpr,
|
||||
playForPassengers,
|
||||
playForNonPassengers,
|
||||
submerged,
|
||||
muffleEnabled,
|
||||
attenuationModel
|
||||
)
|
||||
|
||||
-3
@@ -40,12 +40,9 @@ class PokemonSpawnAction(
|
||||
override fun createEntity(): PokemonEntity {
|
||||
val props = props.copy()
|
||||
props.level = levelRange.random()
|
||||
|
||||
val sourcePlayer = spawnablePosition.cause.entity as? ServerPlayer
|
||||
val entity = props.createEntity(spawnablePosition.world, sourcePlayer)
|
||||
entity.spawnCause = spawnablePosition.cause
|
||||
entity.pokemon.setFriendship(entity.pokemon.form.baseFriendship)
|
||||
|
||||
SeasonFeatureHandler.updateSeason(entity.pokemon, Cobblemon.seasonResolver(spawnablePosition.world, spawnablePosition.position))
|
||||
val heldItem = heldItem
|
||||
if (heldItem != ItemStack.EMPTY && heldItem != null) {
|
||||
|
||||
@@ -44,7 +44,11 @@ abstract class SpawnAction<R>(
|
||||
|
||||
spawnablePosition.applyInfluences { it.affectAction(this) }
|
||||
val result = run()
|
||||
future.complete(result)
|
||||
if (result != null) {
|
||||
future.complete(result)
|
||||
} else {
|
||||
future.completeExceptionally(Exception("Nothing was spawned."))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
+3
-10
@@ -61,9 +61,7 @@ open class SpawnBaitInfluence(val effects: List<SpawnBait.Effect>, val onUsed: (
|
||||
val baitEVStat = effects.firstOrNull { it.type == Effects.EV }?.subcategory?.path?.let { Stats.getStat(it) }
|
||||
|
||||
if (detailSpecies != null && baitEVStat != null) {
|
||||
val detailAspects = detail.pokemon.aspects
|
||||
val formData = detailSpecies.getForm(detailAspects)
|
||||
val evYieldValue = formData.evYield[baitEVStat]?.toFloat() ?: 0f
|
||||
val evYieldValue = detailSpecies.evYield[baitEVStat]?.toFloat() ?: 0f
|
||||
return when {
|
||||
evYieldValue > 0 -> {
|
||||
markUsed()
|
||||
@@ -85,9 +83,7 @@ open class SpawnBaitInfluence(val effects: List<SpawnBait.Effect>, val onUsed: (
|
||||
val baitTypingEffect = baitEffect?.subcategory?.path?.let { ElementalTypes.get(it) }
|
||||
|
||||
if (detailSpecies != null && baitTypingEffect != null) {
|
||||
val detailAspects = detail.pokemon.aspects
|
||||
val formData = detailSpecies.getForm(detailAspects)
|
||||
val isMatchingType = formData.types.contains(baitTypingEffect)
|
||||
val isMatchingType = detailSpecies.types.contains(baitTypingEffect)
|
||||
return when {
|
||||
isMatchingType -> {
|
||||
markUsed()
|
||||
@@ -104,9 +100,6 @@ open class SpawnBaitInfluence(val effects: List<SpawnBait.Effect>, val onUsed: (
|
||||
val detailSpecies = detail.pokemon.species?.let { PokemonSpecies.getByName(it) }
|
||||
|
||||
if (detailSpecies != null) {
|
||||
val detailAspects = detail.pokemon.aspects
|
||||
val formData = detailSpecies.getForm(detailAspects)
|
||||
|
||||
// Collect all the egg group effects
|
||||
val eggGroupEffects = effects.filter { it.type == Effects.EGG_GROUP }
|
||||
|
||||
@@ -118,7 +111,7 @@ open class SpawnBaitInfluence(val effects: List<SpawnBait.Effect>, val onUsed: (
|
||||
LOGGER.warn("Unknown egg group identifier: $effectEggGroupKey")
|
||||
return@firstOrNull false
|
||||
}
|
||||
formData.eggGroups.contains(eggGroup)
|
||||
detailSpecies.eggGroups.contains(eggGroup)
|
||||
}
|
||||
|
||||
if (matchingEffect != null) {
|
||||
|
||||
@@ -8,58 +8,30 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.stats
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.stats.StatFormatter
|
||||
|
||||
object CobblemonStats {
|
||||
val stats = mutableMapOf<String, CobblemonStat>()
|
||||
val stats = mutableMapOf<String, ResourceLocation>()
|
||||
|
||||
@JvmField
|
||||
var CAPTURED: CobblemonStat = CobblemonStat("captured")
|
||||
@JvmField
|
||||
val SHINIES_CAPTURED: CobblemonStat = CobblemonStat("shinies_captured")
|
||||
@JvmField
|
||||
val RELEASED: CobblemonStat = CobblemonStat("released")
|
||||
@JvmField
|
||||
val EVOLVED: CobblemonStat = CobblemonStat("evolved")
|
||||
@JvmField
|
||||
val LEVEL_UP: CobblemonStat = CobblemonStat("level_up")
|
||||
@JvmField
|
||||
val BATTLES_WON: CobblemonStat = CobblemonStat("battles_won")
|
||||
@JvmField
|
||||
val BATTLES_LOST: CobblemonStat = CobblemonStat("battles_lost")
|
||||
@JvmField
|
||||
val BATTLES_FLED: CobblemonStat = CobblemonStat("battles_fled")
|
||||
@JvmField
|
||||
val BATTLES_TOTAL: CobblemonStat = CobblemonStat("battles_total")
|
||||
@JvmField
|
||||
val DEX_ENTRIES: CobblemonStat = CobblemonStat("dex_entries")
|
||||
@JvmField
|
||||
val EGGS_COLLECTED: CobblemonStat = CobblemonStat("eggs_collected")
|
||||
@JvmField
|
||||
val EGGS_HATCHED: CobblemonStat = CobblemonStat("eggs_hatched")
|
||||
@JvmField
|
||||
val TRADED: CobblemonStat = CobblemonStat("traded")
|
||||
@JvmField
|
||||
val FOSSILS_REVIVED: CobblemonStat = CobblemonStat("fossils_revived")
|
||||
@JvmField
|
||||
val TIMES_RIDDEN: CobblemonStat = CobblemonStat("times_ridden")
|
||||
@JvmField
|
||||
val ROD_CASTS: CobblemonStat = CobblemonStat("rod_casts")
|
||||
@JvmField
|
||||
val REEL_INS: CobblemonStat = CobblemonStat("reel_ins")
|
||||
@JvmField
|
||||
val POKEMON_INTERACTED_WITH: CobblemonStat = CobblemonStat("pokemon_interacted_with")
|
||||
@JvmField
|
||||
val RIDING_LAND: CobblemonStat = CobblemonStat("riding_land", StatFormatter.DISTANCE)
|
||||
@JvmField
|
||||
val RIDING_AIR: CobblemonStat = CobblemonStat("riding_air", StatFormatter.DISTANCE)
|
||||
@JvmField
|
||||
val RIDING_LIQUID: CobblemonStat = CobblemonStat("riding_liquid", StatFormatter.DISTANCE)
|
||||
|
||||
//TODO block, stats (interact, gimmi)
|
||||
var CAPTURED: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "captured") //makeCustomStat("captured", StatFormatter.DEFAULT)
|
||||
val SHINIES_CAPTURED: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "shinies_captured") //makeCustomStat("shinies_captured", StatFormatter.DEFAULT)
|
||||
val RELEASED: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "released") //makeCustomStat("released", StatFormatter.DEFAULT)
|
||||
val EVOLVED: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "evolved") //makeCustomStat("evolved", StatFormatter.DEFAULT)
|
||||
val LEVEL_UP: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "level_up") //makeCustomStat("level_up", StatFormatter.DEFAULT)
|
||||
val BATTLES_WON: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "battles_won") //makeCustomStat("battles_won", StatFormatter.DEFAULT)
|
||||
val BATTLES_LOST: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "battles_lost") //makeCustomStat("battles_lost", StatFormatter.DEFAULT)
|
||||
val BATTLES_FLED: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "battles_fled") //makeCustomStat("battles_fled", StatFormatter.DEFAULT)
|
||||
val BATTLES_TOTAL: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "battles_total") //makeCustomStat("battles_total", StatFormatter.DEFAULT)
|
||||
val DEX_ENTRIES: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "dex_entries") //makeCustomStat("dex_entries", StatFormatter.DEFAULT)
|
||||
val EGGS_COLLECTED: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "eggs_collected") //makeCustomStat("eggs_collected", StatFormatter.DEFAULT)
|
||||
val EGGS_HATCHED: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "eggs_hatched") //makeCustomStat("eggs_hatched", StatFormatter.DEFAULT)
|
||||
val TRADED: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "traded") //makeCustomStat("traded", StatFormatter.DEFAULT)
|
||||
val FOSSILS_REVIVED: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "fossils_revived") //makeCustomStat("fossils_revived", StatFormatter.DEFAULT)
|
||||
val TIMES_RIDDEN: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "times_ridden")
|
||||
val ROD_CASTS: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "rod_casts")
|
||||
val REEL_INS: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "reel_ins")
|
||||
val POKEMON_INTERACTED_WITH: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", "pokemon_interacted_with") //makeCustomStat("pokemon_interacted_with", StatFormatter.DEFAULT)
|
||||
//TODO block, stats (interact, gimmi), riding (styles?)
|
||||
|
||||
fun registerStats() {
|
||||
stats["captured"] = CAPTURED
|
||||
@@ -80,22 +52,5 @@ object CobblemonStats {
|
||||
stats["rod_casts"] = ROD_CASTS
|
||||
stats["reel_ins"] = REEL_INS
|
||||
stats["pokemon_interacted_with"] = POKEMON_INTERACTED_WITH
|
||||
stats["riding_land"] = RIDING_LAND
|
||||
stats["riding_air"] = RIDING_AIR
|
||||
stats["riding_liquid"] = RIDING_LIQUID
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getStat(cobblemonStat: CobblemonStat) : ResourceLocation {
|
||||
val resourceLocation = cobblemonStat.resourceLocation
|
||||
val stat = BuiltInRegistries.CUSTOM_STAT.get(resourceLocation)
|
||||
if (stat == null) {
|
||||
Cobblemon.LOGGER.error("Could not find stat with id {}", resourceLocation)
|
||||
}
|
||||
return stat ?: throw NullPointerException("Could not find stat with id $resourceLocation")
|
||||
}
|
||||
|
||||
data class CobblemonStat(val path: String, val formatter: StatFormatter = StatFormatter.DEFAULT) {
|
||||
val resourceLocation: ResourceLocation = ResourceLocation.fromNamespaceAndPath("cobblemon", path);
|
||||
}
|
||||
}
|
||||
+1
@@ -88,6 +88,7 @@ abstract class OneToOneFileStoreAdapter<S>(
|
||||
result
|
||||
}
|
||||
else {
|
||||
storeClass.getConstructor(UUID::class.java).newInstance(uuid)
|
||||
var result = storeClass.getConstructor(UUID::class.java).newInstance(uuid)
|
||||
save(storeClass, uuid, serialize(result, registryAccess))
|
||||
oldFile.delete()
|
||||
|
||||
@@ -19,6 +19,7 @@ import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.tags.FluidTags
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.*
|
||||
import net.minecraft.world.level.block.Block
|
||||
@@ -174,7 +175,7 @@ class HeartyGrainsBlock(settings: Properties) : CropBlock(settings), SimpleWater
|
||||
UPDATE_CLIENTS
|
||||
)
|
||||
}
|
||||
else if (stateAbove.hasProperty(HALF) && stateAbove.getValue(HALF) == DoubleBlockHalf.UPPER) {
|
||||
else if (stateAbove.getValue(HALF) == DoubleBlockHalf.UPPER) {
|
||||
world.setBlock(
|
||||
abovePos,
|
||||
stateAbove.setValue(AGE, newAge),
|
||||
|
||||
@@ -34,7 +34,6 @@ import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.Explosion
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.LevelAccessor
|
||||
import net.minecraft.world.level.LevelReader
|
||||
@@ -56,10 +55,9 @@ import net.minecraft.world.phys.shapes.VoxelShape
|
||||
import java.util.*
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED
|
||||
import net.minecraft.world.level.gameevent.GameEvent
|
||||
import java.util.function.BiConsumer
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION", "DEPRECATION")
|
||||
class PastureBlock(settings: Properties): BaseEntityBlock(settings), SimpleWaterloggedBlock {
|
||||
class PastureBlock(settings: Properties): BaseEntityBlock(settings), SimpleWaterloggedBlock, PreEmptsExplosion {
|
||||
companion object {
|
||||
val CODEC = simpleCodec(::PastureBlock)
|
||||
|
||||
@@ -215,19 +213,9 @@ class PastureBlock(settings: Properties): BaseEntityBlock(settings), SimpleWater
|
||||
return super.playerWillDestroy(world, pos, state, player)
|
||||
}
|
||||
|
||||
override fun onExplosionHit(
|
||||
state: BlockState,
|
||||
level: Level,
|
||||
pos: BlockPos,
|
||||
explosion: Explosion,
|
||||
dropConsumer: BiConsumer<ItemStack?, BlockPos?>
|
||||
) {
|
||||
val interaction = explosion.blockInteraction
|
||||
if (interaction == Explosion.BlockInteraction.DESTROY || interaction == Explosion.BlockInteraction.DESTROY_WITH_DECAY) {
|
||||
val blockEntity = level.getBlockEntity(pos) as? PokemonPastureBlockEntity ?: return
|
||||
blockEntity.onBroken()
|
||||
}
|
||||
super.onExplosionHit(state, level, pos, explosion, dropConsumer)
|
||||
override fun whenExploded(world: Level, state: BlockState, pos: BlockPos) {
|
||||
val blockEntity = world.getBlockEntity(pos) as? PokemonPastureBlockEntity ?: return
|
||||
blockEntity.onBroken()
|
||||
}
|
||||
|
||||
override fun <T : BlockEntity?> getTicker(world: Level, state: BlockState, type: BlockEntityType<T>): BlockEntityTicker<T>? {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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.block
|
||||
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.level.Level
|
||||
|
||||
interface PreEmptsExplosion {
|
||||
fun whenExploded(world: Level, state: BlockState, pos: BlockPos)
|
||||
}
|
||||
@@ -10,7 +10,6 @@ package com.cobblemon.mod.common.block
|
||||
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
||||
import com.cobblemon.mod.common.util.isServerSide
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.core.dispenser.DispenseItemBehavior
|
||||
@@ -264,39 +263,23 @@ class SaccharineLeafBlock(settings: Properties) : LeavesBlock(settings) {
|
||||
val isGlassBottle = itemStack.`is`(Items.GLASS_BOTTLE)
|
||||
val isHoneyBottle = itemStack.`is`(Items.HONEY_BOTTLE)
|
||||
|
||||
if (isGlassBottle && isAtMaxAge(state)) {
|
||||
if (level.isClientSide) return ItemInteractionResult.SUCCESS
|
||||
if (isGlassBottle && !isAtMinAge(state)) {
|
||||
// Decrement stack if not in creative mode
|
||||
itemStack.consume(1, player)
|
||||
|
||||
// Give player a honey bottle
|
||||
if (stack.isEmpty) {
|
||||
// Replace the consumed empty bottle with a honey bottle
|
||||
player.setItemInHand(hand, ItemStack(Items.HONEY_BOTTLE));
|
||||
} else {
|
||||
player.addItem(Items.HONEY_BOTTLE.defaultInstance)
|
||||
}
|
||||
// Give player honey bottle for now
|
||||
player.addItem(Items.HONEY_BOTTLE.defaultInstance)
|
||||
|
||||
level.playSound(null, pos, SoundEvents.BOTTLE_FILL, SoundSource.BLOCKS)
|
||||
level.setBlock(pos, state.setValue(AGE, 0), UPDATE_CLIENTS)
|
||||
level.setBlock(pos, state.setValue(AGE, 0), 2)
|
||||
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
|
||||
return ItemInteractionResult.SUCCESS
|
||||
} else if (isHoneyBottle && !isAtMaxAge(state)) {
|
||||
if (level.isClientSide) return ItemInteractionResult.SUCCESS
|
||||
|
||||
// Decrement stack if not in creative mode
|
||||
if (!player.isCreative) {
|
||||
itemStack.consume(1, player)
|
||||
if (stack.isEmpty) {
|
||||
// Replace the consumed honey bottle with an empty bottle
|
||||
player.setItemInHand(hand, ItemStack(Items.GLASS_BOTTLE));
|
||||
} else {
|
||||
player.addItem(Items.GLASS_BOTTLE.defaultInstance)
|
||||
}
|
||||
}
|
||||
itemStack.consume(1, player)
|
||||
|
||||
level.playSound(null, pos, SoundEvents.HONEY_BLOCK_PLACE, SoundSource.BLOCKS)
|
||||
level.setBlock(pos, state.setValue(AGE, 2), UPDATE_CLIENTS)
|
||||
level.setBlock(pos, state.setValue(AGE, 2), 2)
|
||||
level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos)
|
||||
return ItemInteractionResult.SUCCESS
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
package com.cobblemon.mod.common.block.campfirepot
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonMenuType
|
||||
import com.cobblemon.mod.common.CobblemonRecipeBookTypes.COOKING_POT
|
||||
import com.cobblemon.mod.common.CobblemonRecipeTypes
|
||||
import com.cobblemon.mod.common.api.cooking.Seasonings
|
||||
import com.cobblemon.mod.common.block.entity.CampfireBlockEntity
|
||||
@@ -212,7 +211,7 @@ class CookingPotMenu : RecipeBookMenu<CraftingInput, CookingPotRecipeBase>, Cont
|
||||
}
|
||||
|
||||
override fun getRecipeBookType(): RecipeBookType {
|
||||
return COOKING_POT
|
||||
return RecipeBookType.valueOf("COOKING_POT")
|
||||
}
|
||||
|
||||
override fun shouldMoveToInventory(slotIndex: Int): Boolean {
|
||||
|
||||
+6
-14
@@ -111,18 +111,13 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
|
||||
BlockEntitySoundTracker.stop(pos, campfireBlockEntity.ambientSound.location)
|
||||
}
|
||||
|
||||
val seasonings = campfireBlockEntity.getSeasonings()
|
||||
if (seasonings.size != campfireBlockEntity.lastSeasoningStacks.size || seasonings.any { it !in campfireBlockEntity.lastSeasoningStacks }) {
|
||||
campfireBlockEntity.lastSeasoningStacks = seasonings
|
||||
campfireBlockEntity.brothColor =
|
||||
getColourMixFromSeasonings(campfireBlockEntity.getSeasonings())
|
||||
?: BASE_BROTH_COLOR
|
||||
|
||||
campfireBlockEntity.brothColor =
|
||||
getColourMixFromSeasonings(seasonings)
|
||||
?: BASE_BROTH_COLOR
|
||||
|
||||
campfireBlockEntity.bubbleColor =
|
||||
getColourMixFromSeasonings(seasonings, true)
|
||||
?: BASE_BROTH_BUBBLE_COLOR
|
||||
}
|
||||
campfireBlockEntity.bubbleColor =
|
||||
getColourMixFromSeasonings(campfireBlockEntity.getSeasonings(), true)
|
||||
?: BASE_BROTH_BUBBLE_COLOR
|
||||
|
||||
if (campfireBlockEntity.particleCooldown > 0) {
|
||||
campfireBlockEntity.particleCooldown--
|
||||
@@ -246,9 +241,6 @@ class CampfireBlockEntity(pos: BlockPos, state: BlockState) : BaseContainerBlock
|
||||
var bubbleColor: Int = BASE_BROTH_BUBBLE_COLOR
|
||||
var time: Int = 0
|
||||
|
||||
/** Used to know if we should be changing the colour of the broth or if we can go with the previous colour. */
|
||||
var lastSeasoningStacks = listOf<ItemStack>()
|
||||
|
||||
var dataAccess: ContainerData = object : ContainerData {
|
||||
override fun get(index: Int): Int {
|
||||
return when (index) {
|
||||
|
||||
+2
-1
@@ -49,6 +49,7 @@ import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import java.util.*
|
||||
|
||||
open class PokeSnackBlockEntity(pos: BlockPos, state: BlockState) :
|
||||
TintBlockEntity(CobblemonBlockEntities.POKE_SNACK, pos, state),
|
||||
@@ -119,7 +120,7 @@ open class PokeSnackBlockEntity(pos: BlockPos, state: BlockState) :
|
||||
level.dimension(),
|
||||
)
|
||||
|
||||
block.eat(level, blockPos, blockState, null)
|
||||
block.eat(level, blockPos, blockState, action.spawnablePosition.cause.entity as? Player)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ object CobblemonClient {
|
||||
) { it is PokemonEntity }
|
||||
|
||||
nearbyPokemon?.forEach { entity ->
|
||||
if (entity is PokemonEntity && !entity.isSilent && !entity.passengers.contains(player)) {
|
||||
if (entity is PokemonEntity && !entity.isSilent) {
|
||||
if (player.isLookingAt(entity) && !player.isSpectator && entity.pokemon.shiny) entity.delegate.spawnShinyParticle(player)
|
||||
entity.delegate.spawnAspectParticle()
|
||||
}
|
||||
|
||||
+118
-127
@@ -38,7 +38,7 @@ import kotlin.math.max
|
||||
class RideControlsOverlay : Gui(Minecraft.getInstance()) {
|
||||
|
||||
companion object {
|
||||
private const val CONTROLS_FADE_FRAMES = 20F
|
||||
private const val FADE_FRAMES = 20F
|
||||
private const val BASELINE_FPS = 60F
|
||||
|
||||
private const val HALF_SCALE = 0.5F
|
||||
@@ -63,9 +63,9 @@ class RideControlsOverlay : Gui(Minecraft.getInstance()) {
|
||||
|
||||
private val screenExemptions: List<Class<out Screen>> = listOf(ChatScreen::class.java)
|
||||
|
||||
private var controlsMaxDurationFrames = Cobblemon.config.displayControlSeconds * BASELINE_FPS
|
||||
private var controlsDurationFrames = controlsMaxDurationFrames
|
||||
private var controlsFadeFrames = CONTROLS_FADE_FRAMES
|
||||
private var maxDurationFrames = Cobblemon.config.displayControlSeconds * BASELINE_FPS
|
||||
private var durationFrames = maxDurationFrames
|
||||
private var fadeFrames = FADE_FRAMES
|
||||
|
||||
private var lastMouseX = 0
|
||||
private var lastMouseY = 0
|
||||
@@ -88,132 +88,123 @@ class RideControlsOverlay : Gui(Minecraft.getInstance()) {
|
||||
|
||||
if (minecraft.options.hideGui || minecraft.debugOverlay.showDebugScreen()) return
|
||||
|
||||
minecraft.player?.let { player ->
|
||||
val riddenEntity = player.vehicle
|
||||
if (riddenEntity != null && riddenEntity is PokemonEntity) {
|
||||
// Only show controls to driver
|
||||
if (riddenEntity === player.controlledVehicle) {
|
||||
renderControls(minecraft, context, tickCounter, riddenEntity)
|
||||
}
|
||||
} else {
|
||||
resetControlsOverlayState()
|
||||
val riddenEntity = minecraft.player?.vehicle
|
||||
if (riddenEntity != null && riddenEntity is PokemonEntity) {
|
||||
// Update max duration if user has changed config
|
||||
val configDuration = Cobblemon.config.displayControlSeconds * BASELINE_FPS
|
||||
if (maxDurationFrames != configDuration) {
|
||||
maxDurationFrames = configDuration
|
||||
resetOverlayState()
|
||||
}
|
||||
|
||||
// Don't render if duration config set to 0 or less
|
||||
if (maxDurationFrames <= 0F) return
|
||||
|
||||
val rideBehaviourSettings = riddenEntity.ridingController?.context?.settings ?: return
|
||||
val ridingBehaviourState = riddenEntity.ridingController?.context?.state ?: return
|
||||
val rideBehaviourKey = rideBehaviourSettings.key
|
||||
|
||||
// Update current ride behaviour if changed
|
||||
// If composite, get active behaviour instead
|
||||
if (rideBehaviourKey == CompositeBehaviour.KEY) {
|
||||
val activeBehaviour = (ridingBehaviourState as CompositeState).activeBehaviour.get()
|
||||
if (currentBehaviourKey != activeBehaviour) {
|
||||
currentBehaviourKey = activeBehaviour
|
||||
resetOverlayState()
|
||||
}
|
||||
} else if (currentBehaviourKey != rideBehaviourKey) {
|
||||
currentBehaviourKey = rideBehaviourKey
|
||||
resetOverlayState()
|
||||
}
|
||||
|
||||
// Render elements if entity has ride behaviour and if display duration has not ended yet
|
||||
if (rideBehaviourSettings != null && fadeFrames > 0) {
|
||||
val tickDelta = tickCounter.realtimeDeltaTicks.takeIf { !minecraft.isPaused } ?: 0F
|
||||
val updateInterval = (tickDelta / 20F) * BASELINE_FPS
|
||||
|
||||
durationFrames = max(durationFrames - updateInterval, 0F)
|
||||
if (durationFrames == 0F && fadeFrames > 0) fadeFrames = max(fadeFrames - updateInterval, 0F)
|
||||
|
||||
var showVerticalMouse = true // Show moving mouse up and down with arrows
|
||||
var showHorizontalMouse = true // Show moving mouse left and right with arrows
|
||||
var showSneakKey = true
|
||||
var showJumpKey = true
|
||||
var showMovementKeys = true
|
||||
var disableHorizontalMovementKeys = false // Disable left and right movement keys
|
||||
|
||||
// Configure what controls to show for each behaviour
|
||||
when (currentBehaviourKey) {
|
||||
BirdBehaviour.KEY -> {}
|
||||
BoatBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
showSneakKey = false
|
||||
}
|
||||
BurstBehaviour.KEY -> {}
|
||||
DolphinBehaviour.KEY -> {
|
||||
disableHorizontalMovementKeys = true
|
||||
showSneakKey = false
|
||||
showJumpKey = false
|
||||
}
|
||||
GliderBehaviour.KEY -> {}
|
||||
HelicopterBehaviour.KEY -> {}
|
||||
HorseBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
disableHorizontalMovementKeys = true
|
||||
showSneakKey = false
|
||||
}
|
||||
HoverBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
}
|
||||
JetBehaviour.KEY -> {
|
||||
showSneakKey = false
|
||||
showJumpKey = false
|
||||
}
|
||||
MinekartBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
showSneakKey = false
|
||||
}
|
||||
RocketBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
}
|
||||
VehicleBehaviour.KEY -> {}
|
||||
}
|
||||
|
||||
val centerX = minecraft.window.guiScaledWidth / 2
|
||||
val centerY = minecraft.window.guiScaledHeight / 2
|
||||
|
||||
renderMouseControls(
|
||||
context,
|
||||
!showMovementKeys && !showJumpKey && !showSneakKey,
|
||||
showHorizontalMouse,
|
||||
showVerticalMouse,
|
||||
centerX,
|
||||
centerY / 2,
|
||||
fadeFrames / FADE_FRAMES
|
||||
)
|
||||
renderKeyControls(
|
||||
context,
|
||||
!showHorizontalMouse && !showVerticalMouse,
|
||||
showMovementKeys,
|
||||
disableHorizontalMovementKeys,
|
||||
showJumpKey,
|
||||
showSneakKey,
|
||||
minecraft.player?.input,
|
||||
centerX,
|
||||
centerY / 2,
|
||||
fadeFrames / FADE_FRAMES
|
||||
)
|
||||
}
|
||||
} else {
|
||||
resetOverlayState()
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderControls(minecraft: Minecraft, context: GuiGraphics, tickCounter: DeltaTracker, riddenEntity: PokemonEntity) {
|
||||
// Update max duration if user has changed config
|
||||
val configDuration = Cobblemon.config.displayControlSeconds * BASELINE_FPS
|
||||
if (controlsMaxDurationFrames != configDuration) {
|
||||
controlsMaxDurationFrames = configDuration
|
||||
resetControlsOverlayState()
|
||||
}
|
||||
|
||||
// Don't render if duration config set to 0 or less
|
||||
if (controlsMaxDurationFrames <= 0F) return
|
||||
|
||||
val rideBehaviourSettings = riddenEntity.ridingController?.context?.settings ?: return
|
||||
val ridingBehaviourState = riddenEntity.ridingController?.context?.state ?: return
|
||||
val rideBehaviourKey = rideBehaviourSettings.key
|
||||
|
||||
// Update current ride behaviour if changed
|
||||
// If composite, get active behaviour instead
|
||||
if (rideBehaviourKey == CompositeBehaviour.KEY) {
|
||||
val activeBehaviour = (ridingBehaviourState as CompositeState).activeBehaviour.get()
|
||||
if (currentBehaviourKey != activeBehaviour) {
|
||||
currentBehaviourKey = activeBehaviour
|
||||
resetControlsOverlayState()
|
||||
}
|
||||
} else if (currentBehaviourKey != rideBehaviourKey) {
|
||||
currentBehaviourKey = rideBehaviourKey
|
||||
resetControlsOverlayState()
|
||||
}
|
||||
|
||||
// Render elements if entity has ride behaviour and if display duration has not ended yet
|
||||
if (rideBehaviourSettings != null && controlsFadeFrames > 0) {
|
||||
val tickDelta = tickCounter.realtimeDeltaTicks.takeIf { !minecraft.isPaused } ?: 0F
|
||||
val updateInterval = (tickDelta / 20F) * BASELINE_FPS
|
||||
|
||||
controlsDurationFrames = max(controlsDurationFrames - updateInterval, 0F)
|
||||
if (controlsDurationFrames == 0F && controlsFadeFrames > 0) controlsFadeFrames = max(controlsFadeFrames - updateInterval, 0F)
|
||||
|
||||
var showVerticalMouse = true // Show moving mouse up and down with arrows
|
||||
var showHorizontalMouse = true // Show moving mouse left and right with arrows
|
||||
var showSneakKey = true
|
||||
var showJumpKey = true
|
||||
var showMovementKeys = true
|
||||
var disableHorizontalMovementKeys = false // Disable left and right movement keys
|
||||
|
||||
// Configure what controls to show for each behaviour
|
||||
when (currentBehaviourKey) {
|
||||
BirdBehaviour.KEY -> {}
|
||||
BoatBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
showSneakKey = false
|
||||
}
|
||||
BurstBehaviour.KEY -> {}
|
||||
DolphinBehaviour.KEY -> {
|
||||
disableHorizontalMovementKeys = true
|
||||
showSneakKey = false
|
||||
showJumpKey = false
|
||||
}
|
||||
GliderBehaviour.KEY -> {}
|
||||
HelicopterBehaviour.KEY -> {}
|
||||
HorseBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
disableHorizontalMovementKeys = true
|
||||
showSneakKey = false
|
||||
}
|
||||
HoverBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
}
|
||||
JetBehaviour.KEY -> {
|
||||
showSneakKey = false
|
||||
showJumpKey = false
|
||||
}
|
||||
MinekartBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
showSneakKey = false
|
||||
}
|
||||
RocketBehaviour.KEY -> {
|
||||
showVerticalMouse = false
|
||||
showHorizontalMouse = false
|
||||
}
|
||||
VehicleBehaviour.KEY -> {}
|
||||
}
|
||||
|
||||
val centerX = minecraft.window.guiScaledWidth / 2
|
||||
val centerY = minecraft.window.guiScaledHeight / 2
|
||||
|
||||
renderMouseControls(
|
||||
context,
|
||||
!showMovementKeys && !showJumpKey && !showSneakKey,
|
||||
showHorizontalMouse,
|
||||
showVerticalMouse,
|
||||
centerX,
|
||||
centerY / 2,
|
||||
controlsFadeFrames / CONTROLS_FADE_FRAMES
|
||||
)
|
||||
renderKeyControls(
|
||||
context,
|
||||
!showHorizontalMouse && !showVerticalMouse,
|
||||
showMovementKeys,
|
||||
disableHorizontalMovementKeys,
|
||||
showJumpKey,
|
||||
showSneakKey,
|
||||
minecraft.player?.input,
|
||||
centerX,
|
||||
centerY / 2,
|
||||
controlsFadeFrames / CONTROLS_FADE_FRAMES
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetControlsOverlayState() {
|
||||
if (controlsDurationFrames != controlsMaxDurationFrames) controlsDurationFrames = controlsMaxDurationFrames
|
||||
if (controlsFadeFrames != CONTROLS_FADE_FRAMES) controlsFadeFrames = CONTROLS_FADE_FRAMES
|
||||
private fun resetOverlayState() {
|
||||
if (durationFrames != maxDurationFrames) durationFrames = maxDurationFrames
|
||||
if (fadeFrames != FADE_FRAMES) fadeFrames = FADE_FRAMES
|
||||
if (mouseMovedUp != null) {
|
||||
mouseMovedUp = null
|
||||
lastMouseY = 0
|
||||
@@ -422,7 +413,7 @@ class RideControlsOverlay : Gui(Minecraft.getInstance()) {
|
||||
|
||||
if (showJump || showSneak) {
|
||||
val offsetY = if (showMovement) 0 else -14
|
||||
var label: MutableComponent?
|
||||
var label: MutableComponent? = null
|
||||
|
||||
if (showJump && showSneak) {
|
||||
label = "key.sneak".asTranslated().append("/").append("key.jump".asTranslated())
|
||||
|
||||
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.client.gui.pc
|
||||
import com.cobblemon.mod.common.CobblemonNetwork
|
||||
import com.cobblemon.mod.common.CobblemonSounds
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.api.gui.getPixelRGB
|
||||
import com.cobblemon.mod.common.api.storage.StorePosition
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyPosition
|
||||
import com.cobblemon.mod.common.api.storage.pc.PCPosition
|
||||
@@ -283,6 +284,20 @@ class StorageWidget(
|
||||
height = 189,
|
||||
alpha = if (screenLoaded) 1F else ((pcGui.ticksElapsed).toFloat() / 10F).coerceIn(0F, 1F)
|
||||
)
|
||||
} else {
|
||||
val rgb = getPixelRGB(x + (SCREEN_WIDTH / 2), y + (SCREEN_HEIGHT / 2))
|
||||
blitk(
|
||||
matrixStack = matrices,
|
||||
texture = screenGlowResource,
|
||||
x = x - 17,
|
||||
y = y - 17,
|
||||
width = 208,
|
||||
height = 189,
|
||||
red = rgb.first / 255F,
|
||||
green = rgb.second / 255F,
|
||||
blue = rgb.third / 255F,
|
||||
alpha = if (screenLoaded) 1F else ((pcGui.ticksElapsed).toFloat() / 10F).coerceIn(0F, 1F)
|
||||
)
|
||||
}
|
||||
|
||||
blitk(
|
||||
|
||||
-6
@@ -592,10 +592,6 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
|
||||
}
|
||||
|
||||
private fun switchForm(nextIndex: Boolean) {
|
||||
if (visibleForms.isEmpty() || currentEntry == null) {
|
||||
return
|
||||
}
|
||||
|
||||
selectedPoseIndex = 0
|
||||
|
||||
if (nextIndex) {
|
||||
@@ -606,8 +602,6 @@ class PokemonInfoWidget(val pX: Int, val pY: Int, val updateForm: (PokedexForm)
|
||||
else selectedFormIndex = visibleForms.lastIndex
|
||||
}
|
||||
|
||||
selectedFormIndex = selectedFormIndex.coerceIn(0, visibleForms.lastIndex)
|
||||
|
||||
setupButtons(currentEntry!!, visibleForms[selectedFormIndex])
|
||||
updateAspects()
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ object CobblemonKeyBinds {
|
||||
val PARTY_OVERLAY_DOWN = this.queue(DownShiftPartyBinding)
|
||||
val PARTY_OVERLAY_UP = this.queue(UpShiftPartyBinding)
|
||||
val SEND_OUT_POKEMON = this.queue(PartySendBinding)
|
||||
val RIDING_FREELOOK = this.queue(RidingFreelookBinding)
|
||||
|
||||
fun register(registrar: (KeyMapping) -> Unit) {
|
||||
this.keyBinds.forEach(registrar::invoke)
|
||||
|
||||
-29
@@ -1,29 +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.keybind.keybinds
|
||||
|
||||
import com.cobblemon.mod.common.client.keybind.CobblemonBlockingKeyBinding
|
||||
import com.cobblemon.mod.common.client.keybind.KeybindCategories
|
||||
|
||||
import com.mojang.blaze3d.platform.InputConstants
|
||||
|
||||
|
||||
object RidingFreelookBinding : CobblemonBlockingKeyBinding(
|
||||
"key.cobblemon.ridingfreelook",
|
||||
InputConstants.Type.KEYSYM,
|
||||
InputConstants.KEY_LALT,
|
||||
KeybindCategories.COBBLEMON_CATEGORY
|
||||
) {
|
||||
override fun onTick() {
|
||||
}
|
||||
override fun onRelease() {
|
||||
}
|
||||
override fun onPress() {
|
||||
}
|
||||
}
|
||||
-27
@@ -1,27 +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.net.data
|
||||
|
||||
import com.cobblemon.mod.common.api.interaction.PokemonInteractions
|
||||
import com.cobblemon.mod.common.api.net.ClientNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.net.messages.client.data.PokemonInteractionsSyncPacket
|
||||
import net.minecraft.client.Minecraft
|
||||
|
||||
object PokemonInteractionsSyncHandler : ClientNetworkPacketHandler<PokemonInteractionsSyncPacket> {
|
||||
|
||||
override fun handle(
|
||||
packet: PokemonInteractionsSyncPacket,
|
||||
client: Minecraft,
|
||||
) {
|
||||
PokemonInteractions.speciesInteractions.clear()
|
||||
PokemonInteractions.speciesInteractions.addAll(packet.speciesInteractions)
|
||||
PokemonInteractions.generalInteractions.clear()
|
||||
PokemonInteractions.generalInteractions.addAll(packet.generalInteractions)
|
||||
}
|
||||
}
|
||||
+5
-21
@@ -8,8 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common.client.persisted
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.Cobblemon.LOGGER
|
||||
import com.cobblemon.mod.common.config.CobblemonConfig
|
||||
import java.io.BufferedReader
|
||||
import java.io.BufferedWriter
|
||||
@@ -33,14 +31,7 @@ object ClientPersistedData {
|
||||
fun readSnapshotsData() : SnapshotAcknowledgementData? {
|
||||
if (snapshotsPath.exists()) {
|
||||
BufferedReader(InputStreamReader(FileInputStream(snapshotsPath.toFile()))).use { reader ->
|
||||
try {
|
||||
return gson.fromJson(reader, SnapshotAcknowledgementData::class.java)
|
||||
} catch (exception: Exception) {
|
||||
LOGGER.error("Failed to load snapshots.json... Resetting File")
|
||||
val data = SnapshotAcknowledgementData(Cobblemon.VERSION, false)
|
||||
writeSnapshotsData(data)
|
||||
return data
|
||||
}
|
||||
return gson.fromJson(reader, SnapshotAcknowledgementData::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,23 +46,16 @@ object ClientPersistedData {
|
||||
fun readRidingPerspectivesData() : RidingPerspectiveData? {
|
||||
if (ridingPerspectivesPath.exists()) {
|
||||
BufferedReader(InputStreamReader(FileInputStream(ridingPerspectivesPath.toFile()))).use { reader ->
|
||||
try {
|
||||
return gson.fromJson(reader, RidingPerspectiveData::class.java)
|
||||
} catch (exception: Exception) {
|
||||
LOGGER.error("Failed to load riding_perspectives.json... Resetting File")
|
||||
val data = RidingPerspectiveData()
|
||||
saveRidingPerspectivesData(data)
|
||||
return data
|
||||
}
|
||||
return gson.fromJson(reader, RidingPerspectiveData::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun saveRidingPerspectivesData(data: RidingPerspectiveData) {
|
||||
fun saveRidingPerspectivesData() {
|
||||
ridingPerspectivesPath.toFile().parentFile.mkdirs()
|
||||
BufferedWriter(FileWriter(ridingPerspectivesPath.toFile())).use { writer -> gson.toJson(data, writer) }
|
||||
BufferedWriter(FileWriter(ridingPerspectivesPath.toFile())).use { writer -> gson.toJson(ridingPerspectives, writer) }
|
||||
}
|
||||
|
||||
data class SnapshotAcknowledgementData(val version: String, val dontShowAgain: Boolean)
|
||||
@@ -80,7 +64,7 @@ object ClientPersistedData {
|
||||
) {
|
||||
fun updatePerspective(key: ResourceLocation, cameraType: CameraType) {
|
||||
perspectives[key] = cameraType
|
||||
saveRidingPerspectivesData(this)
|
||||
saveRidingPerspectivesData()
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-9
@@ -23,6 +23,7 @@ import com.cobblemon.mod.common.duck.CameraDuck
|
||||
import com.cobblemon.mod.common.duck.RidePassenger
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import com.cobblemon.mod.common.util.toVec3d
|
||||
import com.mojang.blaze3d.Blaze3D
|
||||
import net.minecraft.client.Camera
|
||||
import net.minecraft.client.CameraType
|
||||
@@ -34,7 +35,6 @@ import net.minecraft.world.phys.HitResult
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import org.joml.Matrix3f
|
||||
import org.joml.Quaternionf
|
||||
import org.joml.Vector3d
|
||||
import org.joml.Vector3f
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sign
|
||||
@@ -81,6 +81,7 @@ object MountedCameraRenderer {
|
||||
val currEyeHeight: Double = Mth.lerp(instance.partialTickTime.toDouble(), eyeHeight, eyeHeightOld)
|
||||
var offset = Vec3(0.0, currEyeHeight - (driver.bbHeight / 2), 0.0)
|
||||
var eyeOffset = Vec3(0.0, currEyeHeight - (driver.bbHeight / 2), 0.0)
|
||||
val locatorOffset = Vec3(locator.matrix.getTranslation(Vector3f()))
|
||||
|
||||
val shouldFlip = !(vehicleController.active && vehicleController.orientation != null) // Do not flip the offset for 3rd person reverse unless we are using normal mc camera rotation.
|
||||
val isFirstPerson = Minecraft.getInstance().options.cameraType == CameraType.FIRST_PERSON
|
||||
@@ -102,17 +103,15 @@ object MountedCameraRenderer {
|
||||
else Quaternionf()
|
||||
.rotateY((Math.PI.toFloat() - Mth.lerp(instance.partialTickTime, vehicle.yRotO, vehicle.yRot).toRadians()))
|
||||
|
||||
offset = rotation.transform(Vector3d(offset.x, offset.y, offset.z)).let { Vec3(it.x, it.y, it.z) }
|
||||
eyeOffset = rotation.transform(Vector3d(eyeOffset.x, eyeOffset.y, eyeOffset.z)).let { Vec3(it.x, it.y, it.z) }
|
||||
offset = rotation.transform(offset.toVector3f()).toVec3d()
|
||||
eyeOffset = rotation.transform(eyeOffset.toVector3f()).toVec3d()
|
||||
|
||||
val eyeLocatorOffset = Vec3(locator.matrix.getTranslation(Vector3f()))
|
||||
val eyePos = eyeLocatorOffset.add(entityPos)
|
||||
val eyePos = locatorOffset.add(entityPos)
|
||||
|
||||
// Get the camera position before offsets are applied (which are done with maxZoom to account for clipping). If 3rd person viewbobbing is enabled or the player is
|
||||
// in first person then base the camera position off the seat locator offset
|
||||
val pos = /* if (isFirstPerson || Cobblemon.config.thirdPersonViewBobbing) { */
|
||||
Vec3(locator.matrix.getTranslation(Vector3f()))
|
||||
.add(entityPos)
|
||||
locatorOffset.add(entityPos)
|
||||
/* } else {
|
||||
val pokemonCenter = Vector3f(0f, driver.bbHeight/2, 0f)
|
||||
|
||||
@@ -327,7 +326,7 @@ object MountedCameraRenderer {
|
||||
locatorName: String,
|
||||
shouldFlip: Boolean = true
|
||||
): Vec3 {
|
||||
val offset = if (thirdPersonReverse && cameraOffsets.containsKey(locatorName + "_reverse")) {
|
||||
var offset = if (thirdPersonReverse && cameraOffsets.containsKey(locatorName + "_reverse")) {
|
||||
cameraOffsets[locatorName + "_reverse"]!!
|
||||
} else if (cameraOffsets.containsKey(locatorName)) {
|
||||
cameraOffsets[locatorName]!!
|
||||
@@ -337,7 +336,8 @@ object MountedCameraRenderer {
|
||||
|
||||
// Don't need to account for this since orientation is derived from camera rotation and that z is already flipped.
|
||||
// Flip only when not on a rollable.
|
||||
return if (thirdPersonReverse && shouldFlip) offset.multiply(1.0, 1.0, -1.0) else offset
|
||||
if (thirdPersonReverse && shouldFlip) offset = offset.multiply(1.0, 1.0, -1.0)
|
||||
return offset
|
||||
}
|
||||
|
||||
private fun getFirstPersonOffset(model: PosableModel, locatorName: String): Vec3 {
|
||||
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.gen9
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.createTransformation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.ModelPartTransformation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class TinkatinkModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("tinkatink")
|
||||
override val head = getPart("head")
|
||||
override val rightArm = getPart("arm_right")
|
||||
override val leftArm = getPart("arm_left")
|
||||
override val rightLeg = getPart("leg_right")
|
||||
override val leftLeg = getPart("leg_left")
|
||||
|
||||
override var portraitScale = 2.0F
|
||||
override var portraitTranslation = Vec3(0.0, -1.01, 0.0)
|
||||
|
||||
override var profileScale = 1.0F
|
||||
override var profileTranslation = Vec3(0.0, 0.25, 0.0)
|
||||
|
||||
lateinit var standing: Pose
|
||||
lateinit var walking: Pose
|
||||
lateinit var sleep: Pose
|
||||
lateinit var battleidle: Pose
|
||||
lateinit var shoulderLeft: Pose
|
||||
lateinit var shoulderRight: Pose
|
||||
|
||||
val shoulderOffset = 1
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("tinkatink", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("tinkatink", "blink") }
|
||||
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("tinkatink", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
|
||||
transformTicks = 10,
|
||||
condition = { !it.isBattling },
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("tinkatink", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walking = registerPose(
|
||||
poseName = "walking",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("tinkatink", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { it.isBattling },
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("tinkatink", "battle_idle")
|
||||
)
|
||||
)
|
||||
|
||||
shoulderLeft = registerPose(
|
||||
poseType = PoseType.SHOULDER_LEFT,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { !it.isBattling },
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("tinkatink", "shoulder_left")
|
||||
),
|
||||
transformedParts = arrayOf(
|
||||
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, shoulderOffset)
|
||||
)
|
||||
)
|
||||
|
||||
shoulderRight = registerPose(
|
||||
poseType = PoseType.SHOULDER_RIGHT,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { !it.isBattling },
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("tinkatink", "shoulder_right")
|
||||
),
|
||||
transformedParts = arrayOf(
|
||||
rootPart.createTransformation().addPosition(ModelPartTransformation.X_AXIS, -shoulderOffset)
|
||||
)
|
||||
)
|
||||
}
|
||||
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walking, battleidle, sleep)) bedrockStateful("tinkatink", "faint") else null
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.gen9
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BimanualFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.BipedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.HeadedFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.CryProvider
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Pose
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.util.isBattling
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class TinkatuffModel (root: ModelPart) : PokemonPosableModel(root), HeadedFrame, BipedFrame, BimanualFrame {
|
||||
override val rootPart = root.registerChildWithAllChildren("tinkatuff")
|
||||
override val head = getPart("head")
|
||||
override val rightArm = getPart("arm_right")
|
||||
override val leftArm = getPart("arm_left")
|
||||
override val rightLeg = getPart("leg_right")
|
||||
override val leftLeg = getPart("leg_left")
|
||||
|
||||
override var portraitScale = 1.9F
|
||||
override var portraitTranslation = Vec3(0.0, -0.41, 0.0)
|
||||
|
||||
override var profileScale = 0.9F
|
||||
override var profileTranslation = Vec3(0.0, 0.4, 0.0)
|
||||
|
||||
lateinit var standing: Pose
|
||||
lateinit var walking: Pose
|
||||
lateinit var sleep: Pose
|
||||
lateinit var battleidle: Pose
|
||||
|
||||
override val cryAnimation = CryProvider { bedrockStateful("tinkatuff", "cry") }
|
||||
|
||||
override fun registerPoses() {
|
||||
val blink = quirk { bedrockStateful("tinkatuff", "blink") }
|
||||
sleep = registerPose(
|
||||
poseType = PoseType.SLEEP,
|
||||
animations = arrayOf(bedrock("tinkatuff", "sleep"))
|
||||
)
|
||||
|
||||
standing = registerPose(
|
||||
poseName = "standing",
|
||||
poseTypes = PoseType.STATIONARY_POSES + PoseType.UI_POSES,
|
||||
transformTicks = 10,
|
||||
condition = { !it.isBattling },
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("tinkatuff", "ground_idle")
|
||||
)
|
||||
)
|
||||
|
||||
walking = registerPose(
|
||||
poseName = "walking",
|
||||
poseTypes = PoseType.MOVING_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("tinkatuff", "ground_walk")
|
||||
)
|
||||
)
|
||||
|
||||
battleidle = registerPose(
|
||||
poseName = "battle_idle",
|
||||
poseTypes = PoseType.STATIONARY_POSES,
|
||||
transformTicks = 10,
|
||||
quirks = arrayOf(blink),
|
||||
condition = { it.isBattling },
|
||||
animations = arrayOf(
|
||||
singleBoneLook(),
|
||||
bedrock("tinkatuff", "battle_idle")
|
||||
)
|
||||
)
|
||||
}
|
||||
override fun getFaintAnimation(state: PosableState) = if (state.isPosedIn(standing, walking, battleidle, sleep)) bedrockStateful("tinkatuff", "faint") else null
|
||||
}
|
||||
+2
@@ -477,6 +477,8 @@ object VaryingModelRepository {
|
||||
inbuilt("illumise", ::IllumiseModel)
|
||||
inbuilt("yamper", ::YamperModel)
|
||||
inbuilt("boltund", ::BoltundModel)
|
||||
inbuilt("tinkatink", ::TinkatinkModel)
|
||||
inbuilt("tinkatuff", ::TinkatuffModel)
|
||||
inbuilt("fuecoco", :: FuecocoModel)
|
||||
inbuilt("crocalor", :: CrocalorModel)
|
||||
inbuilt("skeledirge", :: SkeledirgeModel)
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
package com.cobblemon.mod.common.entity.ai
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.getMemorySafely
|
||||
import com.cobblemon.mod.common.util.mainThreadRuntime
|
||||
import com.cobblemon.mod.common.util.resolveInt
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
@@ -32,23 +29,12 @@ object FleeFromAttackerTask {
|
||||
Trigger { _, entity, _ ->
|
||||
val hurtByEntity = it.get(hurtByEntity)
|
||||
val avoidTarget = it.tryGet(avoidTarget).orElse(null)
|
||||
|
||||
if (avoidTarget != null && avoidTarget == hurtByEntity) {
|
||||
if (avoidTarget != null && avoidTarget == hurtByEntity.uuid) {
|
||||
return@Trigger false
|
||||
}
|
||||
|
||||
mainThreadRuntime.withQueryValue("entity", entity.asMostSpecificMoLangValue())
|
||||
val avoidDurationTicks = mainThreadRuntime.resolveInt(avoidDurationTicks)
|
||||
|
||||
val pokemonEntity = entity as? PokemonEntity
|
||||
pokemonEntity?.let {
|
||||
it.after(1.0f) {
|
||||
it.playMoodParticle("mood_stress")
|
||||
}
|
||||
}
|
||||
|
||||
entity.brain.setMemoryWithExpiry(MemoryModuleType.AVOID_TARGET, hurtByEntity, avoidDurationTicks.toLong())
|
||||
|
||||
return@Trigger true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,16 +39,15 @@ class FollowWalkTargetTask(
|
||||
private var lookTargetPos: BlockPos? = null
|
||||
private var speed = 0f
|
||||
|
||||
override fun checkExtraStartConditions(level: ServerLevel, entity: PathfinderMob): Boolean {
|
||||
override fun checkExtraStartConditions(arg: ServerLevel, arg2: PathfinderMob): Boolean {
|
||||
if (this.pathUpdateCountdownTicks > 0) {
|
||||
--this.pathUpdateCountdownTicks
|
||||
return false
|
||||
} else {
|
||||
val brain = entity.brain
|
||||
val brain = arg2.brain
|
||||
val walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get()
|
||||
val hasReached = this.hasReached(entity, walkTarget)
|
||||
resetPathUpdateCountdownTicks(entity)
|
||||
if (!hasReached && this.hasFinishedPath(entity, walkTarget, level.gameTime)) {
|
||||
val hasReached = this.hasReached(arg2, walkTarget)
|
||||
if (!hasReached && this.hasFinishedPath(arg2, walkTarget, arg.gameTime)) {
|
||||
this.lookTargetPos = walkTarget.target.currentBlockPosition()
|
||||
return true
|
||||
} else {
|
||||
@@ -62,10 +61,6 @@ class FollowWalkTargetTask(
|
||||
}
|
||||
}
|
||||
|
||||
fun resetPathUpdateCountdownTicks(entity: PathfinderMob) {
|
||||
pathUpdateCountdownTicks = entity.random.nextInt(20) + 20
|
||||
}
|
||||
|
||||
override fun canStillUse(arg: ServerLevel, arg2: PathfinderMob, l: Long): Boolean {
|
||||
if (this.path != null && this.lookTargetPos != null) {
|
||||
val optional = arg2.brain.getMemory(MemoryModuleType.WALK_TARGET)
|
||||
@@ -80,7 +75,7 @@ class FollowWalkTargetTask(
|
||||
override fun stop(world: ServerLevel, entity: PathfinderMob, l: Long) {
|
||||
val walkTarget = entity.brain.getMemory(MemoryModuleType.WALK_TARGET).orElse(null)
|
||||
if (walkTarget != null && !this.hasReached(entity, walkTarget) && entity.navigation.isStuck) {
|
||||
resetPathUpdateCountdownTicks(entity)
|
||||
this.pathUpdateCountdownTicks = world.getRandom().nextInt(40)
|
||||
}
|
||||
|
||||
entity.navigation.stop()
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
package com.cobblemon.mod.common.entity.ai
|
||||
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.behavior.OneShot
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
@@ -25,10 +24,6 @@ object GetAngryAtAttackerTask {
|
||||
Trigger { _, entity, _ ->
|
||||
val hurtByEntity = it.get(hurtByEntity)
|
||||
val angryAt = it.tryGet(angryAt).orElse(null)
|
||||
if (angryAt == null && hurtByEntity != null) {
|
||||
(entity as PokemonEntity?)?.playMoodParticle("mood_anger_steam")
|
||||
}
|
||||
|
||||
if (angryAt != null && angryAt == hurtByEntity.uuid) {
|
||||
return@Trigger false
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ class OmniPathNavigation(val world: Level, val entity: Mob) : GroundPathNavigati
|
||||
|
||||
val blockState = this.world.getBlockState(target)
|
||||
val path = if (!blockState.isSolid
|
||||
|| (blockState.`is`(BlockTags.LEAVES) && blockState.block == CobblemonBlocks.SACCHARINE_LEAVES && pather.canPathThroughSaccLeaves())) {
|
||||
|| (blockState.`is`(BlockTags.LEAVES) && blockState.block == CobblemonBlocks.SACCHARINE_LEAVES && (this.entity as PokemonEntity).canPathThroughSaccLeaves())) {
|
||||
findPath(target, distance)
|
||||
} else {
|
||||
blockPos = target.above()
|
||||
@@ -269,7 +269,7 @@ class OmniPathNavigation(val world: Level, val entity: Mob) : GroundPathNavigati
|
||||
// If we can fly and we're airborne, return the current Y position
|
||||
return vec.y
|
||||
}
|
||||
if (world.getBlockState(blockPos).block == CobblemonBlocks.SACCHARINE_LEAVES && pather.canPathThroughSaccLeaves()) {
|
||||
if (world.getBlockState(blockPos).block == CobblemonBlocks.SACCHARINE_LEAVES && (this.entity as PokemonEntity).canPathThroughSaccLeaves()) {
|
||||
return vec.y + 0.5
|
||||
}
|
||||
return if ((canFloat()) && blockGetter.getFluidState(blockPos).`is`(FluidTags.WATER)) vec.y + 0.5 else super.getGroundY(vec)
|
||||
|
||||
+2
-3
@@ -802,14 +802,13 @@ class PokeRodFishingBobberEntity(type: EntityType<out PokeRodFishingBobberEntity
|
||||
|
||||
spawnAction.complete()
|
||||
val result = spawnAction.future
|
||||
val resultingSpawn = result.get()
|
||||
|
||||
if (resultingSpawn == null) {
|
||||
if (result.isCompletedExceptionally) {
|
||||
noBite(player)
|
||||
return false
|
||||
}
|
||||
|
||||
var spawnedPokemon: PokemonEntity? = null
|
||||
val resultingSpawn = result.get()
|
||||
|
||||
if (resultingSpawn is EntitySpawnResult) {
|
||||
for (entity in resultingSpawn.entities) {
|
||||
|
||||
@@ -82,7 +82,6 @@ import com.cobblemon.mod.common.entity.pokemon.effects.EffectTracker
|
||||
import com.cobblemon.mod.common.entity.pokemon.effects.IllusionEffect
|
||||
import com.cobblemon.mod.common.net.messages.client.OpenBehaviourEditorPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.animation.PlayPosableAnimationPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
|
||||
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
|
||||
@@ -420,9 +419,6 @@ open class PokemonEntity(
|
||||
|
||||
var occupiedSeats = arrayOfNulls<Entity>(seats.size)
|
||||
|
||||
var moodParticleLock = false
|
||||
var playedZeroStaminaParticle = false
|
||||
|
||||
init {
|
||||
delegate.initialize(this)
|
||||
delegate.changePokemon(pokemon)
|
||||
@@ -551,11 +547,6 @@ open class PokemonEntity(
|
||||
ifRidingAvailable { _, _, state -> pokemon.rideStamina = state.stamina.get() }
|
||||
ridingController?.context?.state?.reset()
|
||||
ridingAnimationData.clear()
|
||||
|
||||
// reset riding orientation
|
||||
if (this is OrientationControllable) {
|
||||
this.orientationController.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,28 +828,6 @@ open class PokemonEntity(
|
||||
return future
|
||||
}
|
||||
|
||||
fun playMoodParticle(particleName: String) {
|
||||
if (moodParticleLock) return
|
||||
|
||||
cry()
|
||||
SpawnSnowstormEntityParticlePacket(
|
||||
cobblemonResource(particleName),
|
||||
id,
|
||||
listOf("head", "top")
|
||||
).sendToPlayersAround(
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
64.0,
|
||||
level().dimension()
|
||||
)
|
||||
|
||||
moodParticleLock = true
|
||||
after(5.0f) {
|
||||
moodParticleLock = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun saveWithoutId(nbt: CompoundTag): CompoundTag {
|
||||
val tethering = this.tethering
|
||||
if (tethering != null) {
|
||||
@@ -1234,13 +1203,14 @@ open class PokemonEntity(
|
||||
}
|
||||
}
|
||||
|
||||
if (hand == InteractionHand.MAIN_HAND) {
|
||||
if (player.isShiftKeyDown && player is ServerPlayer) {
|
||||
if (hand == InteractionHand.MAIN_HAND && player is ServerPlayer) {
|
||||
if (player.isShiftKeyDown) {
|
||||
showInteractionWheel(player, itemStack)
|
||||
return InteractionResult.sidedSuccess(level().isClientSide)
|
||||
}
|
||||
else if (this.ownerUUID == player.uuid && this.attemptItemInteraction(player, player.getItemInHand(hand))) {
|
||||
return InteractionResult.sidedSuccess(level().isClientSide)
|
||||
else if (pokemon.getOwnerPlayer() == player) {
|
||||
// TODO #105
|
||||
if (this.attemptItemInteraction(player, player.getItemInHand(hand))) return InteractionResult.SUCCESS
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1307,7 +1277,7 @@ open class PokemonEntity(
|
||||
}
|
||||
|
||||
override fun shouldBeSaved(): Boolean {
|
||||
if (ownerUUID == null && !pokemon.isNPCOwned() && (Cobblemon.config.savePokemonToWorld || isPersistenceRequired)) {
|
||||
if (ownerUUID == null && !pokemon.isNPCOwned() && (Cobblemon.config.savePokemonToWorld || isPersistenceRequired || this.pokemon.canDropHeldItem)) {
|
||||
CobblemonEvents.POKEMON_ENTITY_SAVE_TO_WORLD.postThen(PokemonEntitySaveToWorldEvent(this)) {
|
||||
return true
|
||||
}
|
||||
@@ -1416,24 +1386,18 @@ open class PokemonEntity(
|
||||
return bagItemLike.handleInteraction(player, battlePokemon, stack)
|
||||
}
|
||||
|
||||
if (this.isBusy) {
|
||||
if (player !is ServerPlayer || this.isBusy) {
|
||||
return false
|
||||
}
|
||||
|
||||
val interaction = PokemonInteractions.findInteraction(this)
|
||||
|
||||
if (interaction != null && !pokemon.isOnInteractionCooldown(interaction.grouping)) {
|
||||
if (player is ServerPlayer) {
|
||||
interaction.effects.forEach { it.applyEffect(this, player) }
|
||||
pokemon.interactionCooldowns.put(interaction.grouping, runtime.resolveInt(interaction.cooldown))
|
||||
}
|
||||
|
||||
interaction.effects.forEach { it.applyEffect(this, player) }
|
||||
pokemon.interactionCooldowns.put(interaction.grouping, runtime.resolveInt(interaction.cooldown))
|
||||
return true
|
||||
}
|
||||
|
||||
if (player !is ServerPlayer) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Evolution item logic
|
||||
if (pokemon.getOwnerPlayer() == player) {
|
||||
val context = ItemInteractionEvolution.ItemInteractionContext(stack, player.level())
|
||||
@@ -2239,8 +2203,6 @@ open class PokemonEntity(
|
||||
ifRidingAvailable { _, _, state ->
|
||||
state.stamina.set(entityData.get(RIDE_STAMINA))
|
||||
}
|
||||
|
||||
playedZeroStaminaParticle = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2269,26 +2231,12 @@ open class PokemonEntity(
|
||||
|
||||
override fun tickRidden(driver: Player, movementInput: Vec3) {
|
||||
super.tickRidden(driver, movementInput)
|
||||
|
||||
ifRidingAvailable { behaviour, settings, state ->
|
||||
behaviour.tick(settings, state, this, driver, movementInput)
|
||||
if (entityData.get(RIDE_STAMINA) == -1F) {
|
||||
state.stamina.set(1F, forced = true)
|
||||
}
|
||||
|
||||
if (!level().isClientSide) {
|
||||
val stamina = state.stamina.get()
|
||||
|
||||
if (stamina <= 0f) {
|
||||
if (!playedZeroStaminaParticle) {
|
||||
playMoodParticle("mood_stress")
|
||||
playedZeroStaminaParticle = true
|
||||
}
|
||||
} else {
|
||||
playedZeroStaminaParticle = false
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.level().isClientSide) {
|
||||
val pose = behaviour.pose(settings, state, this)
|
||||
if (pose != this.entityData.get(POSE_TYPE)) {
|
||||
|
||||
+2
-19
@@ -10,11 +10,8 @@ package com.cobblemon.mod.common.entity.pokemon.ai.sensors
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.getMemorySafely
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.Mob
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities
|
||||
import net.minecraft.world.entity.ai.sensing.Sensor
|
||||
@@ -31,24 +28,10 @@ class DefendOwnerSensor : Sensor<PokemonEntity>(10) {
|
||||
}
|
||||
|
||||
private fun setNearestAttacker(entity: PokemonEntity, visibleMobs: NearestVisibleLivingEntities, owner: LivingEntity) {
|
||||
val nearestAttacker = visibleMobs.findClosest { livingEntity ->
|
||||
// Prevents Pokémons from attacking players as owned Pokémons are currently invulnerable
|
||||
if (livingEntity is ServerPlayer) return@findClosest false
|
||||
|
||||
if (livingEntity.lastHurtMob == owner) return@findClosest true
|
||||
if (livingEntity is Mob && livingEntity.target == owner) return@findClosest true
|
||||
|
||||
val mobAttackTarget = livingEntity.brain.getMemorySafely(MemoryModuleType.ATTACK_TARGET)
|
||||
if (mobAttackTarget.isPresent && mobAttackTarget.get() == owner) return@findClosest true
|
||||
|
||||
return@findClosest false
|
||||
val nearestAttacker = visibleMobs.findClosest { mob ->
|
||||
mob.lastHurtMob == owner
|
||||
}.map { mob -> mob as LivingEntity }
|
||||
|
||||
val previousAttacker = entity.brain.getMemorySafely(CobblemonMemories.NEAREST_VISIBLE_ATTACKER)
|
||||
if (nearestAttacker.isPresent && previousAttacker.isEmpty) {
|
||||
entity.playMoodParticle("mood_anger_steam")
|
||||
}
|
||||
|
||||
entity.brain.setMemory(CobblemonMemories.NEAREST_VISIBLE_ATTACKER, nearestAttacker)
|
||||
}
|
||||
}
|
||||
-6
@@ -9,7 +9,6 @@
|
||||
package com.cobblemon.mod.common.entity.pokemon.ai.tasks
|
||||
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.util.getMemorySafely
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.Mob
|
||||
import net.minecraft.world.entity.ai.behavior.OneShot
|
||||
@@ -61,12 +60,7 @@ object AttackHostileMobsTask {
|
||||
}
|
||||
|
||||
if (hostile != null) {
|
||||
if (currentTarget == null) {
|
||||
(entity as? PokemonEntity)?.playMoodParticle("mood_anger_steam")
|
||||
}
|
||||
|
||||
entity.brain.setMemory(MemoryModuleType.ATTACK_TARGET, hostile)
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
||||
+8
@@ -10,10 +10,18 @@ package com.cobblemon.mod.common.entity.pokemon.ai.tasks
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.google.common.collect.ImmutableMap
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes
|
||||
import net.minecraft.world.entity.ai.behavior.Behavior
|
||||
import net.minecraft.world.entity.ai.behavior.OneShot
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder
|
||||
import net.minecraft.world.entity.ai.behavior.declarative.Trigger
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType
|
||||
import net.minecraft.world.entity.ai.memory.MemoryStatus
|
||||
import net.minecraft.world.entity.ai.memory.WalkTarget
|
||||
import net.minecraft.world.entity.ai.targeting.TargetingConditions
|
||||
|
||||
object DefendOwnerTask {
|
||||
fun create(): OneShot<PokemonEntity> {
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ class EatHeldItemTask(entity: PokemonEntity) : Behavior<PokemonEntity>(
|
||||
}
|
||||
this.timelastEaten = time
|
||||
if (itemConfig != null && itemConfig.fullnessValue > 0) {
|
||||
entity.pokemon.feedPokemon(itemConfig.fullnessValue, false, false)
|
||||
entity.pokemon.feedPokemon(itemConfig.fullnessValue, false)
|
||||
}
|
||||
// Check if the result item is something that should be dropped
|
||||
resultItemStack = entity.pokemon.heldItem()
|
||||
|
||||
+1
-2
@@ -52,9 +52,8 @@ object PlaceHoneyInHiveTask {
|
||||
if (blockEntity.isFull) {
|
||||
// Erase Hive memory and give the bee a moment to locate a new hive
|
||||
entity.brain.eraseMemory(CobblemonMemories.HIVE_LOCATION)
|
||||
} else {
|
||||
blockEntity.addOccupant(entity)
|
||||
}
|
||||
blockEntity.addOccupant(entity)
|
||||
}
|
||||
|
||||
return@Trigger true
|
||||
|
||||
@@ -30,13 +30,21 @@ import com.cobblemon.mod.common.api.events.battles.BattleStartedEvent
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleVictoryEvent
|
||||
import com.cobblemon.mod.common.api.events.fishing.PokerodCastEvent
|
||||
import com.cobblemon.mod.common.api.events.fishing.PokerodReelEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.*
|
||||
import com.cobblemon.mod.common.api.events.pokemon.CollectEggEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.FossilRevivedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.HatchEggEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.LevelUpEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.PokemonCapturedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.PokemonGainedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.RidePokemonEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.TradeEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.evolution.EvolutionCompleteEvent
|
||||
import com.cobblemon.mod.common.api.events.storage.ReleasePokemonEvent
|
||||
import com.cobblemon.mod.common.api.stats.CobblemonStats.getStat
|
||||
import com.cobblemon.mod.common.util.getPlayer
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
|
||||
object StatHandler : EventHandler {
|
||||
override fun registerListeners() {
|
||||
@@ -92,13 +100,13 @@ object StatHandler : EventHandler {
|
||||
|
||||
fun onBattleStart(event : BattleStartedEvent) {
|
||||
event.battle.players.forEach { player ->
|
||||
player.awardStat(getStat(Cobblemon.statistics.BATTLES_TOTAL))
|
||||
player.awardStat(this.getStat(getStat(Cobblemon.statistics.BATTLES_TOTAL)))
|
||||
}
|
||||
}
|
||||
|
||||
fun onDexEntryGain(event : PokemonGainedEvent) {
|
||||
val player = event.pokemon.getOwnerPlayer()
|
||||
player?.awardStat(getStat(Cobblemon.statistics.DEX_ENTRIES))
|
||||
player?.awardStat(getStat(getStat(Cobblemon.statistics.DEX_ENTRIES)))
|
||||
}
|
||||
|
||||
fun onCollectEgg(event : CollectEggEvent) {
|
||||
@@ -131,4 +139,12 @@ object StatHandler : EventHandler {
|
||||
fun onReelIn(event : PokerodReelEvent) {
|
||||
event.player.awardStat(getStat(Cobblemon.statistics.REEL_INS))
|
||||
}
|
||||
|
||||
fun getStat(resourceLocation: ResourceLocation) : ResourceLocation {
|
||||
val stat = BuiltInRegistries.CUSTOM_STAT.get(resourceLocation)
|
||||
if (stat == null) {
|
||||
Cobblemon.LOGGER.error("Could not find stat with id {}", resourceLocation)
|
||||
}
|
||||
return stat ?: throw NullPointerException("Could not find stat with id $resourceLocation")
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,7 @@ import com.cobblemon.mod.common.api.apricorn.Apricorn
|
||||
import com.cobblemon.mod.common.api.item.PokemonSelectingItem
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.client.pot.CookingQuality
|
||||
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
@@ -93,9 +91,7 @@ class AprijuiceItem(val type: Apricorn): CobblemonItem(Properties().stacksTo(16)
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
if (!pokemon.feedPokemon(1)) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
pokemon.feedPokemon(1)
|
||||
|
||||
val boosts = getBoosts(stack)
|
||||
pokemon.addRideBoosts(boosts.mapValues { it.value.toFloat() })
|
||||
|
||||
@@ -96,9 +96,8 @@ class PokePuffItem : Item(Properties().stacksTo(64)), PokemonSelectingItem {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
if (!pokemon.feedPokemon(4)) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
// Feed the Pokémon 4 fullness points
|
||||
pokemon.feedPokemon(4)
|
||||
|
||||
val friendshipChange = PokePuffUtils.calculateFriendshipChange(stack, pokemon.nature)
|
||||
|
||||
|
||||
+6
-8
@@ -54,16 +54,14 @@ class FriendshipRaisingBerryItem(block: BerryBlock, val stat: Stat) : BerryItem(
|
||||
val evLowerAmount = max(genericRuntime.resolveInt(CobblemonMechanics.berries.evLowerAmount), 0)
|
||||
val decreasedEVs = pokemon.evs.add(stat, -evLowerAmount, ItemEvSource(player, stack, pokemon)) != 0
|
||||
|
||||
if (!increasedFriendship && !decreasedEVs) {
|
||||
return InteractionResultHolder.pass(stack)
|
||||
}
|
||||
return if (increasedFriendship || decreasedEVs) {
|
||||
pokemon.feedPokemon(1)
|
||||
|
||||
if (!pokemon.feedPokemon(1)) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
stack.consume(1, player)
|
||||
InteractionResultHolder.success(stack)
|
||||
} else {
|
||||
InteractionResultHolder.pass(stack)
|
||||
}
|
||||
|
||||
stack.consume(1, player)
|
||||
return InteractionResultHolder.success(stack)
|
||||
}
|
||||
|
||||
override fun use(world: Level, user: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
|
||||
|
||||
@@ -54,10 +54,7 @@ class HealingBerryItem(block: BerryBlock, val amount: () -> ExpressionLike): Ber
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
if (!pokemon.feedPokemon(1)) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
pokemon.feedPokemon(1)
|
||||
pokemon.currentHealth = Integer.min(pokemon.currentHealth + genericRuntime.resolveInt(amount(), pokemon), pokemon.maxHealth)
|
||||
stack.consume(1, player)
|
||||
return InteractionResultHolder.success(stack)
|
||||
@@ -65,7 +62,7 @@ class HealingBerryItem(block: BerryBlock, val amount: () -> ExpressionLike): Ber
|
||||
|
||||
override fun applyToBattlePokemon(player: ServerPlayer, stack: ItemStack, battlePokemon: BattlePokemon) {
|
||||
super.applyToBattlePokemon(player, stack, battlePokemon)
|
||||
battlePokemon.originalPokemon.feedPokemon(1, playMoodParticle = false)
|
||||
battlePokemon.originalPokemon.feedPokemon(1)
|
||||
}
|
||||
|
||||
override fun use(world: Level, user: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
|
||||
|
||||
@@ -48,26 +48,21 @@ class PPRestoringBerryItem(block: BerryBlock, val amount: () -> ExpressionLike):
|
||||
&& super.canUseOnPokemon(stack, pokemon)
|
||||
|
||||
override fun applyToPokemon(player: ServerPlayer, stack: ItemStack, pokemon: Pokemon, move: Move) {
|
||||
if (!canUseOnPokemon(stack, pokemon) && canUseOnMove(stack, move)) {
|
||||
return
|
||||
}
|
||||
if (canUseOnPokemon(stack, pokemon) && canUseOnMove(stack, move)) {
|
||||
pokemon.feedPokemon(1)
|
||||
val moveToRecover = pokemon.moveSet.find { it.template == move.template }
|
||||
if (moveToRecover != null && moveToRecover.currentPp < moveToRecover.maxPp) {
|
||||
moveToRecover.currentPp =
|
||||
min(moveToRecover.maxPp, moveToRecover.currentPp + genericRuntime.resolveInt(amount(), pokemon))
|
||||
|
||||
if (!pokemon.feedPokemon(1)) {
|
||||
return
|
||||
}
|
||||
|
||||
val moveToRecover = pokemon.moveSet.find { it.template == move.template }
|
||||
if (moveToRecover != null && moveToRecover.currentPp < moveToRecover.maxPp) {
|
||||
moveToRecover.currentPp =
|
||||
min(moveToRecover.maxPp, moveToRecover.currentPp + genericRuntime.resolveInt(amount(), pokemon))
|
||||
|
||||
stack.consume(1, player)
|
||||
stack.consume(1, player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun applyToBattlePokemon(player: ServerPlayer, stack: ItemStack, battlePokemon: BattlePokemon, move: Move) {
|
||||
super.applyToBattlePokemon(player, stack, battlePokemon, move)
|
||||
battlePokemon.originalPokemon.feedPokemon(1, playMoodParticle = false)
|
||||
battlePokemon.originalPokemon.feedPokemon(1)
|
||||
}
|
||||
|
||||
override fun use(world: Level, user: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
|
||||
|
||||
+2
-4
@@ -59,9 +59,7 @@ class PortionHealingBerryItem(block: BerryBlock, val canCauseConfusion: Boolean,
|
||||
}
|
||||
|
||||
// count these berries as multiple feedings due to the amount they heal
|
||||
if (!pokemon.feedPokemon(5)) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
pokemon.feedPokemon(5)
|
||||
|
||||
var amount = Integer.min(pokemon.currentHealth + (genericRuntime.resolveFloat(portion(), pokemon) * pokemon.maxHealth).toInt(), pokemon.maxHealth)
|
||||
CobblemonEvents.POKEMON_HEALED.postThen(PokemonHealedEvent(pokemon, amount, this), { cancelledEvent -> return InteractionResultHolder.fail(stack)}) { event ->
|
||||
@@ -75,7 +73,7 @@ class PortionHealingBerryItem(block: BerryBlock, val canCauseConfusion: Boolean,
|
||||
|
||||
override fun applyToBattlePokemon(player: ServerPlayer, stack: ItemStack, battlePokemon: BattlePokemon) {
|
||||
super.applyToBattlePokemon(player, stack, battlePokemon)
|
||||
battlePokemon.originalPokemon.feedPokemon(5, playMoodParticle = false)
|
||||
battlePokemon.originalPokemon.feedPokemon(5)
|
||||
}
|
||||
|
||||
override fun use(world: Level, user: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
|
||||
|
||||
+8
-12
@@ -58,23 +58,19 @@ class StatusCuringBerryItem(block: BerryBlock, vararg val status: Status): Berry
|
||||
stack: ItemStack,
|
||||
pokemon: Pokemon
|
||||
): InteractionResultHolder<ItemStack>? {
|
||||
if (!canUseOnPokemon(stack, pokemon)) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
return if (canUseOnPokemon(stack, pokemon)) {
|
||||
pokemon.feedPokemon(1)
|
||||
pokemon.status = null
|
||||
stack.consume(1, player)
|
||||
InteractionResultHolder.success(stack)
|
||||
} else {
|
||||
InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
if (!pokemon.feedPokemon(1)) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
pokemon.status = null
|
||||
stack.consume(1, player)
|
||||
|
||||
return InteractionResultHolder.success(stack)
|
||||
}
|
||||
|
||||
override fun applyToBattlePokemon(player: ServerPlayer, stack: ItemStack, battlePokemon: BattlePokemon) {
|
||||
super.applyToBattlePokemon(player, stack, battlePokemon)
|
||||
battlePokemon.originalPokemon.feedPokemon(1, playMoodParticle = false)
|
||||
battlePokemon.originalPokemon.feedPokemon(1)
|
||||
}
|
||||
|
||||
override fun use(world: Level, user: Player, hand: InteractionHand): InteractionResultHolder<ItemStack> {
|
||||
|
||||
@@ -53,10 +53,7 @@ class BerryJuiceItem : CobblemonItem(Properties()), PokemonSelectingItem, Healin
|
||||
if (!canUseOnPokemon(stack, pokemon)) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
if (!pokemon.feedPokemon(1)) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
pokemon.feedPokemon(1)
|
||||
|
||||
var amount = Integer.min(pokemon.currentHealth + 20, pokemon.maxHealth)
|
||||
CobblemonEvents.POKEMON_HEALED.postThen(PokemonHealedEvent(pokemon, amount, this), { cancelledEvent -> return InteractionResultHolder.fail(stack)}) { event ->
|
||||
@@ -77,9 +74,7 @@ class BerryJuiceItem : CobblemonItem(Properties()), PokemonSelectingItem, Healin
|
||||
|
||||
override fun applyToBattlePokemon(player: ServerPlayer, stack: ItemStack, battlePokemon: BattlePokemon) {
|
||||
super.applyToBattlePokemon(player, stack, battlePokemon)
|
||||
|
||||
battlePokemon.originalPokemon.feedPokemon(1, playMoodParticle = false)
|
||||
|
||||
battlePokemon.originalPokemon.feedPokemon(1)
|
||||
if (!player.hasInfiniteMaterials()) {
|
||||
val woodenBowlItemStack = ItemStack(Items.BOWL)
|
||||
if (!player.inventory.add(woodenBowlItemStack)) {
|
||||
|
||||
+1
-4
@@ -33,10 +33,7 @@ class FreshStartMochiItem : CobblemonItem(Properties()), PokemonSelectingItem {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
if (!pokemon.feedPokemon(1)) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
pokemon.feedPokemon(1)
|
||||
pokemon.evs.forEach {
|
||||
pokemon.evs[it.key] = 0
|
||||
}
|
||||
|
||||
@@ -24,10 +24,10 @@ class MochiItem(stat: Stats): EVIncreaseItem(stat, 4) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
if (!pokemon.feedPokemon(1)) {
|
||||
return InteractionResultHolder.fail(stack)
|
||||
}
|
||||
|
||||
pokemon.feedPokemon(1)
|
||||
|
||||
stack.consume(1, player)
|
||||
|
||||
return super.applyToPokemon(player, stack, pokemon)
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import net.minecraft.world.level.Level
|
||||
class PonigiriItem : Item(
|
||||
Properties().stacksTo(64)
|
||||
.food(FoodProperties.Builder()
|
||||
.alwaysEdible()
|
||||
.nutrition(2)
|
||||
.saturationModifier(0.55f)
|
||||
.build())
|
||||
|
||||
-48
@@ -1,48 +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.net.messages.client.data
|
||||
|
||||
import com.cobblemon.mod.common.api.interaction.PokemonInteractionSet
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
|
||||
class PokemonInteractionsSyncPacket(
|
||||
val speciesInteractions: List<PokemonInteractionSet>,
|
||||
val generalInteractions: List<PokemonInteractionSet>,
|
||||
) : NetworkPacket<PokemonInteractionsSyncPacket> {
|
||||
override val id = ID
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeCollection(speciesInteractions) { it, speciesInteraction ->
|
||||
speciesInteraction.encode(it)
|
||||
}
|
||||
buffer.writeCollection(generalInteractions) { it, generalInteraction ->
|
||||
generalInteraction.encode(it)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("pokemon_interactions_sync")
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): PokemonInteractionsSyncPacket {
|
||||
val speciesInteractions = buffer.readList { it ->
|
||||
PokemonInteractionSet.decode(it)
|
||||
}
|
||||
val generalInteractions = buffer.readList { it ->
|
||||
PokemonInteractionSet.decode(it)
|
||||
}
|
||||
|
||||
return PokemonInteractionsSyncPacket(
|
||||
speciesInteractions,
|
||||
generalInteractions,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -21,9 +21,7 @@ class PokemonStateUpdatePacket(pokemon: () -> Pokemon?, value: PokemonState): Si
|
||||
value.writeToBuffer(buffer)
|
||||
}
|
||||
|
||||
override fun set(pokemon: Pokemon, value: PokemonState) {
|
||||
pokemon.state = value
|
||||
}
|
||||
override fun set(pokemon: Pokemon, value: PokemonState) { pokemon.state = value }
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("state_update")
|
||||
|
||||
+10
-24
@@ -13,24 +13,30 @@ import com.cobblemon.mod.common.api.mark.Marks
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.entity.PlatformType
|
||||
import com.cobblemon.mod.common.entity.PoseType
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokemon.Gender
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readEnumConstant
|
||||
import com.cobblemon.mod.common.util.readIdentifier
|
||||
import com.cobblemon.mod.common.util.readString
|
||||
import com.cobblemon.mod.common.util.readText
|
||||
import com.cobblemon.mod.common.util.writeEnumConstant
|
||||
import com.cobblemon.mod.common.util.writeIdentifier
|
||||
import com.cobblemon.mod.common.util.writeString
|
||||
import com.cobblemon.mod.common.util.writeText
|
||||
import java.util.UUID
|
||||
import net.minecraft.client.multiplayer.ClientLevel
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.entity.Entity
|
||||
import java.util.*
|
||||
|
||||
class SpawnPokemonPacket(
|
||||
var ownerId: UUID?,
|
||||
var pokemonUUID: UUID,
|
||||
var storageUUID: UUID?,
|
||||
var scaleModifier: Float,
|
||||
var speciesId: ResourceLocation,
|
||||
var gender: Gender,
|
||||
@@ -55,7 +61,6 @@ class SpawnPokemonPacket(
|
||||
var tickSpawned: Int,
|
||||
var rideBoosts: Map<RidingStat, Float>,
|
||||
var rideStamina: Float,
|
||||
var silent: Boolean,
|
||||
vanillaSpawnPacket: ClientboundAddEntityPacket,
|
||||
) : SpawnExtraDataEntityPacket<SpawnPokemonPacket, PokemonEntity>(vanillaSpawnPacket) {
|
||||
|
||||
@@ -64,7 +69,6 @@ class SpawnPokemonPacket(
|
||||
constructor(entity: PokemonEntity, vanillaSpawnPacket: ClientboundAddEntityPacket) : this(
|
||||
entity.ownerUUID,
|
||||
entity.pokemon.uuid,
|
||||
entity.pokemon.storeCoordinates.get()?.store?.uuid,
|
||||
entity.pokemon.scaleModifier,
|
||||
entity.exposedSpecies.resourceIdentifier,
|
||||
entity.pokemon.gender,
|
||||
@@ -89,14 +93,12 @@ class SpawnPokemonPacket(
|
||||
entity.tickCount,
|
||||
entity.entityData.get(PokemonEntity.RIDE_BOOSTS),
|
||||
entity.entityData.get(PokemonEntity.RIDE_STAMINA),
|
||||
entity.isSilent,
|
||||
vanillaSpawnPacket
|
||||
)
|
||||
|
||||
override fun encodeEntityData(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeNullable(ownerId) { _, v -> buffer.writeUUID(v) }
|
||||
buffer.writeUUID(this.pokemonUUID)
|
||||
buffer.writeNullable(this.storageUUID) { pb, value -> pb.writeUUID(value) }
|
||||
buffer.writeFloat(this.scaleModifier)
|
||||
buffer.writeIdentifier(this.speciesId)
|
||||
buffer.writeEnumConstant(this.gender)
|
||||
@@ -125,21 +127,10 @@ class SpawnPokemonPacket(
|
||||
{ _, value -> buffer.writeFloat(value) }
|
||||
)
|
||||
buffer.writeFloat(rideStamina)
|
||||
buffer.writeBoolean(silent)
|
||||
}
|
||||
|
||||
override fun applyData(entity: PokemonEntity, level: ClientLevel) {
|
||||
entity.ownerUUID = ownerId
|
||||
|
||||
// Reuse the stored Pokémon instance to avoid creating a duplicate,
|
||||
// preventing client/entity desync issues.
|
||||
this@SpawnPokemonPacket.storageUUID?.let {
|
||||
val storedPokemon = CobblemonClient.storage.locatePokemon(it, this@SpawnPokemonPacket.pokemonUUID)
|
||||
if (storedPokemon != null) {
|
||||
entity.pokemon = storedPokemon
|
||||
}
|
||||
}
|
||||
|
||||
entity.pokemon.apply {
|
||||
uuid = this@SpawnPokemonPacket.pokemonUUID
|
||||
scaleModifier = this@SpawnPokemonPacket.scaleModifier
|
||||
@@ -171,7 +162,6 @@ class SpawnPokemonPacket(
|
||||
entity.entityData.set(PokemonEntity.RIDE_BOOSTS, rideBoosts)
|
||||
entity.entityData.set(PokemonEntity.RIDE_STAMINA, rideStamina)
|
||||
entity.entityData.set(PokemonEntity.SCALE_MODIFIER, scaleModifier)
|
||||
entity.isSilent = silent
|
||||
|
||||
entity.ejectPassengers()
|
||||
passengers.forEach {
|
||||
@@ -189,7 +179,6 @@ class SpawnPokemonPacket(
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): SpawnPokemonPacket {
|
||||
val ownerId = buffer.readNullable { buffer.readUUID() }
|
||||
val pokemonUUID = buffer.readUUID()
|
||||
val storageUUID = buffer.readNullable { buffer.readUUID() }
|
||||
val scaleModifier = buffer.readFloat()
|
||||
val speciesId = buffer.readIdentifier()
|
||||
val gender = buffer.readEnumConstant(Gender::class.java)
|
||||
@@ -217,13 +206,11 @@ class SpawnPokemonPacket(
|
||||
{ buffer.readFloat() }
|
||||
)
|
||||
val rideStamina = buffer.readFloat()
|
||||
val silent = buffer.readBoolean()
|
||||
val vanillaPacket = decodeVanillaPacket(buffer)
|
||||
|
||||
return SpawnPokemonPacket(
|
||||
ownerId,
|
||||
pokemonUUID,
|
||||
storageUUID,
|
||||
scaleModifier,
|
||||
speciesId,
|
||||
gender,
|
||||
@@ -248,7 +235,6 @@ class SpawnPokemonPacket(
|
||||
tickSpawned,
|
||||
rideBoosts,
|
||||
rideStamina,
|
||||
silent,
|
||||
vanillaPacket
|
||||
)
|
||||
}
|
||||
|
||||
@@ -897,10 +897,6 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
this.recall()
|
||||
}
|
||||
|
||||
fun playMoodParticle(particleName: String) {
|
||||
entity?.playMoodParticle(particleName)
|
||||
}
|
||||
|
||||
fun heal() {
|
||||
CobblemonEvents.POKEMON_HEALED.postThen(PokemonHealedEvent(this)) { event ->
|
||||
this.currentHealth = maxHealth
|
||||
@@ -968,13 +964,23 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
else -> 0 // For weights less than 0.1
|
||||
}
|
||||
|
||||
fun feedPokemon(feedCount: Int, playSound: Boolean = true, playMoodParticle: Boolean = true): Boolean {
|
||||
playFullnessEffects(playSound, playMoodParticle)
|
||||
fun feedPokemon(feedCount: Int, playSound: Boolean = true) {
|
||||
// play sounds from the entity first (itemstack is consumed outside of this function)
|
||||
if (this.entity != null && playSound) {
|
||||
val fullnessPercent = ((this.currentFullness).toFloat() / (this.getMaxFullness()).toFloat()) * (.5f)
|
||||
|
||||
if (this.currentFullness >= this.getMaxFullness()) {
|
||||
this.entity?.playSound(CobblemonSounds.BERRY_EAT_FULL, 1F, 1F)
|
||||
}
|
||||
else {
|
||||
this.entity?.playSound(CobblemonSounds.BERRY_EAT, 1F, 1F + fullnessPercent)
|
||||
}
|
||||
}
|
||||
|
||||
// if it is already full we don't need to do anything
|
||||
// TODO this can happen when feeding in battle since we are temporarily ignoring fullness checks for pp/hp/status berries
|
||||
if (isFull()) {
|
||||
return false
|
||||
return
|
||||
}
|
||||
|
||||
this.currentFullness = (this.currentFullness + feedCount).coerceIn(0, this.getMaxFullness())
|
||||
@@ -983,31 +989,6 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
if (this.currentFullness == 1) {
|
||||
this.resetMetabolismCycle()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun playFullnessEffects(playSound: Boolean = true, playMoodParticle: Boolean = true) {
|
||||
if (!playSound && !playMoodParticle) return
|
||||
|
||||
val pokemonEntity = entity ?: return
|
||||
val fullnessPercent = ((this.currentFullness).toFloat() / (this.getMaxFullness()).toFloat()) * (.5f)
|
||||
|
||||
if (!isFull()) {
|
||||
if (playSound) {
|
||||
pokemonEntity.playSound(CobblemonSounds.BERRY_EAT, 1F, 1F + fullnessPercent)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (playSound) {
|
||||
pokemonEntity.playSound(CobblemonSounds.BERRY_EAT_FULL, 1F, 1F)
|
||||
|
||||
if (playMoodParticle) {
|
||||
pokemonEntity.playMoodParticle("mood_annoyed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// decrease a pokemon's Fullness value by a certain amount
|
||||
@@ -1456,11 +1437,6 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
}
|
||||
|
||||
fun getOwnerEntity(): LivingEntity? {
|
||||
if (isClient) {
|
||||
val ownerUUID = entity?.ownerUUID ?: return null
|
||||
return entity?.level()?.getPlayerByUUID(ownerUUID)
|
||||
}
|
||||
|
||||
return storeCoordinates.get()?.let {
|
||||
if (isPlayerOwned()) {
|
||||
server()?.playerList?.getPlayer(it.store.uuid)
|
||||
|
||||
+7
-55
@@ -8,22 +8,13 @@
|
||||
|
||||
package com.cobblemon.mod.common.pokemon.adapters
|
||||
|
||||
import com.cobblemon.mod.common.api.interaction.InteractionEffect
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.api.pokemon.adapters.RequirementAdapter
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
||||
import com.cobblemon.mod.common.pokemon.evolution.adapters.LegacyItemConditionWrapperAdapter
|
||||
import com.cobblemon.mod.common.pokemon.requirements.*
|
||||
import com.cobblemon.mod.common.util.adapters.*
|
||||
import com.cobblemon.mod.common.util.readString
|
||||
import com.cobblemon.mod.common.util.writeString
|
||||
import com.google.common.collect.HashBiMap
|
||||
import com.google.gson.*
|
||||
import net.minecraft.advancements.critereon.ItemPredicate
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.LowerCaseEnumTypeAdapterFactory
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@@ -69,60 +60,21 @@ object CobblemonRequirementAdapter : RequirementAdapter {
|
||||
this.registerType(OwnerHoldsItemRequirement.ADAPTER_VARIANT, OwnerHoldsItemRequirement::class)
|
||||
}
|
||||
|
||||
val gson: Gson by lazy {
|
||||
GsonBuilder()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(PokemonProperties::class.java, pokemonPropertiesShortAdapter)
|
||||
.registerTypeAdapter(ItemPredicate::class.java, LegacyItemConditionWrapperAdapter)
|
||||
.registerTypeAdapter(Requirement::class.java, CobblemonRequirementAdapter)
|
||||
.registerTypeAdapter(InteractionEffect::class.java, InteractionEffectAdapter)
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
|
||||
.registerTypeAdapterFactory(LowerCaseEnumTypeAdapterFactory())
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
}
|
||||
|
||||
override fun <T : Requirement> registerType(id: String, type: KClass<T>) {
|
||||
this.types[id.lowercase()] = type
|
||||
}
|
||||
|
||||
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Requirement {
|
||||
val variant = json.asJsonObject.get(VARIANT).asString.lowercase()
|
||||
val type = getRequirementType(variant)
|
||||
val type = this.types[variant] ?: throw IllegalArgumentException("Cannot resolve evolution requirement type for variant $variant")
|
||||
return context.deserialize(json, type.java)
|
||||
}
|
||||
|
||||
override fun serialize(requirement: Requirement, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
|
||||
val json = context.serialize(requirement, requirement::class.java).asJsonObject
|
||||
val variant = getVariant(requirement)
|
||||
override fun serialize(src: Requirement, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
|
||||
val json = context.serialize(src, src::class.java).asJsonObject
|
||||
val variant = this.types.inverse()[src::class] ?: throw IllegalArgumentException("Cannot resolve evolution requirement for type ${src::class.qualifiedName}")
|
||||
json.addProperty(VARIANT, variant)
|
||||
return json
|
||||
}
|
||||
|
||||
fun encode(requirement: Requirement, buffer: FriendlyByteBuf) {
|
||||
buffer.writeString(gson.toJson(requirement, Requirement::class.java))
|
||||
}
|
||||
|
||||
fun decode(buffer: FriendlyByteBuf): Requirement {
|
||||
return gson.fromJson(buffer.readString(), Requirement::class.java)
|
||||
}
|
||||
|
||||
private fun getVariant(requirement: Requirement): String {
|
||||
val variant = this.types.inverse()[requirement::class]
|
||||
if (variant == null) {
|
||||
throw IllegalArgumentException("Cannot resolve evolution requirement for type ${requirement::class.qualifiedName}")
|
||||
}
|
||||
|
||||
return variant
|
||||
}
|
||||
|
||||
private fun getRequirementType(variant: String): KClass<out Requirement> {
|
||||
val requirementType = this.types[variant]
|
||||
if (requirementType == null) {
|
||||
throw IllegalArgumentException("Cannot resolve evolution requirement type for variant $variant")
|
||||
}
|
||||
|
||||
return requirementType
|
||||
}
|
||||
}
|
||||
+4
-7
@@ -11,9 +11,9 @@ package com.cobblemon.mod.common.pokemon.requirements
|
||||
import com.cobblemon.mod.common.api.pokemon.requirement.OwnerQueryRequirement
|
||||
import com.cobblemon.mod.common.entity.npc.NPCEntity
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import kotlin.collections.iterator
|
||||
|
||||
/**
|
||||
* An [com.cobblemon.mod.common.api.pokemon.requirement.Requirement] that checks if the player has a certain [net.minecraft.advancements.Advancement]
|
||||
@@ -26,16 +26,13 @@ class AdvancementRequirement(val requiredAdvancement: ResourceLocation) : OwnerQ
|
||||
|
||||
override fun checkPlayer(
|
||||
pokemon: Pokemon,
|
||||
owner: Player
|
||||
owner: ServerPlayer
|
||||
): Boolean {
|
||||
val serverPlayer = owner as? ServerPlayer ?: return false
|
||||
|
||||
for (entry in serverPlayer.advancements.progress) {
|
||||
for (entry in owner.advancements.progress) {
|
||||
if (entry.key.id == requiredAdvancement && entry.value.isDone) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -12,9 +12,11 @@ import com.cobblemon.mod.common.api.pokemon.requirement.OwnerQueryRequirement
|
||||
import com.cobblemon.mod.common.entity.npc.NPCEntity
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.advancements.critereon.ItemPredicate
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.InteractionHand
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import kotlin.collections.iterator
|
||||
|
||||
/**
|
||||
* An [OwnerQueryRequirement] that checks if the player/npc is holding a certain [ItemPredicate]
|
||||
@@ -28,7 +30,7 @@ class OwnerHoldsItemRequirement(val itemCondition: ItemPredicate)
|
||||
|
||||
override fun checkPlayer(
|
||||
pokemon: Pokemon,
|
||||
owner: Player
|
||||
owner: ServerPlayer
|
||||
): Boolean {
|
||||
return checkItem(owner)
|
||||
}
|
||||
|
||||
+8
-12
@@ -8,22 +8,22 @@
|
||||
|
||||
package com.cobblemon.mod.common.util.adapters
|
||||
|
||||
import com.google.gson.*
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSerializer
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.JsonOps
|
||||
import java.lang.reflect.Type
|
||||
|
||||
class CodecBackedAdapter<T>(val codec: Codec<T>) : JsonDeserializer<T>, JsonSerializer<T> {
|
||||
|
||||
override fun deserialize(
|
||||
jElement: JsonElement,
|
||||
typeOfT: Type,
|
||||
context: JsonDeserializationContext
|
||||
): T {
|
||||
val ops = RegistryOpsProvider.getOpsWithDefaultFallback()
|
||||
val result = ops.withDecoder(codec).apply(jElement)
|
||||
return result.result().orElseThrow {
|
||||
IllegalStateException("Failed to deserialize $jElement: ${result.error().orElse(null)}")
|
||||
}.first
|
||||
return JsonOps.INSTANCE.withDecoder(codec).apply(jElement).result().get().first as T
|
||||
}
|
||||
|
||||
override fun serialize(
|
||||
@@ -31,10 +31,6 @@ class CodecBackedAdapter<T>(val codec: Codec<T>) : JsonDeserializer<T>, JsonSeri
|
||||
typeOfSrc: Type?,
|
||||
context: JsonSerializationContext?
|
||||
): JsonElement {
|
||||
val ops = RegistryOpsProvider.getOpsWithDefaultFallback()
|
||||
val result = ops.withEncoder(codec).apply(src)
|
||||
return result.result().orElseThrow {
|
||||
IllegalStateException("Failed to serialize $src: ${result.error().orElse(null)}")
|
||||
}
|
||||
return JsonOps.INSTANCE.withEncoder(codec).apply(src).result().get()
|
||||
}
|
||||
}
|
||||
@@ -1,41 +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.util.adapters
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.Environment
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import com.google.gson.JsonElement
|
||||
import com.mojang.serialization.DynamicOps
|
||||
import com.mojang.serialization.JsonOps
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.resources.RegistryOps
|
||||
|
||||
/**
|
||||
* Utility for obtaining RegistryOps with the correct client/server registry access.
|
||||
* Used when manually encoding/decoding registry-backed values (e.g., items, predicates).
|
||||
*/
|
||||
object RegistryOpsProvider {
|
||||
fun getOpsWithDefaultFallback(): DynamicOps<JsonElement> {
|
||||
if (Cobblemon.implementation.environment() == Environment.CLIENT) {
|
||||
val minecraft = Minecraft.getInstance()
|
||||
if (minecraft != null && minecraft.level != null)
|
||||
return RegistryOps.create(JsonOps.INSTANCE, minecraft.level!!.registryAccess())
|
||||
}
|
||||
|
||||
|
||||
if (Cobblemon.implementation.environment() == Environment.SERVER) {
|
||||
val server = server()
|
||||
if (server != null)
|
||||
return RegistryOps.create(JsonOps.INSTANCE, server.registryAccess())
|
||||
}
|
||||
|
||||
return JsonOps.INSTANCE
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"particle_effect": {
|
||||
"description": {
|
||||
"identifier": "cobblemon:mood_anger_steam",
|
||||
"basic_render_parameters": {
|
||||
"material": "particles_alpha",
|
||||
"texture": "textures/particles/mood/steam_center_double"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"veins": {
|
||||
"particle_effect": {
|
||||
"effect": "cobblemon:mood_anger_veins",
|
||||
"type": "emitter"
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:emitter_rate_instant": {
|
||||
"num_particles": 1
|
||||
},
|
||||
"minecraft:emitter_lifetime_looping": {
|
||||
"active_time": 1,
|
||||
"sleep_time": 0.25
|
||||
},
|
||||
"minecraft:emitter_lifetime_events": {
|
||||
"creation_event": "veins"
|
||||
},
|
||||
"minecraft:emitter_shape_point": {
|
||||
"offset": [0, "math.clamp((v.entity_radius*1.2),0.48,0.96)*0.75", 0]
|
||||
},
|
||||
"minecraft:particle_lifetime_expression": {
|
||||
"max_lifetime": 1
|
||||
},
|
||||
"minecraft:particle_initial_speed": 0,
|
||||
"minecraft:particle_motion_dynamic": {},
|
||||
"minecraft:particle_appearance_billboard": {
|
||||
"size": ["math.clamp((v.entity_radius*1.5),0.9,2.4)", "math.clamp((v.entity_radius*0.5),0.3,0.8)"],
|
||||
"facing_camera_mode": "rotate_xyz",
|
||||
"uv": {
|
||||
"texture_width": 48,
|
||||
"texture_height": 176,
|
||||
"flipbook": {
|
||||
"base_UV": [0, 0],
|
||||
"size_UV": [48, 16],
|
||||
"step_UV": [0, 16],
|
||||
"max_frame": 11,
|
||||
"stretch_to_lifetime": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"particle_effect": {
|
||||
"description": {
|
||||
"identifier": "cobblemon:mood_anger_veins",
|
||||
"basic_render_parameters": {
|
||||
"material": "particles_alpha",
|
||||
"texture": "textures/particles/mood/vein_red"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:emitter_initialization": {
|
||||
"creation_expression": "v.particle_size = math.clamp((v.entity_radius*0.75),0.15,0.4);"
|
||||
},
|
||||
"minecraft:emitter_rate_steady": {
|
||||
"spawn_rate": 1,
|
||||
"max_particles": 1
|
||||
},
|
||||
"minecraft:emitter_lifetime_looping": {
|
||||
"active_time": 1,
|
||||
"sleep_time": 0.25
|
||||
},
|
||||
"minecraft:emitter_shape_point": {
|
||||
"direction": ["math.random(-1,1)", 1.5, "math.random(-1,1)"]
|
||||
},
|
||||
"minecraft:particle_lifetime_expression": {
|
||||
"max_lifetime": 1.25
|
||||
},
|
||||
"minecraft:particle_initial_spin": {
|
||||
"rotation": "math.random_integer(-1,2)*90"
|
||||
},
|
||||
"minecraft:particle_initial_speed": "v.particle_size*13",
|
||||
"minecraft:particle_motion_dynamic": {
|
||||
"linear_acceleration": [0, 0.75, 0],
|
||||
"linear_drag_coefficient": "v.particle_size*15"
|
||||
},
|
||||
"minecraft:particle_appearance_billboard": {
|
||||
"size": ["math.clamp((v.entity_radius*0.75),0.15,0.3)", "math.clamp((v.entity_radius*0.75),0.15,0.3)"],
|
||||
"facing_camera_mode": "rotate_xyz",
|
||||
"uv": {
|
||||
"texture_width": 22,
|
||||
"texture_height": 11,
|
||||
"flipbook": {
|
||||
"base_UV": [0, 0],
|
||||
"size_UV": [11, 11],
|
||||
"step_UV": [11, 0],
|
||||
"frames_per_second": 6,
|
||||
"max_frame": 2,
|
||||
"loop": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:particle_motion_collision": {},
|
||||
"minecraft:particle_appearance_lighting": {},
|
||||
"minecraft:particle_appearance_tinting": {
|
||||
"color": {
|
||||
"interpolant": "v.particle_age/v.particle_lifetime",
|
||||
"gradient": {
|
||||
"0.86": "#ffffffff",
|
||||
"1.0": "#FF000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"particle_effect": {
|
||||
"description": {
|
||||
"identifier": "cobblemon:mood_annoyed",
|
||||
"basic_render_parameters": {
|
||||
"material": "particles_alpha",
|
||||
"texture": "textures/particles/mood/scribble_purple"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:emitter_initialization": {
|
||||
"creation_expression": "v.particle_size = math.clamp((v.entity_radius*0.75),0.2,0.5);"
|
||||
},
|
||||
"minecraft:emitter_rate_instant": {
|
||||
"num_particles": 1
|
||||
},
|
||||
"minecraft:emitter_lifetime_once": {
|
||||
"active_time": 2
|
||||
},
|
||||
"minecraft:emitter_shape_point": {
|
||||
"direction": [0, 1, 0]
|
||||
},
|
||||
"minecraft:particle_lifetime_expression": {
|
||||
"max_lifetime": 1
|
||||
},
|
||||
"minecraft:particle_initial_speed": "v.particle_size*10",
|
||||
"minecraft:particle_motion_dynamic": {
|
||||
"linear_drag_coefficient": 3
|
||||
},
|
||||
"minecraft:particle_appearance_billboard": {
|
||||
"size": ["math.clamp((v.entity_radius*0.75),0.2,0.5)", "math.clamp((v.entity_radius*0.75),0.2,0.5)"],
|
||||
"facing_camera_mode": "rotate_xyz",
|
||||
"uv": {
|
||||
"texture_width": 168,
|
||||
"texture_height": 14,
|
||||
"flipbook": {
|
||||
"base_UV": [0, 0],
|
||||
"size_UV": [14, 14],
|
||||
"step_UV": [14, 0],
|
||||
"frames_per_second": 10,
|
||||
"max_frame": 12
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:particle_appearance_lighting": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"particle_effect": {
|
||||
"description": {
|
||||
"identifier": "cobblemon:mood_stress",
|
||||
"basic_render_parameters": {
|
||||
"material": "particles_alpha",
|
||||
"texture": "textures/particles/mood/sweat_blue"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:emitter_initialization": {
|
||||
"creation_expression": "v.particle_height = math.clamp((v.entity_radius*1.2),0.48,0.96);"
|
||||
},
|
||||
"minecraft:emitter_rate_instant": {
|
||||
"num_particles": 1
|
||||
},
|
||||
"minecraft:emitter_lifetime_looping": {
|
||||
"active_time": 1
|
||||
},
|
||||
"minecraft:emitter_shape_point": {
|
||||
"offset": [0, "math.clamp((v.entity_radius*1.2),0.48,0.96)*0.75", 0]
|
||||
},
|
||||
"minecraft:particle_lifetime_expression": {
|
||||
"max_lifetime": 0.45
|
||||
},
|
||||
"minecraft:particle_initial_speed": 0,
|
||||
"minecraft:particle_motion_dynamic": {},
|
||||
"minecraft:particle_appearance_billboard": {
|
||||
"size": ["math.clamp((v.entity_radius*1.2),0.48,0.96)", "math.clamp((v.entity_radius*0.65),0.26,0.52)"],
|
||||
"facing_camera_mode": "rotate_xyz",
|
||||
"uv": {
|
||||
"texture_width": 216,
|
||||
"texture_height": 13,
|
||||
"flipbook": {
|
||||
"base_UV": [0, 0],
|
||||
"size_UV": [24, 13],
|
||||
"step_UV": [24, 0],
|
||||
"max_frame": 9,
|
||||
"stretch_to_lifetime": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:particle_appearance_lighting": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
-5
@@ -297,11 +297,6 @@
|
||||
"1.0833": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"sound_effects": {
|
||||
"0.25": {
|
||||
"effect": "pokemon.ditto.cry"
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.ditto.blink": {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
"animations": {
|
||||
"animation.metagross.ground_idle": {
|
||||
"loop": true,
|
||||
"animation_length": 0,
|
||||
"animation_length": 11.4167,
|
||||
"bones": {
|
||||
"body2": {
|
||||
"position": [0, -11.9, 0]
|
||||
|
||||
-8
@@ -299,14 +299,6 @@
|
||||
"rotation": [0, 0, 15]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.eelektrik.cry": {
|
||||
"animation_length": 1.25,
|
||||
"sound_effects": {
|
||||
"0.0417": {
|
||||
"effect": "pokemon.eelektrik.cry"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-8
@@ -869,14 +869,6 @@
|
||||
"position": [-0.1, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.eelektross.cry": {
|
||||
"animation_length": 1.25,
|
||||
"sound_effects": {
|
||||
"0.0417": {
|
||||
"effect": "pokemon.eelektross.cry"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+149
-357
@@ -84,7 +84,7 @@
|
||||
"position": [0, "0+Math.cos((query.anim_time) * 90 * 8 - 60) * -0.1", 0]
|
||||
},
|
||||
"hair3": {
|
||||
"rotation": ["-2+Math.cos((query.anim_time) * 90 * 8 - 100) * 3", 0, 0]
|
||||
"rotation": ["0+Math.cos((query.anim_time) * 90 * 8 - 100) * 3", 0, 0]
|
||||
},
|
||||
"hair": {
|
||||
"rotation": ["0+Math.cos((query.anim_time) * 90 * 8 - 120) * 10", 12.5, "0+Math.cos((query.anim_time) * 90 * 4 - 180) * 10"]
|
||||
@@ -356,7 +356,7 @@
|
||||
"position": [-1.63659, -1.07651, 3.16823]
|
||||
},
|
||||
"arm_right": {
|
||||
"rotation": [-99.86576, -52.80463, 0.06108]
|
||||
"rotation": [-80.89079, -82.69097, -6.55875]
|
||||
},
|
||||
"finger_right": {
|
||||
"rotation": [0, 0, 17.5]
|
||||
@@ -375,21 +375,6 @@
|
||||
},
|
||||
"arm_hammer_left": {
|
||||
"rotation": [-85, 100, 0]
|
||||
},
|
||||
"hand_right": {
|
||||
"rotation": [0, 0, -22.5]
|
||||
},
|
||||
"brow_right": {
|
||||
"position": [0, -0.75, 0]
|
||||
},
|
||||
"brow_left": {
|
||||
"position": [0, -0.75, 0]
|
||||
},
|
||||
"eyes_ditto": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"eyes_blink_ditto": {
|
||||
"position": [0, 0, -0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -475,26 +460,40 @@
|
||||
"1.875": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.375": [0, 0, 0],
|
||||
"0.4167": [0, 0, -0.125],
|
||||
"0.625": [0, 0, -0.125],
|
||||
"0.6667": [0, 0, 0],
|
||||
"0.8333": [0, 0, 0],
|
||||
"0.875": [0, 0, -0.125],
|
||||
"1.5833": [0, 0, -0.125],
|
||||
"1.625": [0, 0, 0],
|
||||
"1.7083": [0, 0, 0],
|
||||
"1.75": [0, 0, -0.125]
|
||||
}
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.375": [0, 0, 0],
|
||||
"0.4167": [0, 0, -0.1],
|
||||
"0.625": [0, 0, -0.1],
|
||||
"0.4167": [0, 0, -0.125],
|
||||
"0.625": [0, 0, -0.125],
|
||||
"0.6667": [0, 0, 0],
|
||||
"0.8333": [0, 0, 0],
|
||||
"0.875": [0, 0, -0.1],
|
||||
"1.5833": [0, 0, -0.1],
|
||||
"1.625": [0, 0, 1],
|
||||
"0.875": [0, 0, -0.125],
|
||||
"1.5833": [0, 0, -0.125],
|
||||
"1.625": [0, 0, 0],
|
||||
"1.7083": [0, 0, 0],
|
||||
"1.75": [0, 0, -0.1]
|
||||
"1.75": [0, 0, -0.125]
|
||||
}
|
||||
},
|
||||
"mouth_open_cry": {
|
||||
"mouth_open": {
|
||||
"position": {
|
||||
"0.8333": [0, 0, 0],
|
||||
"0.875": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"1.875": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
|
||||
"1.9167": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.875": [0, 0, -0.125],
|
||||
"1.875": [0, 0, -0.125],
|
||||
"1.9167": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"arm_left": {
|
||||
@@ -557,6 +556,13 @@
|
||||
"1.75": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"eye_right": {
|
||||
"scale": {
|
||||
"1.5833": [1, 1, 1],
|
||||
"1.625": [1.4, 1.4, 3.3],
|
||||
"1.7083": [1, 1, 1]
|
||||
}
|
||||
},
|
||||
"eye_left": {
|
||||
"scale": {
|
||||
"1.5833": [1, 1, 1],
|
||||
@@ -716,55 +722,6 @@
|
||||
"1.7083": [1, 1, 1]
|
||||
}
|
||||
},
|
||||
"leg_left": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.2917": [0, -20, -2.5],
|
||||
"0.4167": [-5.68, -13.75, -2.5],
|
||||
"0.5833": [-32.36, -7.5, -2.5],
|
||||
"0.7083": [-40.5, 2.5, -2.5],
|
||||
"0.75": [-33.83, 2.5, -2.5],
|
||||
"0.8333": [-30.5, 2.5, -2.5]
|
||||
},
|
||||
"position": {
|
||||
"0.4167": [0, 0, 0],
|
||||
"0.5833": [0, 0, -0.75],
|
||||
"1.5833": [0, 0, -0.75],
|
||||
"1.625": [1.25, 0, -0.75],
|
||||
"1.75": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"arm_hammer_left": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 17.5],
|
||||
"0.25": [0, -25, 5],
|
||||
"0.4167": [0, -32.5, 3.5],
|
||||
"0.5": [-11.25, 40.75, -16.75],
|
||||
"0.5833": [-22.5, 46.75, -37],
|
||||
"0.7083": [-25, 44, -40.75]
|
||||
}
|
||||
},
|
||||
"eye_right": {
|
||||
"scale": {
|
||||
"1.5833": [1, 1, 1],
|
||||
"1.625": [1.4, 1.4, 3.3],
|
||||
"1.7083": [1, 1, 1]
|
||||
}
|
||||
},
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.375": [0, 0, 0],
|
||||
"0.4167": [0, 0, -0.1],
|
||||
"0.625": [0, 0, -0.1],
|
||||
"0.6667": [0, 0, 0],
|
||||
"0.8333": [0, 0, 0],
|
||||
"0.875": [0, 0, -0.1],
|
||||
"1.5833": [0, 0, -0.1],
|
||||
"1.625": [0, 0, 1],
|
||||
"1.7083": [0, 0, 0],
|
||||
"1.75": [0, 0, -0.1]
|
||||
}
|
||||
},
|
||||
"arm_right": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, -20],
|
||||
@@ -796,6 +753,24 @@
|
||||
"finger_right3": {
|
||||
"rotation": [0, 0, -22.5]
|
||||
},
|
||||
"leg_left": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.2917": [0, -20, -2.5],
|
||||
"0.4167": [-5.68, -13.75, -2.5],
|
||||
"0.5833": [-32.36, -7.5, -2.5],
|
||||
"0.7083": [-40.5, 2.5, -2.5],
|
||||
"0.75": [-33.83, 2.5, -2.5],
|
||||
"0.8333": [-30.5, 2.5, -2.5]
|
||||
},
|
||||
"position": {
|
||||
"0.4167": [0, 0, 0],
|
||||
"0.5833": [0, 0, -0.75],
|
||||
"1.5833": [0, 0, -0.75],
|
||||
"1.625": [1.25, 0, -0.75],
|
||||
"1.75": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"leg_right": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
@@ -814,146 +789,33 @@
|
||||
"1.75": [-0.5, 0, 0]
|
||||
}
|
||||
},
|
||||
"brow_left": {
|
||||
"position": {
|
||||
"0.375": [0, 0, 0],
|
||||
"0.4167": [0, -0.75, 0],
|
||||
"0.625": [0, -0.75, 0],
|
||||
"0.6667": [0, 0, 0],
|
||||
"0.8333": [0, 0, 0],
|
||||
"0.875": [0, -0.75, 0],
|
||||
"1.5833": [0, -0.75, 0],
|
||||
"1.625": [0, 0, 0],
|
||||
"1.7083": [0, 0, 0],
|
||||
"1.75": [0, -0.75, 0]
|
||||
}
|
||||
},
|
||||
"brow_right": {
|
||||
"position": {
|
||||
"0.375": [0, 0, 0],
|
||||
"0.4167": [0, -0.75, 0],
|
||||
"0.625": [0, -0.75, 0],
|
||||
"0.6667": [0, 0, 0],
|
||||
"0.8333": [0, 0, 0],
|
||||
"0.875": [0, -0.75, 0],
|
||||
"1.5833": [0, -0.75, 0],
|
||||
"1.625": [0, 0, 0],
|
||||
"1.7083": [0, 0, 0],
|
||||
"1.75": [0, -0.75, 0]
|
||||
}
|
||||
},
|
||||
"mouth_closed": {
|
||||
"position": {
|
||||
"0.8333": [0, 0, 0],
|
||||
"0.875": {"pre": [0, 0, 0], "post": [0, -0.5, 0]},
|
||||
"1.875": {"pre": [0, -0.5, 0], "post": [0, -0.5, 0]},
|
||||
"1.9167": {"pre": [0, -0.5, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"mouth_lip_top": {
|
||||
"position": {
|
||||
"0.8333": [0, 0, 0],
|
||||
"0.875": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
|
||||
"1.875": {"pre": [0, 0, 0.1], "post": [0, 0, 0.1]},
|
||||
"1.9167": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyes_ditto": {
|
||||
"position": {
|
||||
"0.375": [0, 0, 0],
|
||||
"0.4167": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
|
||||
"0.625": {"pre": [0, 0, 0.1], "post": [0, 0, 0.1]},
|
||||
"0.6667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
|
||||
"0.8333": {"pre": [0, 0, 0], "post": [0, 0, 0]},
|
||||
"0.875": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
|
||||
"1.5833": {"pre": [0, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.75": {"pre": [0, 0, 0], "post": [0, 0, 0.1]}
|
||||
},
|
||||
"scale": {
|
||||
"1.5833": [1, 1, 1],
|
||||
"1.625": [1.4, 1.4, 3.3],
|
||||
"1.7083": [1, 1, 1]
|
||||
}
|
||||
},
|
||||
"eyes_blink_ditto": {
|
||||
"position": {
|
||||
"0.375": [0, 0, 0],
|
||||
"0.4167": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"0.625": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
|
||||
"0.6667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
|
||||
"0.8333": {"pre": [0, 0, 0], "post": [0, 0, 0]},
|
||||
"0.875": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"1.5833": {"pre": [0, 0, -0.1], "post": [0, 0, 0]},
|
||||
"1.75": {"pre": [0, 0, 0], "post": [0, 0, -0.1]}
|
||||
}
|
||||
},
|
||||
"mouth_ditto": {
|
||||
"position": {
|
||||
"0.8333": [0, 0, 0],
|
||||
"0.875": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
|
||||
"1.875": {"pre": [0, 0, 0.1], "post": [0, 0, 0.1]},
|
||||
"1.9167": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"mouth_open_ditto": {
|
||||
"position": {
|
||||
"0.8333": [0, 0, 0],
|
||||
"0.875": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"1.875": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
|
||||
"1.9167": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"arm_hammer_left": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 17.5],
|
||||
"0.25": [0, -25, 5],
|
||||
"0.4167": [0, -32.5, 3.5],
|
||||
"0.5": [-11.25, 40.75, -16.75],
|
||||
"0.5833": [-22.5, 46.75, -37],
|
||||
"0.7083": [-25, 44, -40.75]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatink.blink": {
|
||||
"animation_length": 0.1667,
|
||||
"animation_length": 0.16667,
|
||||
"bones": {
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, -0.1],
|
||||
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.125": [0, 0, -0.1],
|
||||
"0.1667": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, -0.1],
|
||||
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"brow_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"brow_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eye_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eye_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyes_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.1667": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyes_blink_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, -0.1],
|
||||
"0.1667": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.125": [0, 0, -0.1],
|
||||
"0.1667": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -961,6 +823,38 @@
|
||||
"animation.tinkatink.cry": {
|
||||
"animation_length": 1.5,
|
||||
"bones": {
|
||||
"neck": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": [10, 0, 0],
|
||||
"1.25": [10, 0, 0],
|
||||
"1.5": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"mouth": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": [0, -2, 0],
|
||||
"1.25": [0, -2, 0],
|
||||
"1.5": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"mouth2": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": [0, -5, 0],
|
||||
"1.25": [0, -5, 0],
|
||||
"1.5": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"jaw": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": [0, -3, 0],
|
||||
"1.25": [0, -3, 0],
|
||||
"1.5": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"head": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
@@ -969,12 +863,60 @@
|
||||
"1.5": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"mouth_open_cry": {
|
||||
"head2": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": [-15, 0, 0],
|
||||
"1.25": [-15, 0, 0],
|
||||
"1.5": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"mouth_closed2": {
|
||||
"position": {
|
||||
"0.25": [0, 0, -0.1],
|
||||
"0.3333": [0, 0, 0],
|
||||
"1.1667": [0, 0, 0],
|
||||
"1.25": [0, 0, -0.1]
|
||||
}
|
||||
},
|
||||
"mouth_open2": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.25": [0, 0, 0],
|
||||
"1.25": [0, 0, 0],
|
||||
"1.5": [0, 0, 0.1]
|
||||
}
|
||||
},
|
||||
"head3": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": [-15, 0, 0],
|
||||
"1.25": [-15, 0, 0],
|
||||
"1.5": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"mouth_closed3": {
|
||||
"position": {
|
||||
"0.25": [0, 0, -0.1],
|
||||
"0.3333": [0, 0, 0],
|
||||
"1.1667": [0, 0, 0],
|
||||
"1.25": [0, 0, -0.1]
|
||||
}
|
||||
},
|
||||
"mouth_open3": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.25": [0, 0, 0],
|
||||
"1.25": [0, 0, 0],
|
||||
"1.5": [0, 0, 0.1]
|
||||
}
|
||||
},
|
||||
"mouth_open": {
|
||||
"position": {
|
||||
"0.0833": [0, 0, 0],
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"1.25": {"pre": [0, 0, -0.1], "post": [0, 0, -0.1]},
|
||||
"1.3333": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
"0.1667": [0, 0, -0.15],
|
||||
"1.25": [0, 0, -0.15],
|
||||
"1.3333": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"arm_left": {
|
||||
@@ -1006,38 +948,10 @@
|
||||
"1.25": [0, 0, -2.4],
|
||||
"1.5": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"mouth_closed": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [0, -0.5, 0]},
|
||||
"1.3333": {"pre": [0, -0.5, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"mouth_lip_top": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
|
||||
"1.3333": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"mouth_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
|
||||
"1.3333": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"mouth_open_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"1.3333": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sound_effects": {
|
||||
"0.0": {
|
||||
"0.25": {
|
||||
"effect": "pokemon.tinkatink.cry"
|
||||
}
|
||||
}
|
||||
@@ -1148,128 +1062,6 @@
|
||||
"rotation": [0, 0, 32.5]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatink.ditto_face": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"face": {
|
||||
"position": [0, 0, 0.1],
|
||||
"scale": 0
|
||||
},
|
||||
"face_ditto": {
|
||||
"position": [0, 0, -0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatink.happy": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"brow_left": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"brow_right": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"eye_left": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"eye_right": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"mouth_closed": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"mouth_lip_top": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"mouth_open_happy": {
|
||||
"position": [0, 0, -0.1]
|
||||
},
|
||||
"eyelid_happy_left": {
|
||||
"position": [0, 0, -0.1]
|
||||
},
|
||||
"eyelid_happy_right": {
|
||||
"position": [0, 0, -0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatink.angry": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"eye_emote_left": {
|
||||
"scale": [1, 0.5, 1]
|
||||
},
|
||||
"eye_emote_right": {
|
||||
"scale": [1, 0.5, 1]
|
||||
},
|
||||
"eye_emote_left2": {
|
||||
"position": [0.25, 0, 0],
|
||||
"scale": [0.5, 1, 1]
|
||||
},
|
||||
"eye_emote_right2": {
|
||||
"position": [-0.25, 0, 0],
|
||||
"scale": [0.5, 1, 1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatink.very_sad": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"eye_emote_left": {
|
||||
"scale": [1, 0.5, 1]
|
||||
},
|
||||
"eye_emote_right": {
|
||||
"scale": [1, 0.5, 1]
|
||||
},
|
||||
"eye_emote_left2": {
|
||||
"position": [-0.25, 0, 0],
|
||||
"scale": [0.5, 1, 1]
|
||||
},
|
||||
"eye_emote_right2": {
|
||||
"position": [0.25, 0, 0],
|
||||
"scale": [0.5, 1, 1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatink.hurt": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"brow_left": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"brow_right": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"eye_left": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"eye_right": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"eyelid_hurt_left": {
|
||||
"position": [0, 0, -0.1]
|
||||
},
|
||||
"eyelid_hurt_right": {
|
||||
"position": [0, 0, -0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatink.disinterested": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"eye_emote_left": {
|
||||
"scale": [1, 0.5, 1]
|
||||
},
|
||||
"eye_emote_right": {
|
||||
"scale": [1, 0.5, 1]
|
||||
},
|
||||
"eye_emote_left2": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"eye_emote_right2": {
|
||||
"position": [0, 0, 0.1]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+199
-532
@@ -4,6 +4,12 @@
|
||||
"animation.tinkatuff.ground_idle": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"tail": {
|
||||
"rotation": [12.5, 0, 0]
|
||||
},
|
||||
"tail2": {
|
||||
"rotation": [12.5, 0, 0]
|
||||
},
|
||||
"arm_right": {
|
||||
"rotation": [55.98303, 0.22836, "-40.7651+Math.cos((query.anim_time) * 90 * 2 - 120) * 1"],
|
||||
"position": [-0.25, -0.5, 0]
|
||||
@@ -15,8 +21,7 @@
|
||||
"rotation": [0, 0, -5]
|
||||
},
|
||||
"finger_right2": {
|
||||
"rotation": [0, -17.5, 37.5],
|
||||
"position": [-0.25, 0, 0]
|
||||
"rotation": [0, -10, 37.5]
|
||||
},
|
||||
"arm_left": {
|
||||
"rotation": [-84.39003, 4.58778, "53.5046+Math.cos((query.anim_time) * 90 * 2 - 120) * 1"]
|
||||
@@ -25,11 +30,17 @@
|
||||
"rotation": [0, -15, 55]
|
||||
},
|
||||
"finger_left": {
|
||||
"rotation": [0, 0, -40]
|
||||
"rotation": [0, 0, -25]
|
||||
},
|
||||
"finger_left2": {
|
||||
"rotation": [20, 0, 0]
|
||||
},
|
||||
"hand_left": {
|
||||
"rotation": [0, 17.5, 0]
|
||||
},
|
||||
"hand_right": {
|
||||
"rotation": [0, -17.5, 0]
|
||||
},
|
||||
"leg_left": {
|
||||
"rotation": [0, -12.5, -5]
|
||||
},
|
||||
@@ -37,7 +48,7 @@
|
||||
"rotation": [0, 12.5, 5]
|
||||
},
|
||||
"finger_left3": {
|
||||
"rotation": [0, 0, 67.5]
|
||||
"rotation": [0, 0, 57.5]
|
||||
},
|
||||
"finger_right3": {
|
||||
"rotation": [0, 0, -20]
|
||||
@@ -67,6 +78,9 @@
|
||||
"head": {
|
||||
"rotation": ["12.5+Math.cos((query.anim_time) * 90 * 2 - 50) * 2", 0, 0]
|
||||
},
|
||||
"mouth_closed": {
|
||||
"position": [0, 0, 0]
|
||||
},
|
||||
"ponytail": {
|
||||
"rotation": ["0+Math.cos((query.anim_time) * 90 * 2 - 120) * 1", 0, 0]
|
||||
},
|
||||
@@ -173,24 +187,10 @@
|
||||
}
|
||||
},
|
||||
"finger_right2": {
|
||||
"rotation": [7.5, 0, 42.5],
|
||||
"position": [-0.25, 0.25, 0]
|
||||
"rotation": [7.5, 0, 10]
|
||||
},
|
||||
"finger_right3": {
|
||||
"rotation": [-0.88045, -9.96156, 5.07673]
|
||||
},
|
||||
"finger_left": {
|
||||
"rotation": [0, 0, -55],
|
||||
"position": [0, 0.5, 0]
|
||||
},
|
||||
"finger_left2": {
|
||||
"rotation": [0, 0, -17.5]
|
||||
},
|
||||
"finger_left3": {
|
||||
"rotation": [0, 0, 22.5]
|
||||
},
|
||||
"finger_right": {
|
||||
"rotation": [0, 0, 20]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -210,7 +210,7 @@
|
||||
"rotation": [-15, -2.5, 62.5]
|
||||
},
|
||||
"finger_left3": {
|
||||
"rotation": [0, 0, 22.5]
|
||||
"rotation": [0, 0, 52.5]
|
||||
},
|
||||
"arm_right": {
|
||||
"rotation": [22.5, -10, -35],
|
||||
@@ -299,29 +299,18 @@
|
||||
},
|
||||
"arm_hammer_right2": {
|
||||
"rotation": [0, -70, 0]
|
||||
},
|
||||
"finger_left": {
|
||||
"rotation": [0, 0, -52.5],
|
||||
"position": [0, 0.75, 0]
|
||||
},
|
||||
"finger_left2": {
|
||||
"rotation": [0, 0, -15]
|
||||
},
|
||||
"finger_right": {
|
||||
"rotation": [0, 0, 20]
|
||||
},
|
||||
"finger_right2": {
|
||||
"rotation": [7.5, 0, 37.5],
|
||||
"position": [-0.25, 0.25, 0]
|
||||
},
|
||||
"finger_right3": {
|
||||
"rotation": [0, 0, -32.5]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatuff.battle_idle": {
|
||||
"loop": true,
|
||||
"bones": {
|
||||
"tail": {
|
||||
"rotation": [12.5, 0, 0]
|
||||
},
|
||||
"tail2": {
|
||||
"rotation": [12.5, 0, 0]
|
||||
},
|
||||
"arm_right": {
|
||||
"rotation": [40.98303, 0.22836, "-45.7651+Math.cos((query.anim_time) * 90 * 2 - 40) * 2"]
|
||||
},
|
||||
@@ -329,8 +318,7 @@
|
||||
"rotation": [0, -52.5, 0]
|
||||
},
|
||||
"finger_right": {
|
||||
"rotation": [0, 0, 37.5],
|
||||
"position": [0, 0.25, 0]
|
||||
"rotation": [0, 0, -5]
|
||||
},
|
||||
"finger_right2": {
|
||||
"rotation": [0, 0, 37.5]
|
||||
@@ -342,12 +330,17 @@
|
||||
"rotation": [0, 0, "55+Math.cos((query.anim_time) * 90 * 2 - 40) * -2"]
|
||||
},
|
||||
"finger_left": {
|
||||
"rotation": [0, 0, -47.5],
|
||||
"position": [0, 0.5, 0]
|
||||
"rotation": [0, 0, -25]
|
||||
},
|
||||
"finger_left2": {
|
||||
"rotation": [20, 0, 0]
|
||||
},
|
||||
"hand_left": {
|
||||
"rotation": [0, 17.5, 0]
|
||||
},
|
||||
"hand_right": {
|
||||
"rotation": [0, -17.5, 0]
|
||||
},
|
||||
"leg_left": {
|
||||
"rotation": ["-11.2025+Math.cos((query.anim_time) * 90 * 2) * 3", -21.49336, -9.33448]
|
||||
},
|
||||
@@ -355,11 +348,10 @@
|
||||
"rotation": ["-13.5954+Math.cos((query.anim_time) * 90 * 2) * 3", 22.38126, 10.45107]
|
||||
},
|
||||
"finger_left3": {
|
||||
"rotation": [0, 0, 42.5],
|
||||
"position": [-0.5, -0.25, 0]
|
||||
"rotation": [0, 0, 57.5]
|
||||
},
|
||||
"finger_right3": {
|
||||
"rotation": [0, 0, -40]
|
||||
"rotation": [0, 0, -20]
|
||||
},
|
||||
"hammer": {
|
||||
"rotation": [-12.18122, -2.58318, 113.79667]
|
||||
@@ -424,8 +416,7 @@
|
||||
"position": [-0.5, 0, 0]
|
||||
},
|
||||
"hammer": {
|
||||
"rotation": [15, 0, 0],
|
||||
"position": [0, 0.5, 3.75]
|
||||
"rotation": [15, 0, 0]
|
||||
},
|
||||
"hammer2": {
|
||||
"rotation": ["90+Math.cos((query.anim_time) * 90 * 1) * -1", 0, 0],
|
||||
@@ -465,18 +456,43 @@
|
||||
},
|
||||
"leg_right": {
|
||||
"rotation": [-90, 20, 0]
|
||||
},
|
||||
"eyes_ditto": {
|
||||
"position": [0, 0, 0.1]
|
||||
},
|
||||
"eyes_blink_ditto": {
|
||||
"position": [0, 0, -0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatuff.faint": {
|
||||
"animation_length": 3,
|
||||
"bones": {
|
||||
"arm_right": {
|
||||
"rotation": {
|
||||
"0.0": [40.98303, 0.22836, -45.7651],
|
||||
"0.2083": [5.98, 0.23, -45.77],
|
||||
"0.2917": [35.98, 0.23, -45.77],
|
||||
"0.75": [18.48, 5.23, -23.27],
|
||||
"0.9167": [60.98, -12.27, -35.77],
|
||||
"1.2083": [30.98, -59.77, -35.77],
|
||||
"1.3333": [32.05, -62.98, -35.77],
|
||||
"1.5": [33.48, -67.27, -35.77],
|
||||
"1.8333": [15.98, -79.77, -35.77],
|
||||
"1.9167": [67.65, -129.77, -110.77],
|
||||
"1.9583": [93.48, -154.77, -148.27],
|
||||
"2.0833": [93.48, -174.77, -168.27],
|
||||
"2.3333": [93.48, -169.77, -168.27]
|
||||
}
|
||||
},
|
||||
"arm_right2": {
|
||||
"rotation": {
|
||||
"0.0": [0, -52.5, 0],
|
||||
"1.0": [0, -52.5, 0],
|
||||
"1.2083": [0, -57.5, 0],
|
||||
"1.5": [0, -30, 0]
|
||||
}
|
||||
},
|
||||
"finger_right": {
|
||||
"rotation": [0, 0, -5]
|
||||
},
|
||||
"finger_right2": {
|
||||
"rotation": [0, 0, 37.5]
|
||||
},
|
||||
"arm_left": {
|
||||
"rotation": {
|
||||
"0.0": [-84.39003, 24.58778, 53.5046],
|
||||
@@ -531,9 +547,30 @@
|
||||
"2.375": [-30.37, 0, -5]
|
||||
}
|
||||
},
|
||||
"leg_right": {
|
||||
"rotation": {
|
||||
"0.0": [-13.6, 22.38, 10.45],
|
||||
"0.1667": [-31.1, 22.38, 10.45],
|
||||
"0.25": [-26.1, 22.38, 10.45],
|
||||
"0.5": [-3.6, 22.38, 10.45],
|
||||
"0.7917": [6.4, 22.38, 10.45],
|
||||
"0.9167": [-31.1, 22.38, 10.45],
|
||||
"1.2083": [-31.1, 42.38, 10.45],
|
||||
"1.375": [-30, 0, 0],
|
||||
"1.6667": [-30, 0, 5],
|
||||
"1.875": [70, 0, 5],
|
||||
"2.0417": [40.36, 0, 5],
|
||||
"2.1667": [-30, 0, 5],
|
||||
"2.25": [-45, 0, 5],
|
||||
"2.375": [-35, 0, 5]
|
||||
}
|
||||
},
|
||||
"finger_left3": {
|
||||
"rotation": [0, 0, 57.5]
|
||||
},
|
||||
"finger_right3": {
|
||||
"rotation": [0, 0, -20]
|
||||
},
|
||||
"hammer": {
|
||||
"rotation": {
|
||||
"0.0": [-0.78, -6.26, 38.97],
|
||||
@@ -556,6 +593,9 @@
|
||||
"skirt_left": {
|
||||
"rotation": [0, 0, -15]
|
||||
},
|
||||
"skirt_right": {
|
||||
"rotation": [-10, 0, 15]
|
||||
},
|
||||
"leg_left2": {
|
||||
"rotation": {
|
||||
"0.0": [20, 0, 0],
|
||||
@@ -571,6 +611,18 @@
|
||||
"2.0417": [15, 0, 0]
|
||||
}
|
||||
},
|
||||
"leg_right2": {
|
||||
"rotation": {
|
||||
"0.0": [15, 0, -10],
|
||||
"0.1667": [35, 0, -10],
|
||||
"0.25": [-10, 0, -10],
|
||||
"0.5": [27.5, 0, 5],
|
||||
"0.7917": [5, 0, 5],
|
||||
"0.9167": [35, 0, 5],
|
||||
"1.375": [35, 0, 0],
|
||||
"1.6667": [22.5, 0, 0]
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"rotation": {
|
||||
"0.9167": [0, 0, 0],
|
||||
@@ -799,517 +851,132 @@
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"0.4167": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"0.9583": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"1.7917": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mouth_top": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0.5, 0]
|
||||
},
|
||||
"0.9167": {
|
||||
"pre": [0, 0.5, 0],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.2917": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0.5, 0]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0.5, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.2083": [0, 0, 0],
|
||||
"0.25": [0, 0, -0.15],
|
||||
"0.375": [0, 0, -0.15],
|
||||
"0.4167": [0, 0, 0],
|
||||
"0.9167": [0, 0, 0],
|
||||
"0.9583": [0, 0, -0.15],
|
||||
"1.75": [0, 0, -0.15],
|
||||
"1.7917": [0, 0, 0],
|
||||
"2.0": [0, 0, 0],
|
||||
"2.0417": [0, 0, -0.15]
|
||||
}
|
||||
},
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"0.4167": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"0.9583": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"1.7917": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
}
|
||||
"0.2083": [0, 0, 0],
|
||||
"0.25": [0, 0, -0.15],
|
||||
"0.375": [0, 0, -0.15],
|
||||
"0.4167": [0, 0, 0],
|
||||
"0.9167": [0, 0, 0],
|
||||
"0.9583": [0, 0, -0.15],
|
||||
"1.75": [0, 0, -0.15],
|
||||
"1.7917": [0, 0, 0],
|
||||
"2.0": [0, 0, 0],
|
||||
"2.0417": [0, 0, -0.15]
|
||||
}
|
||||
},
|
||||
"mouth_open": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"0.9167": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.2917": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.2083": [0, 0, 0],
|
||||
"0.25": [0, 0, -0.15],
|
||||
"0.875": [0, 0, -0.15],
|
||||
"0.9167": [0, 0, 0],
|
||||
"1.25": [0, 0, 0],
|
||||
"1.2917": [0, 0, -0.15],
|
||||
"2.0": [0, 0, -0.15],
|
||||
"2.0417": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"arm_right": {
|
||||
"rotation": {
|
||||
"0.0": [40.98303, 0.22836, -45.7651],
|
||||
"0.2083": [5.98, 0.23, -45.77],
|
||||
"0.2917": [35.98, 0.23, -45.77],
|
||||
"0.75": [18.48, 5.23, -23.27],
|
||||
"0.9167": [60.98, -12.27, -35.77],
|
||||
"1.2083": [30.98, -59.77, -35.77],
|
||||
"1.3333": [32.05, -62.98, -35.77],
|
||||
"1.5": [33.48, -67.27, -35.77],
|
||||
"1.8333": [15.98, -79.77, -35.77],
|
||||
"1.9167": [67.65, -129.77, -110.77],
|
||||
"1.9583": [93.48, -154.77, -148.27],
|
||||
"2.0833": [93.48, -174.77, -168.27],
|
||||
"2.3333": [93.48, -169.77, -168.27]
|
||||
}
|
||||
},
|
||||
"arm_right2": {
|
||||
"rotation": {
|
||||
"0.0": [0, -52.5, 0],
|
||||
"1.0": [0, -52.5, 0],
|
||||
"1.2083": [0, -57.5, 0],
|
||||
"1.5": [0, -30, 0]
|
||||
}
|
||||
},
|
||||
"finger_right": {
|
||||
"rotation": [0, 0, -5]
|
||||
},
|
||||
"finger_right2": {
|
||||
"rotation": [0, 0, 37.5]
|
||||
},
|
||||
"finger_right3": {
|
||||
"rotation": [0, 0, -20]
|
||||
},
|
||||
"skirt_right": {
|
||||
"rotation": [-10, 0, 15]
|
||||
},
|
||||
"leg_right": {
|
||||
"rotation": {
|
||||
"0.0": [-13.6, 22.38, 10.45],
|
||||
"0.1667": [-31.1, 22.38, 10.45],
|
||||
"0.25": [-26.1, 22.38, 10.45],
|
||||
"0.5": [-3.6, 22.38, 10.45],
|
||||
"0.7917": [6.4, 22.38, 10.45],
|
||||
"0.9167": [-31.1, 22.38, 10.45],
|
||||
"1.2083": [-31.1, 42.38, 10.45],
|
||||
"1.375": [-30, 0, 0],
|
||||
"1.6667": [-30, 0, 5],
|
||||
"1.875": [70, 0, 5],
|
||||
"2.0417": [40.36, 0, 5],
|
||||
"2.1667": [-30, 0, 5],
|
||||
"2.25": [-45, 0, 5],
|
||||
"2.375": [-35, 0, 5]
|
||||
}
|
||||
},
|
||||
"leg_right2": {
|
||||
"rotation": {
|
||||
"0.0": [15, 0, -10],
|
||||
"0.1667": [35, 0, -10],
|
||||
"0.25": [-10, 0, -10],
|
||||
"0.5": [27.5, 0, 5],
|
||||
"0.7917": [5, 0, 5],
|
||||
"0.9167": [35, 0, 5],
|
||||
"1.375": [35, 0, 0],
|
||||
"1.6667": [22.5, 0, 0]
|
||||
}
|
||||
},
|
||||
"brow_left": {
|
||||
"mouth_closed": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"0.4167": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"0.9583": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"1.7917": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
}
|
||||
"0.2083": [0, 0, 0],
|
||||
"0.25": [0, 0, 0.1],
|
||||
"0.875": [0, 0, 0.1],
|
||||
"0.9167": [0, 0, 0],
|
||||
"1.25": [0, 0, 0],
|
||||
"1.2917": [0, 0, 0.1],
|
||||
"2.0": [0, 0, 0.1],
|
||||
"2.0417": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"brow_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"0.4167": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"0.9583": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"1.7917": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mouth_bottom": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, -0.5, 0]
|
||||
},
|
||||
"0.9167": {
|
||||
"pre": [0, -0.5, 0],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.2917": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, -0.5, 0]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, -0.5, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eye_emote_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"0.4167": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"0.9583": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"1.7917": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eye_emote_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"0.4167": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"0.9583": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"1.7917": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyes_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"0.4167": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"0.9583": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"1.7917": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyes_blink_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"0.4167": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"0.9583": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"1.7917": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mouth_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"0.9167": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.2917": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0.1]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mouth_open_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"0.9167": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.2917": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, -0.1]
|
||||
},
|
||||
"2.0417": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatuff.cry": {
|
||||
"animation_length": 1.5,
|
||||
"bones": {
|
||||
"head": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": [-15, 0, 0],
|
||||
"1.25": [-15, 0, 0],
|
||||
"1.5": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"mouth_open": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"1.3333": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"mouth_top": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {"pre": [0, 0, 0], "post": [0, 0.5, 0]},
|
||||
"1.3333": {"pre": [0, 0.5, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"mouth_bottom": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {"pre": [0, 0, 0], "post": [0, -0.5, 0]},
|
||||
"1.3333": {"pre": [0, -0.5, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"mouth_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {"pre": [0, 0, 0], "post": [0, 0, 0.1]},
|
||||
"1.3333": {"pre": [0, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"mouth_open_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {"pre": [0, 0, 0], "post": [0, 0, -0.1]},
|
||||
"1.3333": {"pre": [0, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sound_effects": {
|
||||
"0.0": {
|
||||
"effect": "pokemon.tinkatuff.cry"
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatuff.blink": {
|
||||
"animation_length": 0.1667,
|
||||
"animation_length": 0.16667,
|
||||
"bones": {
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, -0.1],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.125": [0, 0, -0.1],
|
||||
"0.1667": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, -0.1],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"brow_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"brow_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eye_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eye_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyes_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0.1],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyes_blink_ditto": {
|
||||
"position": {
|
||||
"0.0": [0, 0, -0.1],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.125": [0, 0, -0.1],
|
||||
"0.1667": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"animation.tinkatuff.ditto_face": {
|
||||
"loop": true,
|
||||
"animation.tinkatuff.cry": {
|
||||
"animation_length": 0.91667,
|
||||
"bones": {
|
||||
"face": {
|
||||
"position": [0, 0, 0.1],
|
||||
"scale": 0
|
||||
"head": {
|
||||
"rotation": {
|
||||
"0.0": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": {
|
||||
"post": [-15, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [-15, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.9167": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"face_ditto": {
|
||||
"position": [0, 0, -0.1]
|
||||
"mouth_closed": {
|
||||
"position": {
|
||||
"0.25": [0, 0, 0],
|
||||
"0.3333": [0, 0, 0.1],
|
||||
"0.5833": [0, 0, 0.1],
|
||||
"0.6667": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
"mouth_open": {
|
||||
"position": {
|
||||
"0.0": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.25": {
|
||||
"post": [0, 0, -0.1],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.6667": {
|
||||
"post": [0, 0, -0.1],
|
||||
"lerp_mode": "catmullrom"
|
||||
},
|
||||
"0.9167": {
|
||||
"post": [0, 0, 0],
|
||||
"lerp_mode": "catmullrom"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sound_effects": {
|
||||
"0.1667": {
|
||||
"effect": "pokemon.tinkatuff.cry"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2080
-7209
File diff suppressed because it is too large.
Load diff
Loaded 100 of 297 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user