mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-11-02 14:28:54 -05:00
Compare commits
62
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b52b3d517 | ||
|
|
82b5d12f32 | ||
|
|
07c5d10f3d | ||
|
|
5ac50e0931 | ||
|
|
45079052de | ||
|
|
76a9feb7d9 | ||
|
|
33faecc517 | ||
|
|
205323d568 | ||
|
|
c6dfb77e47 | ||
|
|
2273e32d9f | ||
|
|
ed159cf9e5 | ||
|
|
d36f69b63d | ||
|
|
aa2eed1f60 | ||
|
|
7abb786157 | ||
|
|
488a89e3f1 | ||
|
|
093deb73fb | ||
|
|
792ce4d0cb | ||
|
|
fd004cc51b | ||
|
|
015c072a41 | ||
|
|
cb389f6cef | ||
|
|
3f1ff0503d | ||
|
|
fcf8c44aca | ||
|
|
c128a435c7 | ||
|
|
8bd20692f4 | ||
|
|
83c019f566 | ||
|
|
49047cac05 | ||
|
|
39c40bfebb | ||
|
|
beed33ccb0 | ||
|
|
4d8a6c8c12 | ||
|
|
ffd0ef499d | ||
|
|
56fd26d29e | ||
|
|
bc908a9a0a | ||
|
|
c5a7b4bc06 | ||
|
|
b4b55967bd | ||
|
|
ca52c578dd | ||
|
|
7d78a72925 | ||
|
|
f4cea63612 | ||
|
|
5b0c34ce9a | ||
|
|
37f70903c5 | ||
|
|
1149880926 | ||
|
|
42d569b4fa | ||
|
|
f1f1f183f1 | ||
|
|
c4fdb4c89e | ||
|
|
87510acd17 | ||
|
|
dc8821ed8d | ||
|
|
04478d7807 | ||
|
|
f708c1bddb | ||
|
|
97b7cf4bee | ||
|
|
0447ecded7 | ||
|
|
ab9e73d3ec | ||
|
|
d34a0d28aa | ||
|
|
d46627d24e | ||
|
|
9f5c76fc0b | ||
|
|
94e12787a2 | ||
|
|
2cd0686537 | ||
|
|
9c539d7aaf | ||
|
|
1ee2374923 | ||
|
|
f6f9d1329d | ||
|
|
ae2f91a94d | ||
|
|
74ff99c478 | ||
|
|
d6367518c6 | ||
|
|
a2aa4bbd7d |
No files matched your search
+2
-29
@@ -1,42 +1,15 @@
|
||||
# Changelog
|
||||
## [1.8.5 (MONTH xth, 2026)](#1-8-5)
|
||||
## [1.8.x (MONTH xth, 2026)](#1-8-x)
|
||||
|
||||
### Additions
|
||||
- You can now drag to select multiple Pokémon inside the PC menu.
|
||||
|
||||
### Pokémon Added
|
||||
#### Generation 4
|
||||
|
||||
#### Generation 5
|
||||
|
||||
#### Generation 6
|
||||
|
||||
#### Generation 7
|
||||
|
||||
#### Generation 8
|
||||
|
||||
#### Generation 9
|
||||
|
||||
### Model updates for the following Pokémon
|
||||
|
||||
### Animation updates for the following Pokémon
|
||||
- Added the `healersSetSpawn` gamerule. When enabled, using a healing machine will set your spawnpoint.
|
||||
|
||||
### Changes
|
||||
- Amethyst now grows from Typegem core blocks like typegems do
|
||||
|
||||
### Fixes
|
||||
- Fixed Ponigiri food values for AppleSkin integration
|
||||
- Fixed errors emitted by typos in Parched Peat bog structure files
|
||||
|
||||
### Developer
|
||||
|
||||
### Molang & Datapacks
|
||||
- `q.is_standing_on_blocks` now properly checks for non-full blocks like slabs, Mud or Soul Sand
|
||||
- Added Molang functions to play footstep sounds based on the corresponding surface. These are intended to be used by Pokémon animations.
|
||||
- Pokémon can now have their Minecraft footstep sounds silenced in their poser. This doesn't affect emitting game events.
|
||||
|
||||
### Particles
|
||||
|
||||
### Localization
|
||||
- Updated translations for:
|
||||
- Updated translations for:
|
||||
@@ -15,7 +15,6 @@ 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.block.HealingMachineBlock;
|
||||
import com.cobblemon.mod.common.duck.ServerLevelDuck;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
|
||||
@@ -23,14 +22,10 @@ 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.core.BlockPos;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -38,9 +33,6 @@ import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(ServerPlayer.class)
|
||||
public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
|
||||
@@ -150,17 +142,4 @@ public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
|
||||
((ServerLevelDuck) this.serverLevel()).cobblemon$getLevelResourceLocation()
|
||||
);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "findRespawnAndUseSpawnBlock(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;FZZ)Ljava/util/Optional;",
|
||||
at = @At(value = "HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private static void cobblemon$useHealthStationAsRespawn(ServerLevel level, BlockPos pos, float angle, boolean forced, boolean keepInventory, CallbackInfoReturnable<Optional<ServerPlayer.RespawnPosAngle>> cir) {
|
||||
BlockState state = level.getBlockState(pos);
|
||||
Block block = state.getBlock();
|
||||
if (block instanceof HealingMachineBlock && HealingMachineBlock.Companion.canSetSpawn(level)) {
|
||||
cir.setReturnValue(HealingMachineBlock.Companion.findStandUpPosition(EntityType.PLAYER, level, pos).map((vec3) -> ServerPlayer.RespawnPosAngle.of(vec3, pos)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,9 @@ import com.cobblemon.mod.common.ModAPI;
|
||||
import com.cobblemon.mod.common.item.PokeBallItem;
|
||||
import com.cobblemon.mod.common.item.PokedexItem;
|
||||
import com.cobblemon.mod.common.item.WearableItem;
|
||||
import com.cobblemon.mod.common.item.components.PokeBallComponent;
|
||||
import com.cobblemon.mod.common.item.components.TMMoveComponent;
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.ItemModelShaper;
|
||||
@@ -57,12 +59,32 @@ public abstract class ItemRendererMixin {
|
||||
cancellable = true
|
||||
)
|
||||
private void cobblemon$overrideItemModel(ItemStack stack, ItemDisplayContext renderMode, boolean leftHanded, PoseStack matrices, MultiBufferSource multiBufferSource, int light, int overlay, BakedModel model, CallbackInfo ci) {
|
||||
boolean shouldBe2d = renderMode == ItemDisplayContext.GUI || renderMode == ItemDisplayContext.FIXED || stack.getItem() == CobblemonItems.TECHNICAL_MACHINE;
|
||||
boolean shouldBe2d =
|
||||
renderMode == ItemDisplayContext.GUI
|
||||
|| renderMode == ItemDisplayContext.FIXED
|
||||
|| stack.getItem() == CobblemonItems.TECHNICAL_MACHINE;
|
||||
|
||||
boolean shouldBe3d =
|
||||
renderMode == ItemDisplayContext.FIRST_PERSON_LEFT_HAND
|
||||
|| renderMode == ItemDisplayContext.FIRST_PERSON_RIGHT_HAND
|
||||
|| renderMode == ItemDisplayContext.THIRD_PERSON_LEFT_HAND
|
||||
|| renderMode == ItemDisplayContext.THIRD_PERSON_RIGHT_HAND
|
||||
|| renderMode == ItemDisplayContext.GROUND
|
||||
|| renderMode == ItemDisplayContext.HEAD;
|
||||
|
||||
ResourceLocation resourceLocation = null;
|
||||
if (stack.getItem() instanceof PokeBallItem) {
|
||||
if (shouldBe2d || renderMode == ItemDisplayContext.NONE) {
|
||||
resourceLocation = PokeBallComponent.getPokeBall(stack).getModel2d();
|
||||
}
|
||||
if (shouldBe3d) {
|
||||
resourceLocation = PokeBallComponent.getPokeBall(stack).getModel3d();
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldBe2d) {
|
||||
if (stack.getItem() instanceof PokeBallItem pokeBallItem) resourceLocation = pokeBallItem.getPokeBall().getModel2d();
|
||||
else if (stack.getItem() instanceof PokedexItem pokedexItem) resourceLocation = pokedexItem.getType().getItemSpritePath();
|
||||
else if (stack.getItem() == CobblemonItems.TECHNICAL_MACHINE) {
|
||||
if (stack.getItem() instanceof PokedexItem pokedexItem) resourceLocation = pokedexItem.getType().getItemSpritePath();
|
||||
if (stack.getItem() == CobblemonItems.TECHNICAL_MACHINE) {
|
||||
TMMoveComponent component = stack.get(CobblemonItemComponents.TM_MOVE);
|
||||
if (component != null) {
|
||||
resourceLocation = new ResourceLocation(Cobblemon.MODID, "tm/" + component.getMove().getElementalType().showdownId() + "_tm");
|
||||
@@ -74,6 +96,9 @@ public abstract class ItemRendererMixin {
|
||||
if (resourceLocation != null) {
|
||||
BakedModel replacementModel = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation(resourceLocation, "inventory"));
|
||||
if (!cobblemon$isSameModel(model, replacementModel)) {
|
||||
if (stack.getItem() instanceof PokeBallItem) {
|
||||
ci.cancel();
|
||||
}
|
||||
ci.cancel();
|
||||
render(stack, renderMode, leftHanded, matrices, multiBufferSource, light, overlay, replacementModel);
|
||||
}
|
||||
@@ -83,16 +108,21 @@ public abstract class ItemRendererMixin {
|
||||
@Inject(method = "getModel", at = @At("HEAD"), cancellable = true)
|
||||
private void cobblemon$getItemModel(ItemStack stack, Level world, LivingEntity entity, int seed, CallbackInfoReturnable<BakedModel> cir) {
|
||||
ResourceLocation resourceLocation = null;
|
||||
if (stack.getItem() instanceof PokeBallItem pokeBallItem) resourceLocation = pokeBallItem.getPokeBall().getModel3d();
|
||||
else if (stack.getItem() instanceof PokedexItem pokedexItem) {
|
||||
boolean isScanModel = entity instanceof Player && entity.getUseItem() == stack && entity.isUsingItem();
|
||||
boolean canOpenScreen = entity != null && ((entity.getOffhandItem() == stack && !(entity.getMainHandItem().getItem() instanceof PokedexItem)) || entity.getMainHandItem() == stack);
|
||||
resourceLocation = pokedexItem.getType().getItemModelPath(isScanModel ? "scanning" : (canOpenScreen ? null : "off"));
|
||||
switch (stack.getItem()) {
|
||||
case PokeBallItem ignored -> resourceLocation = PokeBallComponent.getPokeBall(stack).getModel3d();
|
||||
case PokedexItem pokedexItem -> {
|
||||
boolean isScanModel = entity instanceof Player && entity.getUseItem() == stack && entity.isUsingItem();
|
||||
boolean canOpenScreen = entity != null && ((entity.getOffhandItem() == stack && !(entity.getMainHandItem().getItem() instanceof PokedexItem)) || entity.getMainHandItem() == stack);
|
||||
resourceLocation = pokedexItem.getType().getItemModelPath(isScanModel ? "scanning" : (canOpenScreen ? null : "off"));
|
||||
}
|
||||
case WearableItem wearableItem -> resourceLocation = wearableItem.getModel3d();
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
else if (stack.getItem() instanceof WearableItem wearableItem) resourceLocation = wearableItem.getModel3d();
|
||||
|
||||
if (resourceLocation != null) {
|
||||
BakedModel model = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation(resourceLocation, MODEL_PATH));
|
||||
String modelPath = (stack.getItem() instanceof PokeBallItem && stack.has(CobblemonItemComponents.POKE_BALL)) ? "inventory" : MODEL_PATH;
|
||||
BakedModel model = this.itemModelShaper.getModelManager().getModel(new ModelResourceLocation(resourceLocation, modelPath));
|
||||
ClientLevel clientWorld = world instanceof ClientLevel ? (ClientLevel) world : null;
|
||||
BakedModel overriddenModel = model.getOverrides().resolve(model, stack, clientWorld, entity, seed);
|
||||
cir.setReturnValue(overriddenModel == null ? this.itemModelShaper.getModelManager().getMissingModel() : overriddenModel);
|
||||
@@ -103,10 +133,11 @@ public abstract class ItemRendererMixin {
|
||||
// this falls back to comparing the model contents (e.g. location of the texture, width and height)
|
||||
@Unique
|
||||
private static boolean cobblemon$isSameModel(BakedModel original, BakedModel replacement) {
|
||||
return original.equals(replacement) ||
|
||||
(original.getParticleIcon().contents().name().equals(replacement.getParticleIcon().contents().name()) &&
|
||||
original.getParticleIcon().contents().width() == replacement.getParticleIcon().contents().width() &&
|
||||
original.getParticleIcon().contents().height() == replacement.getParticleIcon().contents().height());
|
||||
return original.equals(replacement) || (
|
||||
original.getParticleIcon().contents().name().equals(replacement.getParticleIcon().contents().name())
|
||||
&& original.getParticleIcon().contents().width() == replacement.getParticleIcon().contents().width()
|
||||
&& original.getParticleIcon().contents().height() == replacement.getParticleIcon().contents().height()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.client.CobblemonBakingOverrides;
|
||||
import com.cobblemon.mod.common.client.CobblemonClient;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
@@ -19,6 +20,7 @@ import net.minecraft.client.resources.model.UnbakedModel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
@@ -29,6 +31,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Mixin(ModelBakery.class)
|
||||
public abstract class ModelLoaderMixin {
|
||||
@@ -38,15 +41,18 @@ public abstract class ModelLoaderMixin {
|
||||
|
||||
@Shadow protected abstract void loadItemModelAndDependencies(ResourceLocation resourceLocation);
|
||||
|
||||
@Shadow protected abstract void loadSpecialItemModelAndDependencies(ModelResourceLocation modelResourceLocation);
|
||||
|
||||
@Unique
|
||||
List<String> dynamicFolders = Arrays.asList("egg", "tm");
|
||||
List<String> dynamicFolders = Arrays.asList("egg", "tm", "poke_ball");
|
||||
|
||||
@Inject(
|
||||
method = "<init>",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V",
|
||||
ordinal = 1
|
||||
ordinal = 1,
|
||||
shift = At.Shift.AFTER
|
||||
)
|
||||
)
|
||||
public void loadCustomItemModels(BlockColors blockColors,
|
||||
@@ -67,13 +73,24 @@ public abstract class ModelLoaderMixin {
|
||||
* hacky at the init stage and hacky at the render stage. Pretty cool in the gameplay stage though.
|
||||
*
|
||||
* - Hiro
|
||||
*
|
||||
* We also want to load different contexts (first/third person etc.) for poke ball models, so additional check was added for them.
|
||||
* - Gito
|
||||
*/
|
||||
|
||||
dynamicFolders.forEach(folder -> {
|
||||
Map<ResourceLocation, Resource> map = Minecraft.getInstance().getResourceManager().listResources("models/item/" + folder, (t) -> true);
|
||||
map.forEach((key, value) -> {
|
||||
ResourceLocation resourceLocation = new ResourceLocation(key.getNamespace(), key.getPath().replace("models/item/", "").replace(".json", ""));
|
||||
this.loadItemModelAndDependencies(resourceLocation);
|
||||
|
||||
if (folder.equals("poke_ball")) {
|
||||
// also load variants for different display ctx
|
||||
Arrays.stream(ItemDisplayContext.values())
|
||||
.forEach(item -> {
|
||||
ModelResourceLocation model = new ModelResourceLocation(resourceLocation, item.getSerializedName());
|
||||
this.loadSpecialItemModelAndDependencies(model);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ object CobblemonEntities : PlatformRegistry<Registry<EntityType<*>>, ResourceKey
|
||||
@JvmField
|
||||
val EMPTY_POKEBALL: EntityType<EmptyPokeBallEntity> = this.create(
|
||||
EMPTY_POKEBALL_KEY.path,
|
||||
EntityType.Builder.of({ _, world -> EmptyPokeBallEntity(PokeBalls.POKE_BALL, world) }, MobCategory.MISC)
|
||||
EntityType.Builder.of({ _, world -> EmptyPokeBallEntity(PokeBalls.STRANGE_BALL, world) }, MobCategory.MISC)
|
||||
.build(EMPTY_POKEBALL_KEY.toString())
|
||||
)
|
||||
|
||||
@@ -99,4 +99,4 @@ object CobblemonEntities : PlatformRegistry<Registry<EntityType<*>>, ResourceKey
|
||||
consumer(POKEMON, PokemonEntity.createAttributes())
|
||||
consumer(NPC, NPCEntity.createAttributes())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,6 +99,12 @@ object CobblemonItemComponents : PlatformRegistry<Registry<DataComponentType<*>>
|
||||
.networkSynchronized(ByteBufCodecs.BOOL)
|
||||
.build())
|
||||
|
||||
@JvmField
|
||||
val POKE_BALL: DataComponentType<PokeBallComponent> = create("poke_ball", DataComponentType.builder<PokeBallComponent>()
|
||||
.persistent(PokeBallComponent.CODEC)
|
||||
.networkSynchronized(PokeBallComponent.PACKET_CODEC)
|
||||
.build())
|
||||
|
||||
fun register() {
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:pokemon_item"), POKEMON_ITEM)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:bait"), BAIT)
|
||||
@@ -112,9 +118,10 @@ object CobblemonItemComponents : PlatformRegistry<Registry<DataComponentType<*>>
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:food"), FOOD)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:mob_effects"), MOB_EFFECTS)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:held_item_effect"), HELD_ITEM_EFFECT)
|
||||
Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, ResourceLocation.parse("cobblemon:poke_ball"), POKE_BALL)
|
||||
}
|
||||
|
||||
override val registry = BuiltInRegistries.DATA_COMPONENT_TYPE
|
||||
override val resourceKey = Registries.DATA_COMPONENT_TYPE
|
||||
|
||||
}
|
||||
}
|
||||
@@ -75,103 +75,105 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
val NPC_EDITOR = create("npc_editor", CobblemonItem(Item.Properties().stacksTo(1)))
|
||||
|
||||
@JvmField
|
||||
val pokeBalls = mutableListOf<PokeBallItem>()
|
||||
val pokeBalls = mutableMapOf< ResourceLocation, PokeBallItem>()
|
||||
@JvmField
|
||||
val POKE_BALL = pokeBallItem(PokeBalls.POKE_BALL)
|
||||
val STRANGE_BALL = pokeBallItem("strange_ball")
|
||||
@JvmField
|
||||
val CITRINE_BALL = pokeBallItem(PokeBalls.CITRINE_BALL)
|
||||
val POKE_BALL = pokeBallItem("poke_ball")
|
||||
@JvmField
|
||||
val VERDANT_BALL = pokeBallItem(PokeBalls.VERDANT_BALL)
|
||||
val CITRINE_BALL = pokeBallItem("citrine_ball")
|
||||
@JvmField
|
||||
val AZURE_BALL = pokeBallItem(PokeBalls.AZURE_BALL)
|
||||
val VERDANT_BALL = pokeBallItem("verdant_ball")
|
||||
@JvmField
|
||||
val ROSEATE_BALL = pokeBallItem(PokeBalls.ROSEATE_BALL)
|
||||
val AZURE_BALL = pokeBallItem("azure_ball")
|
||||
@JvmField
|
||||
val SLATE_BALL = pokeBallItem(PokeBalls.SLATE_BALL)
|
||||
val ROSEATE_BALL = pokeBallItem("roseate_ball")
|
||||
@JvmField
|
||||
val PREMIER_BALL = pokeBallItem(PokeBalls.PREMIER_BALL)
|
||||
val SLATE_BALL = pokeBallItem("slate_ball")
|
||||
@JvmField
|
||||
val GREAT_BALL = pokeBallItem(PokeBalls.GREAT_BALL)
|
||||
val PREMIER_BALL = pokeBallItem("premier_ball")
|
||||
@JvmField
|
||||
val ULTRA_BALL = pokeBallItem(PokeBalls.ULTRA_BALL)
|
||||
val GREAT_BALL = pokeBallItem("great_ball")
|
||||
@JvmField
|
||||
val SAFARI_BALL = pokeBallItem(PokeBalls.SAFARI_BALL)
|
||||
val ULTRA_BALL = pokeBallItem("ultra_ball")
|
||||
@JvmField
|
||||
val FAST_BALL = pokeBallItem(PokeBalls.FAST_BALL)
|
||||
val SAFARI_BALL = pokeBallItem("safari_ball")
|
||||
@JvmField
|
||||
val LEVEL_BALL = pokeBallItem(PokeBalls.LEVEL_BALL)
|
||||
val FAST_BALL = pokeBallItem("fast_ball")
|
||||
@JvmField
|
||||
val LURE_BALL = pokeBallItem(PokeBalls.LURE_BALL)
|
||||
val LEVEL_BALL = pokeBallItem("level_ball")
|
||||
@JvmField
|
||||
val HEAVY_BALL = pokeBallItem(PokeBalls.HEAVY_BALL)
|
||||
val LURE_BALL = pokeBallItem("lure_ball")
|
||||
@JvmField
|
||||
val LOVE_BALL = pokeBallItem(PokeBalls.LOVE_BALL)
|
||||
val HEAVY_BALL = pokeBallItem("heavy_ball")
|
||||
@JvmField
|
||||
val FRIEND_BALL = pokeBallItem(PokeBalls.FRIEND_BALL)
|
||||
val LOVE_BALL = pokeBallItem("love_ball")
|
||||
@JvmField
|
||||
val MOON_BALL = pokeBallItem(PokeBalls.MOON_BALL)
|
||||
val FRIEND_BALL = pokeBallItem("friend_ball")
|
||||
@JvmField
|
||||
val SPORT_BALL = pokeBallItem(PokeBalls.SPORT_BALL)
|
||||
val MOON_BALL = pokeBallItem("moon_ball")
|
||||
@JvmField
|
||||
val PARK_BALL = pokeBallItem(PokeBalls.PARK_BALL)
|
||||
val SPORT_BALL = pokeBallItem("sport_ball")
|
||||
@JvmField
|
||||
val NET_BALL = pokeBallItem(PokeBalls.NET_BALL)
|
||||
val PARK_BALL = pokeBallItem("park_ball")
|
||||
@JvmField
|
||||
val DIVE_BALL = pokeBallItem(PokeBalls.DIVE_BALL)
|
||||
val NET_BALL = pokeBallItem("net_ball")
|
||||
@JvmField
|
||||
val NEST_BALL = pokeBallItem(PokeBalls.NEST_BALL)
|
||||
val DIVE_BALL = pokeBallItem("dive_ball")
|
||||
@JvmField
|
||||
val REPEAT_BALL = pokeBallItem(PokeBalls.REPEAT_BALL)
|
||||
val NEST_BALL = pokeBallItem("nest_ball")
|
||||
@JvmField
|
||||
val TIMER_BALL = pokeBallItem(PokeBalls.TIMER_BALL)
|
||||
val REPEAT_BALL = pokeBallItem("repeat_ball")
|
||||
@JvmField
|
||||
val LUXURY_BALL = pokeBallItem(PokeBalls.LUXURY_BALL)
|
||||
val TIMER_BALL = pokeBallItem("timer_ball")
|
||||
@JvmField
|
||||
val DUSK_BALL = pokeBallItem(PokeBalls.DUSK_BALL)
|
||||
val LUXURY_BALL = pokeBallItem("luxury_ball")
|
||||
@JvmField
|
||||
val HEAL_BALL = pokeBallItem(PokeBalls.HEAL_BALL)
|
||||
val DUSK_BALL = pokeBallItem("dusk_ball")
|
||||
@JvmField
|
||||
val QUICK_BALL = pokeBallItem(PokeBalls.QUICK_BALL)
|
||||
val HEAL_BALL = pokeBallItem("heal_ball")
|
||||
@JvmField
|
||||
val DREAM_BALL = pokeBallItem(PokeBalls.DREAM_BALL)
|
||||
val QUICK_BALL = pokeBallItem("quick_ball")
|
||||
@JvmField
|
||||
val BEAST_BALL = pokeBallItem(PokeBalls.BEAST_BALL)
|
||||
val DREAM_BALL = pokeBallItem("dream_ball")
|
||||
@JvmField
|
||||
val MASTER_BALL = pokeBallItem(PokeBalls.MASTER_BALL)
|
||||
val BEAST_BALL = pokeBallItem("beast_ball")
|
||||
@JvmField
|
||||
val CHERISH_BALL = pokeBallItem(PokeBalls.CHERISH_BALL)
|
||||
val MASTER_BALL = pokeBallItem("master_ball")
|
||||
@JvmField
|
||||
val ANCIENT_POKE_BALL = pokeBallItem(PokeBalls.ANCIENT_POKE_BALL)
|
||||
val CHERISH_BALL = pokeBallItem("cherish_ball")
|
||||
@JvmField
|
||||
val ANCIENT_CITRINE_BALL = pokeBallItem(PokeBalls.ANCIENT_CITRINE_BALL)
|
||||
val ANCIENT_POKE_BALL = pokeBallItem("ancient_poke_ball")
|
||||
@JvmField
|
||||
val ANCIENT_VERDANT_BALL = pokeBallItem(PokeBalls.ANCIENT_VERDANT_BALL)
|
||||
val ANCIENT_CITRINE_BALL = pokeBallItem("ancient_citrine_ball")
|
||||
@JvmField
|
||||
val ANCIENT_AZURE_BALL = pokeBallItem(PokeBalls.ANCIENT_AZURE_BALL)
|
||||
val ANCIENT_VERDANT_BALL = pokeBallItem("ancient_verdant_ball")
|
||||
@JvmField
|
||||
val ANCIENT_ROSEATE_BALL = pokeBallItem(PokeBalls.ANCIENT_ROSEATE_BALL)
|
||||
val ANCIENT_AZURE_BALL = pokeBallItem("ancient_azure_ball")
|
||||
@JvmField
|
||||
val ANCIENT_SLATE_BALL = pokeBallItem(PokeBalls.ANCIENT_SLATE_BALL)
|
||||
val ANCIENT_ROSEATE_BALL = pokeBallItem("ancient_roseate_ball")
|
||||
@JvmField
|
||||
val ANCIENT_IVORY_BALL = pokeBallItem(PokeBalls.ANCIENT_IVORY_BALL)
|
||||
val ANCIENT_SLATE_BALL = pokeBallItem("ancient_slate_ball")
|
||||
@JvmField
|
||||
val ANCIENT_GREAT_BALL = pokeBallItem(PokeBalls.ANCIENT_GREAT_BALL)
|
||||
val ANCIENT_IVORY_BALL = pokeBallItem("ancient_ivory_ball")
|
||||
@JvmField
|
||||
val ANCIENT_ULTRA_BALL = pokeBallItem(PokeBalls.ANCIENT_ULTRA_BALL)
|
||||
val ANCIENT_GREAT_BALL = pokeBallItem("ancient_great_ball")
|
||||
@JvmField
|
||||
val ANCIENT_FEATHER_BALL = pokeBallItem(PokeBalls.ANCIENT_FEATHER_BALL)
|
||||
val ANCIENT_ULTRA_BALL = pokeBallItem("ancient_ultra_ball")
|
||||
@JvmField
|
||||
val ANCIENT_WING_BALL = pokeBallItem(PokeBalls.ANCIENT_WING_BALL)
|
||||
val ANCIENT_FEATHER_BALL = pokeBallItem("ancient_feather_ball")
|
||||
@JvmField
|
||||
val ANCIENT_JET_BALL = pokeBallItem(PokeBalls.ANCIENT_JET_BALL)
|
||||
val ANCIENT_WING_BALL = pokeBallItem("ancient_wing_ball")
|
||||
@JvmField
|
||||
val ANCIENT_HEAVY_BALL = pokeBallItem(PokeBalls.ANCIENT_HEAVY_BALL)
|
||||
val ANCIENT_JET_BALL = pokeBallItem("ancient_jet_ball")
|
||||
@JvmField
|
||||
val ANCIENT_LEADEN_BALL = pokeBallItem(PokeBalls.ANCIENT_LEADEN_BALL)
|
||||
val ANCIENT_HEAVY_BALL = pokeBallItem("ancient_heavy_ball")
|
||||
@JvmField
|
||||
val ANCIENT_GIGATON_BALL = pokeBallItem(PokeBalls.ANCIENT_GIGATON_BALL)
|
||||
val ANCIENT_LEADEN_BALL = pokeBallItem("ancient_leaden_ball")
|
||||
@JvmField
|
||||
val ANCIENT_ORIGIN_BALL = pokeBallItem(PokeBalls.ANCIENT_ORIGIN_BALL)
|
||||
val ANCIENT_GIGATON_BALL = pokeBallItem("ancient_gigaton_ball")
|
||||
@JvmField
|
||||
val ANCIENT_ORIGIN_BALL = pokeBallItem("ancient_origin_ball")
|
||||
|
||||
val pokedexes = mutableListOf<PokedexItem>()
|
||||
@JvmField
|
||||
@@ -1406,102 +1408,102 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
)
|
||||
|
||||
val pokeRods = mutableListOf<PokerodItem>()
|
||||
@JvmField
|
||||
val POKE_ROD = pokerodItem(cobblemonResource("poke_rod"))
|
||||
@JvmField
|
||||
val CITRINE_ROD = pokerodItem(cobblemonResource("citrine_rod"))
|
||||
@JvmField
|
||||
val VERDANT_ROD = pokerodItem(cobblemonResource("verdant_rod"))
|
||||
@JvmField
|
||||
val AZURE_ROD = pokerodItem(cobblemonResource("azure_rod"))
|
||||
@JvmField
|
||||
val ROSEATE_ROD = pokerodItem(cobblemonResource("roseate_rod"))
|
||||
@JvmField
|
||||
val SLATE_ROD = pokerodItem(cobblemonResource("slate_rod"))
|
||||
@JvmField
|
||||
val PREMIER_ROD = pokerodItem(cobblemonResource("premier_rod"))
|
||||
@JvmField
|
||||
val GREAT_ROD = pokerodItem(cobblemonResource("great_rod"))
|
||||
@JvmField
|
||||
val ULTRA_ROD = pokerodItem(cobblemonResource("ultra_rod"))
|
||||
@JvmField
|
||||
val SAFARI_ROD = pokerodItem(cobblemonResource("safari_rod"))
|
||||
@JvmField
|
||||
val FAST_ROD = pokerodItem(cobblemonResource("fast_rod"))
|
||||
@JvmField
|
||||
val LEVEL_ROD = pokerodItem(cobblemonResource("level_rod"))
|
||||
@JvmField
|
||||
val LURE_ROD = pokerodItem(cobblemonResource("lure_rod"))
|
||||
@JvmField
|
||||
val HEAVY_ROD = pokerodItem(cobblemonResource("heavy_rod"))
|
||||
@JvmField
|
||||
val LOVE_ROD = pokerodItem(cobblemonResource("love_rod"))
|
||||
@JvmField
|
||||
val FRIEND_ROD = pokerodItem(cobblemonResource("friend_rod"))
|
||||
@JvmField
|
||||
val MOON_ROD = pokerodItem(cobblemonResource("moon_rod"))
|
||||
@JvmField
|
||||
val SPORT_ROD = pokerodItem(cobblemonResource("sport_rod"))
|
||||
@JvmField
|
||||
val PARK_ROD = pokerodItem(cobblemonResource("park_rod"))
|
||||
@JvmField
|
||||
val NET_ROD = pokerodItem(cobblemonResource("net_rod"))
|
||||
@JvmField
|
||||
val DIVE_ROD = pokerodItem(cobblemonResource("dive_rod"))
|
||||
@JvmField
|
||||
val NEST_ROD = pokerodItem(cobblemonResource("nest_rod"))
|
||||
@JvmField
|
||||
val REPEAT_ROD = pokerodItem(cobblemonResource("repeat_rod"))
|
||||
@JvmField
|
||||
val TIMER_ROD = pokerodItem(cobblemonResource("timer_rod"))
|
||||
@JvmField
|
||||
val LUXURY_ROD = pokerodItem(cobblemonResource("luxury_rod"))
|
||||
@JvmField
|
||||
val DUSK_ROD = pokerodItem(cobblemonResource("dusk_rod"))
|
||||
@JvmField
|
||||
val HEAL_ROD = pokerodItem(cobblemonResource("heal_rod"))
|
||||
@JvmField
|
||||
val QUICK_ROD = pokerodItem(cobblemonResource("quick_rod"))
|
||||
@JvmField
|
||||
val DREAM_ROD = pokerodItem(cobblemonResource("dream_rod"))
|
||||
@JvmField
|
||||
val BEAST_ROD = pokerodItem(cobblemonResource("beast_rod"), Rarity.RARE)
|
||||
@JvmField
|
||||
val MASTER_ROD = pokerodItem(cobblemonResource("master_rod"), Rarity.EPIC)
|
||||
@JvmField
|
||||
val CHERISH_ROD = pokerodItem(cobblemonResource("cherish_rod"), Rarity.EPIC)
|
||||
@JvmField
|
||||
val ANCIENT_POKE_ROD = pokerodItem(cobblemonResource("ancient_poke_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_CITRINE_ROD = pokerodItem(cobblemonResource("ancient_citrine_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_VERDANT_ROD = pokerodItem(cobblemonResource("ancient_verdant_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_AZURE_ROD = pokerodItem(cobblemonResource("ancient_azure_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_ROSEATE_ROD = pokerodItem(cobblemonResource("ancient_roseate_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_SLATE_ROD = pokerodItem(cobblemonResource("ancient_slate_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_IVORY_ROD = pokerodItem(cobblemonResource("ancient_ivory_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_GREAT_ROD = pokerodItem(cobblemonResource("ancient_great_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_ULTRA_ROD = pokerodItem(cobblemonResource("ancient_ultra_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_FEATHER_ROD = pokerodItem(cobblemonResource("ancient_feather_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_WING_ROD = pokerodItem(cobblemonResource("ancient_wing_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_JET_ROD = pokerodItem(cobblemonResource("ancient_jet_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_HEAVY_ROD = pokerodItem(cobblemonResource("ancient_heavy_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_LEADEN_ROD = pokerodItem(cobblemonResource("ancient_leaden_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_GIGATON_ROD = pokerodItem(cobblemonResource("ancient_gigaton_rod"))
|
||||
@JvmField
|
||||
val ANCIENT_ORIGIN_ROD = pokerodItem(cobblemonResource("ancient_origin_rod"), Rarity.EPIC)
|
||||
// @JvmField
|
||||
// val POKE_ROD = pokerodItem(cobblemonResource("poke_rod"))
|
||||
// @JvmField
|
||||
// val CITRINE_ROD = pokerodItem(cobblemonResource("citrine_rod"))
|
||||
// @JvmField
|
||||
// val VERDANT_ROD = pokerodItem(cobblemonResource("verdant_rod"))
|
||||
// @JvmField
|
||||
// val AZURE_ROD = pokerodItem(cobblemonResource("azure_rod"))
|
||||
// @JvmField
|
||||
// val ROSEATE_ROD = pokerodItem(cobblemonResource("roseate_rod"))
|
||||
// @JvmField
|
||||
// val SLATE_ROD = pokerodItem(cobblemonResource("slate_rod"))
|
||||
// @JvmField
|
||||
// val PREMIER_ROD = pokerodItem(cobblemonResource("premier_rod"))
|
||||
// @JvmField
|
||||
// val GREAT_ROD = pokerodItem(cobblemonResource("great_rod"))
|
||||
// @JvmField
|
||||
// val ULTRA_ROD = pokerodItem(cobblemonResource("ultra_rod"))
|
||||
// @JvmField
|
||||
// val SAFARI_ROD = pokerodItem(cobblemonResource("safari_rod"))
|
||||
// @JvmField
|
||||
// val FAST_ROD = pokerodItem(cobblemonResource("fast_rod"))
|
||||
// @JvmField
|
||||
// val LEVEL_ROD = pokerodItem(cobblemonResource("level_rod"))
|
||||
// @JvmField
|
||||
// val LURE_ROD = pokerodItem(cobblemonResource("lure_rod"))
|
||||
// @JvmField
|
||||
// val HEAVY_ROD = pokerodItem(cobblemonResource("heavy_rod"))
|
||||
// @JvmField
|
||||
// val LOVE_ROD = pokerodItem(cobblemonResource("love_rod"))
|
||||
// @JvmField
|
||||
// val FRIEND_ROD = pokerodItem(cobblemonResource("friend_rod"))
|
||||
// @JvmField
|
||||
// val MOON_ROD = pokerodItem(cobblemonResource("moon_rod"))
|
||||
// @JvmField
|
||||
// val SPORT_ROD = pokerodItem(cobblemonResource("sport_rod"))
|
||||
// @JvmField
|
||||
// val PARK_ROD = pokerodItem(cobblemonResource("park_rod"))
|
||||
// @JvmField
|
||||
// val NET_ROD = pokerodItem(cobblemonResource("net_rod"))
|
||||
// @JvmField
|
||||
// val DIVE_ROD = pokerodItem(cobblemonResource("dive_rod"))
|
||||
// @JvmField
|
||||
// val NEST_ROD = pokerodItem(cobblemonResource("nest_rod"))
|
||||
// @JvmField
|
||||
// val REPEAT_ROD = pokerodItem(cobblemonResource("repeat_rod"))
|
||||
// @JvmField
|
||||
// val TIMER_ROD = pokerodItem(cobblemonResource("timer_rod"))
|
||||
// @JvmField
|
||||
// val LUXURY_ROD = pokerodItem(cobblemonResource("luxury_rod"))
|
||||
// @JvmField
|
||||
// val DUSK_ROD = pokerodItem(cobblemonResource("dusk_rod"))
|
||||
// @JvmField
|
||||
// val HEAL_ROD = pokerodItem(cobblemonResource("heal_rod"))
|
||||
// @JvmField
|
||||
// val QUICK_ROD = pokerodItem(cobblemonResource("quick_rod"))
|
||||
// @JvmField
|
||||
// val DREAM_ROD = pokerodItem(cobblemonResource("dream_rod"))
|
||||
// @JvmField
|
||||
// val BEAST_ROD = pokerodItem(cobblemonResource("beast_rod"), Rarity.RARE)
|
||||
// @JvmField
|
||||
// val MASTER_ROD = pokerodItem(cobblemonResource("master_rod"), Rarity.EPIC)
|
||||
// @JvmField
|
||||
// val CHERISH_ROD = pokerodItem(cobblemonResource("cherish_rod"), Rarity.EPIC)
|
||||
// @JvmField
|
||||
// val ANCIENT_POKE_ROD = pokerodItem(cobblemonResource("ancient_poke_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_CITRINE_ROD = pokerodItem(cobblemonResource("ancient_citrine_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_VERDANT_ROD = pokerodItem(cobblemonResource("ancient_verdant_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_AZURE_ROD = pokerodItem(cobblemonResource("ancient_azure_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_ROSEATE_ROD = pokerodItem(cobblemonResource("ancient_roseate_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_SLATE_ROD = pokerodItem(cobblemonResource("ancient_slate_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_IVORY_ROD = pokerodItem(cobblemonResource("ancient_ivory_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_GREAT_ROD = pokerodItem(cobblemonResource("ancient_great_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_ULTRA_ROD = pokerodItem(cobblemonResource("ancient_ultra_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_FEATHER_ROD = pokerodItem(cobblemonResource("ancient_feather_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_WING_ROD = pokerodItem(cobblemonResource("ancient_wing_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_JET_ROD = pokerodItem(cobblemonResource("ancient_jet_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_HEAVY_ROD = pokerodItem(cobblemonResource("ancient_heavy_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_LEADEN_ROD = pokerodItem(cobblemonResource("ancient_leaden_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_GIGATON_ROD = pokerodItem(cobblemonResource("ancient_gigaton_rod"))
|
||||
// @JvmField
|
||||
// val ANCIENT_ORIGIN_ROD = pokerodItem(cobblemonResource("ancient_origin_rod"), Rarity.EPIC)
|
||||
|
||||
// Misc
|
||||
@JvmField
|
||||
@@ -1584,15 +1586,19 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
|
||||
private fun noSettingsItem(name: String): CobblemonItem = this.create(name, CobblemonItem(Item.Properties()))
|
||||
|
||||
private fun itemWithRarity(name: String, rarity: Rarity): CobblemonItem = this.create(name, CobblemonItem(Item.Properties().rarity(rarity)))
|
||||
|
||||
|
||||
fun berries() = this.berries.toMap()
|
||||
|
||||
private fun mulchItem(name: String, mulchVariant: MulchVariant): MulchItem = this.create(name, MulchItem(mulchVariant))
|
||||
|
||||
private fun pokeBallItem(pokeBall: PokeBall): PokeBallItem {
|
||||
val item = create(pokeBall.name.path, PokeBallItem(pokeBall))
|
||||
pokeBall.item = item
|
||||
pokeBalls.add(item)
|
||||
private fun pokeBallItem(name: String): PokeBallItem {
|
||||
// we attach strange ball by default to let registry load
|
||||
// actual ball configurations will be attached on datapack loading stage
|
||||
// see PokeBalls.reload
|
||||
val ball = PokeBalls.STRANGE_BALL
|
||||
val item = create(name, PokeBallItem(ball))
|
||||
ball.stack = item.defaultInstance
|
||||
pokeBalls.put(cobblemonResource(name), item)
|
||||
return item
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ 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.pokeballs.PokeBallsRegistrySyncPacket
|
||||
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
|
||||
@@ -445,6 +446,7 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(MarkRegistrySyncPacket.ID, MarkRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(RideSettingsSyncPacket.ID, RideSettingsSyncPacket::decode, RideSettingsSyncHandler))
|
||||
list.add(PacketRegisterInfo(TechnicalMachineRegistrySyncPacket.ID, TechnicalMachineRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
list.add(PacketRegisterInfo(PokeBallsRegistrySyncPacket.ID, PokeBallsRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
|
||||
|
||||
// Effects
|
||||
list.add(PacketRegisterInfo(SpawnSnowstormParticlePacket.ID, SpawnSnowstormParticlePacket::decode, SpawnSnowstormParticleHandler))
|
||||
@@ -566,7 +568,6 @@ object CobblemonNetwork {
|
||||
list.add(PacketRegisterInfo(SwapPartyPokemonPacket.ID, SwapPartyPokemonPacket::decode, SwapPartyPokemonHandler))
|
||||
|
||||
list.add(PacketRegisterInfo(MovePCPokemonPacket.ID, MovePCPokemonPacket::decode, MovePCPokemonHandler))
|
||||
list.add(PacketRegisterInfo(MovePCPokemonBatchPacket.ID, MovePCPokemonBatchPacket::decode, MovePCPokemonBatchHandler))
|
||||
list.add(PacketRegisterInfo(MovePartyPokemonPacket.ID, MovePartyPokemonPacket::decode, MovePartyPokemonHandler))
|
||||
|
||||
list.add(PacketRegisterInfo(SwapPCPartyPokemonPacket.ID, SwapPCPartyPokemonPacket::decode, SwapPCPartyPokemonHandler))
|
||||
@@ -658,4 +659,4 @@ object CobblemonNetwork {
|
||||
fun sendPacketToPlayer(player: ServerPlayer, packet: NetworkPacket<*>) {
|
||||
Cobblemon.implementation.networkManager.sendPacketToPlayer(player, packet)
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -25,6 +25,7 @@ data class PokemonCapturedEvent (
|
||||
"pokemon" to pokemon.struct,
|
||||
"player" to player.asMoLangValue(),
|
||||
"poke_ball" to pokeBallEntity.struct,
|
||||
"item" to player.level().itemRegistry.wrapAsHolder(pokeBallEntity.pokeBall.item).asMoLangValue(Registries.ITEM)
|
||||
"item" to player.level().itemRegistry.wrapAsHolder(pokeBallEntity.pokeBall.item()).asMoLangValue(Registries.ITEM),
|
||||
"stack" to pokeBallEntity.pokeBall.stack.asMoLangValue(player.level().registryAccess())
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ import com.cobblemon.mod.common.api.molang.function.NPCMoLangFunctions
|
||||
import com.cobblemon.mod.common.api.molang.function.PCMoLangFunctions
|
||||
import com.cobblemon.mod.common.api.molang.function.PartyMoLangFunctions
|
||||
import com.cobblemon.mod.common.api.molang.function.PlayerMoLangFunctions
|
||||
import com.cobblemon.mod.common.api.molang.function.PokeBallMoLangFunctions
|
||||
import com.cobblemon.mod.common.api.molang.function.PokedexMoLangFunctions
|
||||
import com.cobblemon.mod.common.api.molang.function.PokemonEntityMoLangFunctions
|
||||
import com.cobblemon.mod.common.api.molang.function.PokemonMoLangFunctions
|
||||
@@ -56,6 +57,7 @@ import com.cobblemon.mod.common.api.storage.party.PartyStore
|
||||
import com.cobblemon.mod.common.api.storage.pc.PCStore
|
||||
import com.cobblemon.mod.common.entity.npc.NPCEntity
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.pokemon.Species
|
||||
import com.cobblemon.mod.common.util.effectiveName
|
||||
@@ -262,6 +264,18 @@ object MoLangFunctions {
|
||||
return value
|
||||
}
|
||||
|
||||
fun PokeBall.asMoLangValue(): ObjectValue<PokeBall> {
|
||||
val value =
|
||||
ObjectValue(
|
||||
obj = this,
|
||||
stringify = { it.name.toString() }
|
||||
)
|
||||
|
||||
value.addFunctions(PokeBallMoLangFunctions.attach(this))
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
fun Vec3.asMoLangValue(): ObjectValue<Vec3> {
|
||||
val value =
|
||||
ObjectValue(
|
||||
@@ -389,6 +403,12 @@ object MoLangFunctions {
|
||||
return this
|
||||
}
|
||||
|
||||
fun QueryStruct.addPokeBallFunctions(ball: PokeBall): QueryStruct {
|
||||
val addedFunctions = PokeBallMoLangFunctions.attach(ball)
|
||||
addFunctions(addedFunctions)
|
||||
return this
|
||||
}
|
||||
|
||||
fun <T : QueryStruct> T.addFunctions(functions: Map<String, Function<MoParams, Any>>): T {
|
||||
this.functions.putAll(functions)
|
||||
return this
|
||||
|
||||
+10
@@ -23,6 +23,7 @@ import com.cobblemon.mod.common.api.scheduling.Schedulable
|
||||
import com.cobblemon.mod.common.api.text.text
|
||||
import com.cobblemon.mod.common.entity.MoLangScriptingEntity
|
||||
import com.cobblemon.mod.common.entity.PosableEntity
|
||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
|
||||
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.util.asArrayValue
|
||||
@@ -307,6 +308,15 @@ object EntityMoLangFunctions : AbstractMoLangFunctionHolder<Entity>() {
|
||||
functions["face"] = { params ->
|
||||
ObjectValue(ReferenceDialogueFaceProvider(entity.id, params.getBooleanOrNull(0) != false))
|
||||
}
|
||||
|
||||
// EmptyPokeBallEntity is a subclass of PosableEntity
|
||||
// meaning we need to add a condition here to attach our func
|
||||
// only to instance of EmptyPokeBallEntity
|
||||
if (entity is EmptyPokeBallEntity) {
|
||||
functions["capture_state"] = {
|
||||
StringValue(entity.captureState.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is Schedulable -> {
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.molang.function
|
||||
|
||||
import com.bedrockk.molang.runtime.MoParams
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.util.getStringOrNull
|
||||
|
||||
object PokeBallMoLangFunctions : AbstractMoLangFunctionHolder<PokeBall>() {
|
||||
override fun PokeBall.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
|
||||
val ball = this
|
||||
val functions = hashMapOf<String, (MoParams) -> Any>()
|
||||
|
||||
|
||||
return functions
|
||||
}
|
||||
}
|
||||
+5
@@ -47,6 +47,10 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
||||
functions["max_hp"] = { DoubleValue(pokemon.maxHealth.toDouble()) }
|
||||
functions["current_hp"] = { DoubleValue(pokemon.currentHealth.toDouble()) }
|
||||
functions["friendship"] = { DoubleValue(pokemon.friendship.toDouble()) }
|
||||
functions["set_friendship"] = { params ->
|
||||
val amount = params.getDouble(0)
|
||||
pokemon.setFriendship(amount.toInt())
|
||||
}
|
||||
functions["max_fullness"] = { DoubleValue(pokemon.getMaxFullness().toDouble()) }
|
||||
functions["fullness"] = { DoubleValue(pokemon.currentFullness.toDouble()) }
|
||||
functions["lose_fullness"] = { params ->
|
||||
@@ -452,6 +456,7 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
|
||||
functions["entity"] = { pokemon.entity?.asMoLangValue() ?: DoubleValue.ZERO }
|
||||
functions["is_alpha"] = { DoubleValue(pokemon.isAlpha) }
|
||||
functions["size_category"] = { StringValue(pokemon.getSizeCategory().name) }
|
||||
functions["full_heal"] = { pokemon.heal() }
|
||||
|
||||
return functions
|
||||
}
|
||||
|
||||
@@ -8,293 +8,348 @@
|
||||
|
||||
package com.cobblemon.mod.common.api.pokeball
|
||||
|
||||
import com.bedrockk.molang.Expression
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.api.Priority
|
||||
import com.cobblemon.mod.common.api.data.JsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.data.ServerJsonDataRegistry
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.CaptureEffect
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.CatchRateModifier
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.effects.CaptureEffects
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.effects.FriendshipEarningBoostEffect
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.*
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.BaseStatModifier
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.CatchRateModifiers
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.DynamicMultiplierModifier
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.ExpressionModifier
|
||||
import com.cobblemon.mod.common.api.pokemon.labels.CobblemonPokemonLabels
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stats
|
||||
import com.cobblemon.mod.common.api.pokemon.status.Statuses
|
||||
import com.cobblemon.mod.common.api.reactive.SimpleObservable
|
||||
import com.cobblemon.mod.common.api.types.ElementalTypes
|
||||
import com.cobblemon.mod.common.item.components.PokeBallComponent
|
||||
import com.cobblemon.mod.common.net.messages.client.pokeballs.PokeBallsRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.util.adapters.*
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.removeIf
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import net.minecraft.advancements.critereon.MinMaxBounds
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.server.packs.PackType
|
||||
import net.minecraft.util.LowerCaseEnumTypeAdapterFactory
|
||||
import java.awt.Color
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* The data registry for [PokeBall]s.
|
||||
* All the pokeball fields are guaranteed to exist
|
||||
*/
|
||||
object PokeBalls : JsonDataRegistry<PokeBall> {
|
||||
|
||||
override val id = cobblemonResource("pokeballs")
|
||||
object PokeBalls : ServerJsonDataRegistry<PokeBall> {
|
||||
// <editor-fold desc="Registry definitions">
|
||||
override val type = PackType.SERVER_DATA
|
||||
override val resourcePath = "pokeballs"
|
||||
override val id = cobblemonResource(resourcePath)
|
||||
override val observable = SimpleObservable<PokeBalls>()
|
||||
override val typeToken: TypeToken<PokeBall> = TypeToken.get(PokeBall::class.java)
|
||||
|
||||
// ToDo once datapack pokeball is implemented add required adapters here
|
||||
override val gson: Gson = GsonBuilder()
|
||||
override fun setupParser(registry: HolderLookup.Provider): Gson = GsonBuilder()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
|
||||
.registerTypeAdapter(MinMaxBounds.Doubles::class.java, FloatNumberRangeAdapter)
|
||||
.registerTypeAdapter(CatchRateModifier::class.java, CobblemonCatchRateModifierAdapter)
|
||||
.registerTypeAdapter(CaptureEffect::class.java, CobblemonCaptureEffectAdapter)
|
||||
.registerTypeAdapter(Color::class.java, LiteralHexColorAdapter)
|
||||
.registerTypeAdapter(PokeBall::class.java, PokeBallAdapter)
|
||||
.registerTypeAdapterFactory(OptionalTypeAdapterFactory())
|
||||
.registerTypeAdapterFactory(LowerCaseEnumTypeAdapterFactory())
|
||||
.disableHtmlEscaping()
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
override val typeToken: TypeToken<PokeBall> = TypeToken.get(PokeBall::class.java)
|
||||
override val resourcePath = "pokeballs"
|
||||
|
||||
private val defaults = hashMapOf<ResourceLocation, PokeBall>()
|
||||
// ToDo datapack pokeball type here instead
|
||||
private val custom = hashMapOf<ResourceLocation, PokeBall>()
|
||||
private val entries = hashMapOf<ResourceLocation, PokeBall>()
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold desc="Default balls">
|
||||
@JvmStatic
|
||||
@get:JvmName("getPokeBall")
|
||||
val POKE_BALL
|
||||
get() = this.byName("poke_ball")
|
||||
get() = getPokeBall("poke_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getSlateBall")
|
||||
val SLATE_BALL
|
||||
get() = this.byName("slate_ball")
|
||||
get() = getPokeBall("slate_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAzureBall")
|
||||
val AZURE_BALL
|
||||
get() = this.byName("azure_ball")
|
||||
get() = getPokeBall("azure_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getVerdantBall")
|
||||
val VERDANT_BALL
|
||||
get() = this.byName("verdant_ball")
|
||||
get() = getPokeBall("verdant_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getRoseateBall")
|
||||
val ROSEATE_BALL
|
||||
get() = this.byName("roseate_ball")
|
||||
get() = getPokeBall("roseate_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getCitrineBall")
|
||||
val CITRINE_BALL
|
||||
get() = this.byName("citrine_ball")
|
||||
get() = getPokeBall("citrine_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getGreatBall")
|
||||
val GREAT_BALL
|
||||
get() = this.byName("great_ball")
|
||||
get() = getPokeBall("great_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getUltraBall")
|
||||
val ULTRA_BALL
|
||||
get() = this.byName("ultra_ball")
|
||||
get() = getPokeBall("ultra_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getMasterBall")
|
||||
val MASTER_BALL
|
||||
get() = this.byName("master_ball")
|
||||
get() = getPokeBall("master_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getSafariBall")
|
||||
val SAFARI_BALL
|
||||
get() = this.byName("safari_ball")
|
||||
get() = getPokeBall("safari_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getFastBall")
|
||||
val FAST_BALL
|
||||
get() = this.byName("fast_ball")
|
||||
get() = getPokeBall("fast_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getLevelBall")
|
||||
val LEVEL_BALL
|
||||
get() = this.byName("level_ball")
|
||||
get() = getPokeBall("level_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getLureBall")
|
||||
val LURE_BALL
|
||||
get() = this.byName("lure_ball")
|
||||
get() = getPokeBall("lure_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getHeavyBall")
|
||||
val HEAVY_BALL
|
||||
get() = this.byName("heavy_ball")
|
||||
get() = getPokeBall("heavy_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getLoveBall")
|
||||
val LOVE_BALL
|
||||
get() = this.byName("love_ball")
|
||||
get() = getPokeBall("love_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getFriendBall")
|
||||
val FRIEND_BALL
|
||||
get() = this.byName("friend_ball")
|
||||
get() = getPokeBall("friend_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getMoonBall")
|
||||
val MOON_BALL
|
||||
get() = this.byName("moon_ball")
|
||||
get() = getPokeBall("moon_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getSportBall")
|
||||
val SPORT_BALL
|
||||
get() = this.byName("sport_ball")
|
||||
get() = getPokeBall("sport_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getNetBall")
|
||||
val NET_BALL
|
||||
get() = this.byName("net_ball")
|
||||
get() = getPokeBall("net_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getDiveBall")
|
||||
val DIVE_BALL
|
||||
get() = this.byName("dive_ball")
|
||||
get() = getPokeBall("dive_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getNestBall")
|
||||
val NEST_BALL
|
||||
get() = this.byName("nest_ball")
|
||||
get() = getPokeBall("nest_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getRepeatBall")
|
||||
val REPEAT_BALL
|
||||
get() = this.byName("repeat_ball")
|
||||
get() = getPokeBall("repeat_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getTimerBall")
|
||||
val TIMER_BALL
|
||||
get() = this.byName("timer_ball")
|
||||
get() = getPokeBall("timer_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getLuxuryBall")
|
||||
val LUXURY_BALL
|
||||
get() = this.byName("luxury_ball")
|
||||
get() = getPokeBall("luxury_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getPremierBall")
|
||||
val PREMIER_BALL
|
||||
get() = this.byName("premier_ball")
|
||||
get() = getPokeBall("premier_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getDuskBall")
|
||||
val DUSK_BALL
|
||||
get() = this.byName("dusk_ball")
|
||||
get() = getPokeBall("dusk_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getHealBall")
|
||||
val HEAL_BALL
|
||||
get() = this.byName("heal_ball")
|
||||
get() = getPokeBall("heal_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getQuickBall")
|
||||
val QUICK_BALL
|
||||
get() = this.byName("quick_ball")
|
||||
get() = getPokeBall("quick_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getCherishBall")
|
||||
val CHERISH_BALL
|
||||
get() = this.byName("cherish_ball")
|
||||
get() = getPokeBall("cherish_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getParkBall")
|
||||
val PARK_BALL
|
||||
get() = this.byName("park_ball")
|
||||
get() = getPokeBall("park_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getDreamBall")
|
||||
val DREAM_BALL
|
||||
get() = this.byName("dream_ball")
|
||||
get() = getPokeBall("dream_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getBeastBall")
|
||||
val BEAST_BALL
|
||||
get() = this.byName("beast_ball")
|
||||
get() = getPokeBall("beast_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientPokeBall")
|
||||
val ANCIENT_POKE_BALL
|
||||
get() = this.byName("ancient_poke_ball")
|
||||
get() = getPokeBall("ancient_poke_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientCitrineBall")
|
||||
val ANCIENT_CITRINE_BALL
|
||||
get() = this.byName("ancient_citrine_ball")
|
||||
get() = getPokeBall("ancient_citrine_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientVerdantBall")
|
||||
val ANCIENT_VERDANT_BALL
|
||||
get() = this.byName("ancient_verdant_ball")
|
||||
get() = getPokeBall("ancient_verdant_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientAzureBall")
|
||||
val ANCIENT_AZURE_BALL
|
||||
get() = this.byName("ancient_azure_ball")
|
||||
get() = getPokeBall("ancient_azure_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientRoseateBall")
|
||||
val ANCIENT_ROSEATE_BALL
|
||||
get() = this.byName("ancient_roseate_ball")
|
||||
get() = getPokeBall("ancient_roseate_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientSlateBall")
|
||||
val ANCIENT_SLATE_BALL
|
||||
get() = this.byName("ancient_slate_ball")
|
||||
get() = getPokeBall("ancient_slate_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientIvoryBall")
|
||||
val ANCIENT_IVORY_BALL
|
||||
get() = this.byName("ancient_ivory_ball")
|
||||
get() = getPokeBall("ancient_ivory_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientGreatBall")
|
||||
val ANCIENT_GREAT_BALL
|
||||
get() = this.byName("ancient_great_ball")
|
||||
get() = getPokeBall("ancient_great_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientUltraBall")
|
||||
val ANCIENT_ULTRA_BALL
|
||||
get() = this.byName("ancient_ultra_ball")
|
||||
get() = getPokeBall("ancient_ultra_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientHeavyBall")
|
||||
val ANCIENT_HEAVY_BALL
|
||||
get() = this.byName("ancient_heavy_ball")
|
||||
get() = getPokeBall("ancient_heavy_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientLeadenBall")
|
||||
val ANCIENT_LEADEN_BALL
|
||||
get() = this.byName("ancient_leaden_ball")
|
||||
get() = getPokeBall("ancient_leaden_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientGigatonBall")
|
||||
val ANCIENT_GIGATON_BALL
|
||||
get() = this.byName("ancient_gigaton_ball")
|
||||
get() = getPokeBall("ancient_gigaton_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientFeatherBall")
|
||||
val ANCIENT_FEATHER_BALL
|
||||
get() = this.byName("ancient_feather_ball")
|
||||
get() = getPokeBall("ancient_feather_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientWingBall")
|
||||
val ANCIENT_WING_BALL
|
||||
get() = this.byName("ancient_wing_ball")
|
||||
get() = getPokeBall("ancient_wing_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientJetBall")
|
||||
val ANCIENT_JET_BALL
|
||||
get() = this.byName("ancient_jet_ball")
|
||||
get() = getPokeBall("ancient_jet_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getAncientOriginBall")
|
||||
val ANCIENT_ORIGIN_BALL
|
||||
get() = this.byName("ancient_origin_ball")
|
||||
get() = getPokeBall("ancient_origin_ball")
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("getStrangeBall")
|
||||
val STRANGE_BALL = create("strange_ball")
|
||||
// </editor-fold>
|
||||
|
||||
init {
|
||||
createDefault("poke_ball")
|
||||
createDefault("slate_ball")
|
||||
createDefault("azure_ball")
|
||||
createDefault("verdant_ball")
|
||||
createDefault("roseate_ball")
|
||||
createDefault("citrine_ball")
|
||||
createDefault("great_ball", MultiplierModifier(1.5F))
|
||||
createDefault("ultra_ball", MultiplierModifier(2F))
|
||||
createDefault("master_ball", GuaranteedModifier())
|
||||
createDefault("safari_ball", CatchRateModifiers.SAFARI)
|
||||
createDefault("fast_ball", BaseStatModifier(Stats.SPEED, { it >= 100 }, 4F))
|
||||
createDefault("level_ball", CatchRateModifiers.LEVEL)
|
||||
createDefault("lure_ball", CatchRateModifiers.LURE)
|
||||
createDefault("heavy_ball", CatchRateModifiers.WEIGHT_BASED)
|
||||
createDefault("love_ball", CatchRateModifiers.LOVE)
|
||||
createDefault("friend_ball", effects = listOf(CaptureEffects.friendshipSetter(150)))
|
||||
createDefault("moon_ball", CatchRateModifiers.MOON_PHASES)
|
||||
createDefault("sport_ball", MultiplierModifier(1.5F))
|
||||
createDefault("net_ball", CatchRateModifiers.typeBoosting(3F, ElementalTypes.BUG, ElementalTypes.WATER))
|
||||
createDefault("dive_ball", CatchRateModifiers.SUBMERGED_IN_WATER, waterDragValue = 0.99F)
|
||||
createDefault("nest_ball", CatchRateModifiers.NEST)
|
||||
createDefault("repeat_ball", CatchRateModifiers.REPEAT)
|
||||
createDefault("timer_ball", CatchRateModifiers.turnBased { turn -> (1F + turn * (1229F / 4096F)).coerceAtMost(4F) })
|
||||
createDefault("luxury_ball", effects = listOf(FriendshipEarningBoostEffect(2F)))
|
||||
createDefault("premier_ball")
|
||||
createDefault("dusk_ball", CatchRateModifiers.LIGHT_LEVEL)
|
||||
createDefault("heal_ball", effects = listOf(CaptureEffects.FULL_RESTORE))
|
||||
createDefault("quick_ball", CatchRateModifiers.turnBased { turn -> if (turn == 1) 5F else 1F })
|
||||
createDefault("cherish_ball")
|
||||
createDefault("park_ball", CatchRateModifiers.PARK)
|
||||
createDefault("dream_ball", CatchRateModifiers.statusBoosting(4F, Statuses.SLEEP))
|
||||
createDefault("beast_ball", DynamicMultiplierModifier({ _, pokemon -> if (pokemon.hasLabels(CobblemonPokemonLabels.ULTRA_BEAST)) 5F else 0.1F }) { _, _ -> true })
|
||||
createDefault("ancient_poke_ball", ancient = true)
|
||||
createDefault("ancient_citrine_ball", ancient = true)
|
||||
createDefault("ancient_verdant_ball", ancient = true)
|
||||
createDefault("ancient_azure_ball", ancient = true)
|
||||
createDefault("ancient_roseate_ball", ancient = true)
|
||||
createDefault("ancient_slate_ball", ancient = true)
|
||||
createDefault("ancient_ivory_ball", ancient = true)
|
||||
createDefault("ancient_great_ball", MultiplierModifier(1.5F), ancient = true)
|
||||
createDefault("ancient_ultra_ball", MultiplierModifier(2F), ancient = true)
|
||||
createDefault("ancient_heavy_ball", throwPower = 0.75f, ancient = true)
|
||||
createDefault("ancient_leaden_ball", MultiplierModifier(1.5F), throwPower = 0.75f, ancient = true)
|
||||
createDefault("ancient_gigaton_ball", MultiplierModifier(2F), throwPower = 0.75f, ancient = true)
|
||||
createDefault("ancient_feather_ball", throwPower = 2.5f, ancient = true)
|
||||
createDefault("ancient_wing_ball", MultiplierModifier(1.5F), throwPower = 2.5f, ancient = true)
|
||||
createDefault("ancient_jet_ball", MultiplierModifier(2F), throwPower = 2.5f, ancient = true)
|
||||
createDefault("ancient_origin_ball", GuaranteedModifier(), ancient = true)
|
||||
// we need at least one default ball in case of shenanigans
|
||||
create("strange_ball")
|
||||
|
||||
create("safari_ball", CatchRateModifiers.SAFARI)
|
||||
create("fast_ball", BaseStatModifier(Stats.SPEED, 100, BaseStatModifier.Comparator.GTE, 4F))
|
||||
create("level_ball", CatchRateModifiers.LEVEL)
|
||||
create("lure_ball", CatchRateModifiers.LURE)
|
||||
create("heavy_ball", CatchRateModifiers.WEIGHT_BASED)
|
||||
create("love_ball", CatchRateModifiers.LOVE)
|
||||
create("friend_ball", effects = listOf("q.pokemon.set_friendship(150.0)".asExpressionLike()))
|
||||
create("moon_ball", CatchRateModifiers.MOON_PHASES)
|
||||
create("net_ball", CatchRateModifiers.typeBoosting(3F, ElementalTypes.BUG, ElementalTypes.WATER))
|
||||
create("dive_ball", CatchRateModifiers.SUBMERGED_IN_WATER, waterDragValue = 0.99F)
|
||||
create("nest_ball", CatchRateModifiers.NEST)
|
||||
create("repeat_ball", CatchRateModifiers.REPEAT)
|
||||
create("timer_ball", CatchRateModifiers.turnBased { turn -> (1F + turn * (1229F / 4096F)).coerceAtMost(4F) })
|
||||
create("luxury_ball" /*effects = listOf(FriendshipEarningBoostEffect(2F))*/)
|
||||
create("dusk_ball", CatchRateModifiers.LIGHT_LEVEL)
|
||||
create("heal_ball", effects = listOf("q.pokemon.heal()".asExpressionLike()))
|
||||
create("quick_ball", CatchRateModifiers.turnBased { turn -> if (turn == 1) 5F else 1F })
|
||||
create("park_ball", CatchRateModifiers.PARK)
|
||||
create("dream_ball", CatchRateModifiers.statusBoosting(4F, Statuses.SLEEP))
|
||||
create(
|
||||
"beast_ball",
|
||||
DynamicMultiplierModifier({ _, pokemon -> if (pokemon.hasLabels(CobblemonPokemonLabels.ULTRA_BEAST)) 5F else 0.1F }) { _, _ -> true })
|
||||
|
||||
// Luxury ball effect, low priority as it must be triggered before soothe bell as of gen 4
|
||||
CobblemonEvents.FRIENDSHIP_UPDATED.subscribe(priority = Priority.LOW) { event ->
|
||||
if (!event.earned) {
|
||||
@@ -310,235 +365,73 @@ object PokeBalls : JsonDataRegistry<PokeBall> {
|
||||
}
|
||||
}
|
||||
|
||||
override fun reload(data: Map<ResourceLocation, PokeBall>) {
|
||||
this.custom.clear()
|
||||
// ToDo once datapack pokeball is implemented load them here, we will want datapacks to be able to override our default pokeballs too, however they will never be able to disable them
|
||||
override fun reload(
|
||||
data: Map<ResourceLocation, PokeBall>,
|
||||
registry: HolderLookup.Provider
|
||||
) {
|
||||
this.entries.removeIf { it.key != cobblemonResource("strange_ball") }
|
||||
|
||||
data.entries.forEach {
|
||||
val (key, ball) = it
|
||||
ball.name = key
|
||||
when(CobblemonItems.pokeBalls.containsKey(key)) {
|
||||
true -> {
|
||||
val item = CobblemonItems.pokeBalls.get(key)!!
|
||||
item.pokeBall = ball
|
||||
ball.stack = item.defaultInstance
|
||||
}
|
||||
|
||||
false -> {
|
||||
ball.stack = PokeBallComponent.createStack(ball)
|
||||
}
|
||||
}
|
||||
|
||||
this.entries[key] = ball
|
||||
}
|
||||
|
||||
Cobblemon.LOGGER.info("Loaded ${data.size} poke balls.")
|
||||
}
|
||||
|
||||
override fun sync(player: ServerPlayer) {
|
||||
// ToDo once datapack pokeball is implemented sync them here
|
||||
PokeBallsRegistrySyncPacket(this.entries).sendToPlayer(player)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Pokeball from registry name.
|
||||
* @return the pokeball object if found otherwise null.
|
||||
* @return the pokeball object if found otherwise strange ball.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getPokeBall(name : ResourceLocation): PokeBall? = this.custom[name] ?: this.defaults[name]
|
||||
fun getPokeBall(name: ResourceLocation): PokeBall = this.entries[name] ?: STRANGE_BALL
|
||||
|
||||
@JvmStatic
|
||||
fun all() = this.defaults.filterKeys { !this.custom.containsKey(it) }.values + this.custom.values
|
||||
fun getPokeBall(name: String): PokeBall = getPokeBall(cobblemonResource(name))
|
||||
|
||||
private fun createDefault(
|
||||
@JvmStatic
|
||||
fun all() = this.entries.values
|
||||
|
||||
fun create(
|
||||
name: String,
|
||||
modifier: CatchRateModifier = MultiplierModifier(1F) { _, _ -> true },
|
||||
effects: List<CaptureEffect> = emptyList(),
|
||||
modifier: CatchRateModifier = ExpressionModifier(),
|
||||
effects: List<ExpressionLike> = emptyList(),
|
||||
waterDragValue: Float = 0.8F,
|
||||
model2d: ResourceLocation = cobblemonResource(name),
|
||||
model3d: ResourceLocation = cobblemonResource("item/${name}_model"),
|
||||
throwPower: Float = 1.25f,
|
||||
ancient: Boolean = false
|
||||
): PokeBall {
|
||||
val identifier = cobblemonResource(name)
|
||||
val pokeball = PokeBall(identifier, modifier, effects, waterDragValue, model2d, model3d, throwPower, ancient)
|
||||
this.defaults[identifier] = pokeball
|
||||
return pokeball
|
||||
ancient: Boolean = false,
|
||||
color: Color = Color.RED
|
||||
): PokeBall = PokeBall(
|
||||
cobblemonResource(name),
|
||||
modifier,
|
||||
effects,
|
||||
PokeBall.PokeBallProperties(),
|
||||
waterDragValue,
|
||||
model2d,
|
||||
model3d,
|
||||
throwPower,
|
||||
ancient,
|
||||
color
|
||||
).also {
|
||||
this.entries[it.name] = it
|
||||
return it
|
||||
}
|
||||
|
||||
private fun byName(name: String): PokeBall {
|
||||
val identifier = cobblemonResource(name)
|
||||
return this.custom[identifier] ?: this.defaults[identifier]!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility getters
|
||||
*/
|
||||
@JvmName("getPOKE_BALL")
|
||||
@Deprecated("Use PokeBalls.getPokeBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getPOKE_BALL() = POKE_BALL
|
||||
|
||||
@JvmName("getSLATE_BALL")
|
||||
@Deprecated("Use PokeBalls.getSlateBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getSLATE_BALL() = SLATE_BALL
|
||||
|
||||
@JvmName("getAZURE_BALL")
|
||||
@Deprecated("Use PokeBalls.getAzureBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getAZURE_BALL() = AZURE_BALL
|
||||
|
||||
@JvmName("getVERDANT_BALL")
|
||||
@Deprecated("Use PokeBalls.getVerdantBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getVERDANT_BALL() = VERDANT_BALL
|
||||
|
||||
@JvmName("getROSEATE_BALL")
|
||||
@Deprecated("Use PokeBalls.getRoseateBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getROSEATE_BALL() = ROSEATE_BALL
|
||||
|
||||
@JvmName("getCITRINE_BALL")
|
||||
@Deprecated("Use PokeBalls.getCitrineBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getCITRINE_BALL() = CITRINE_BALL
|
||||
|
||||
@JvmName("getGREAT_BALL")
|
||||
@Deprecated("Use PokeBalls.getGreatBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getGREAT_BALL() = GREAT_BALL
|
||||
|
||||
@JvmName("getULTRA_BALL")
|
||||
@Deprecated("Use PokeBalls.getUltraBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getULTRA_BALL() = ULTRA_BALL
|
||||
|
||||
@JvmName("getMASTER_BALL")
|
||||
@Deprecated("Use PokeBalls.getMasterBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getMASTER_BALL() = MASTER_BALL
|
||||
|
||||
@JvmName("getSAFARI_BALL")
|
||||
@Deprecated("Use PokeBalls.getSafariBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getSAFARI_BALL() = SAFARI_BALL
|
||||
|
||||
@JvmName("getFAST_BALL")
|
||||
@Deprecated("Use PokeBalls.getFastBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getFAST_BALL() = FAST_BALL
|
||||
|
||||
@JvmName("getLEVEL_BALL")
|
||||
@Deprecated("Use PokeBalls.getLevelBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getLEVEL_BALL() = LEVEL_BALL
|
||||
|
||||
@JvmName("getLURE_BALL")
|
||||
@Deprecated("Use PokeBalls.getLureBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getLURE_BALL() = LURE_BALL
|
||||
|
||||
@JvmName("getHEAVY_BALL")
|
||||
@Deprecated("Use PokeBalls.getHeavyBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getHEAVY_BALL() = HEAVY_BALL
|
||||
|
||||
@JvmName("getLOVE_BALL")
|
||||
@Deprecated("Use PokeBalls.getLoveBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getLOVE_BALL() = LOVE_BALL
|
||||
|
||||
@JvmName("getFRIEND_BALL")
|
||||
@Deprecated("Use PokeBalls.getFriendBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getFRIEND_BALL() = FRIEND_BALL
|
||||
|
||||
@JvmName("getMOON_BALL")
|
||||
@Deprecated("Use PokeBalls.getMoonBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getMOON_BALL() = MOON_BALL
|
||||
|
||||
@JvmName("getSPORT_BALL")
|
||||
@Deprecated("Use PokeBalls.getSportBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getSPORT_BALL() = SPORT_BALL
|
||||
|
||||
@JvmName("getNET_BALL")
|
||||
@Deprecated("Use PokeBalls.getNetBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getNET_BALL() = NET_BALL
|
||||
|
||||
@JvmName("getNEST_BALL")
|
||||
@Deprecated("Use PokeBalls.getNestBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getNEST_BALL() = NEST_BALL
|
||||
|
||||
@JvmName("getREPEAT_BALL")
|
||||
@Deprecated("Use PokeBalls.getRepeatBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getREPEAT_BALL() = REPEAT_BALL
|
||||
|
||||
@JvmName("getTIMER_BALL")
|
||||
@Deprecated("Use PokeBalls.getTimerBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getTIMER_BALL() = TIMER_BALL
|
||||
|
||||
@JvmName("getLUXURY_BALL")
|
||||
@Deprecated("Use PokeBalls.getLuxuryBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getLUXURY_BALL() = LUXURY_BALL
|
||||
|
||||
@JvmName("getPREMIER_BALL")
|
||||
@Deprecated("Use PokeBalls.getPremierBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getPREMIER_BALL() = PREMIER_BALL
|
||||
|
||||
@JvmName("getDUSK_BALL")
|
||||
@Deprecated("Use PokeBalls.getDuskBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getDUSK_BALL() = DUSK_BALL
|
||||
|
||||
@JvmName("getHEAL_BALL")
|
||||
@Deprecated("Use PokeBalls.getHealBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getHEAL_BALL() = HEAL_BALL
|
||||
|
||||
@JvmName("getQUICK_BALL")
|
||||
@Deprecated("Use PokeBalls.getQuickBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getQUICK_BALL() = QUICK_BALL
|
||||
|
||||
@JvmName("getCHERISH_BALL")
|
||||
@Deprecated("Use PokeBalls.getCherishBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getCHERISH_BALL() = CHERISH_BALL
|
||||
|
||||
@JvmName("getPARK_BALL")
|
||||
@Deprecated("Use PokeBalls.getParkBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getPARK_BALL() = PARK_BALL
|
||||
|
||||
@JvmName("getDREAM_BALL")
|
||||
@Deprecated("Use PokeBalls.getDreamBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getDREAM_BALL() = DREAM_BALL
|
||||
|
||||
@JvmName("getBEAST_BALL")
|
||||
@Deprecated("Use PokeBalls.getBeastBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getBEAST_BALL() = BEAST_BALL
|
||||
|
||||
@JvmName("getANCIENT_POKE_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientPokeBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_POKE_BALL() = ANCIENT_POKE_BALL
|
||||
|
||||
@JvmName("getANCIENT_CITRINE_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientCitrineBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_CITRINE_BALL() = ANCIENT_CITRINE_BALL
|
||||
|
||||
@JvmName("getANCIENT_VERDANT_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientVerdantBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_VERDANT_BALL() = ANCIENT_VERDANT_BALL
|
||||
|
||||
@JvmName("getANCIENT_AZURE_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientAzureBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_AZURE_BALL() = ANCIENT_AZURE_BALL
|
||||
|
||||
@JvmName("getANCIENT_ROSEATE_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientRoseateBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_ROSEATE_BALL() = ANCIENT_ROSEATE_BALL
|
||||
|
||||
@JvmName("getANCIENT_SLATE_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientSlateBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_SLATE_BALL() = ANCIENT_SLATE_BALL
|
||||
|
||||
@JvmName("getANCIENT_IVORY_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientIvoryBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_IVORY_BALL() = ANCIENT_IVORY_BALL
|
||||
|
||||
@JvmName("getANCIENT_GREAT_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientGreatBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_GREAT_BALL() = ANCIENT_GREAT_BALL
|
||||
|
||||
@JvmName("getANCIENT_ULTRA_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientUltraBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_ULTRA_BALL() = ANCIENT_ULTRA_BALL
|
||||
|
||||
@JvmName("getANCIENT_HEAVY_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientHeavyBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_HEAVY_BALL() = ANCIENT_HEAVY_BALL
|
||||
|
||||
@JvmName("getANCIENT_LEADEN_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientLeadenBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_LEADEN_BALL() = ANCIENT_LEADEN_BALL
|
||||
|
||||
@JvmName("getANCIENT_GIGATON_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientGigatonBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_GIGATON_BALL() = ANCIENT_GIGATON_BALL
|
||||
|
||||
@JvmName("getANCIENT_FEATHER_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientFeatherBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_FEATHER_BALL() = ANCIENT_FEATHER_BALL
|
||||
|
||||
@JvmName("getANCIENT_WING_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientWingBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_WING_BALL() = ANCIENT_WING_BALL
|
||||
|
||||
@JvmName("getANCIENT_JET_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientJetBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_JET_BALL() = ANCIENT_JET_BALL
|
||||
|
||||
@JvmName("getANCIENT_ORIGIN_BALL")
|
||||
@Deprecated("Use PokeBalls.getAncientOriginBall(), provided for backwards compatibility until Cobblemon 1.8.")
|
||||
fun getANCIENT_ORIGIN_BALL() = ANCIENT_ORIGIN_BALL
|
||||
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -18,6 +18,10 @@ import net.minecraft.world.entity.LivingEntity
|
||||
*
|
||||
* @property multiplier The multiplier for friendship gains
|
||||
*/
|
||||
class FriendshipEarningBoostEffect(val multiplier: Float) : CaptureEffect {
|
||||
data class FriendshipEarningBoostEffect(val multiplier: Float) : CaptureEffect {
|
||||
companion object {
|
||||
const val VARIANT = "friendship_boost"
|
||||
}
|
||||
|
||||
override fun apply(thrower: LivingEntity, pokemon: Pokemon) {}
|
||||
}
|
||||
}
|
||||
+36
-4
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.api.pokeball.catching.modifiers
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.CatchRateModifier
|
||||
import com.cobblemon.mod.common.api.pokemon.stats.Stat
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.util.StringRepresentable
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
/**
|
||||
@@ -26,9 +27,13 @@ import net.minecraft.world.entity.LivingEntity
|
||||
*/
|
||||
class BaseStatModifier(
|
||||
val stat: Stat,
|
||||
val comparator: (value: Int) -> Boolean,
|
||||
val multiplier: Float
|
||||
val value: Int,
|
||||
val comparator: Comparator,
|
||||
val multiplier: Float,
|
||||
) : CatchRateModifier {
|
||||
companion object {
|
||||
const val VARIANT = "bst"
|
||||
}
|
||||
|
||||
init {
|
||||
if (stat.type != Stat.Type.PERMANENT) {
|
||||
@@ -44,9 +49,36 @@ class BaseStatModifier(
|
||||
|
||||
override fun isValid(thrower: LivingEntity, pokemon: Pokemon): Boolean {
|
||||
val valStat = pokemon.form.baseStats[this.stat] ?: return false
|
||||
return comparator(valStat)
|
||||
return when (comparator) {
|
||||
Comparator.GT -> value > valStat
|
||||
Comparator.LT -> value < valStat
|
||||
Comparator.GTE -> value >= valStat
|
||||
Comparator.LTE -> value <= valStat
|
||||
Comparator.EQ -> value == valStat
|
||||
Comparator.NOT -> value != valStat
|
||||
}
|
||||
}
|
||||
|
||||
override fun modifyCatchRate(currentCatchRate: Float, thrower: LivingEntity, pokemon: Pokemon): Float = this.behavior(thrower, pokemon).mutator(currentCatchRate, this.value(thrower, pokemon))
|
||||
override fun modifyCatchRate(
|
||||
currentCatchRate: Float,
|
||||
thrower: LivingEntity,
|
||||
pokemon: Pokemon,
|
||||
): Float = this.behavior(thrower, pokemon).mutator(currentCatchRate, this.value(thrower, pokemon))
|
||||
|
||||
enum class Comparator : StringRepresentable {
|
||||
@JvmField
|
||||
GT,
|
||||
@JvmField
|
||||
LT,
|
||||
@JvmField
|
||||
GTE,
|
||||
@JvmField
|
||||
LTE,
|
||||
@JvmField
|
||||
EQ,
|
||||
@JvmField
|
||||
NOT,
|
||||
;
|
||||
override fun getSerializedName(): String = this.name.lowercase()
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.api.pokeball.catching.modifiers
|
||||
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asBiomeMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asStruct
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asWorldMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.CatchRateModifier
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.toBlockPos
|
||||
import com.cobblemon.mod.common.util.withPlayerValue
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class ExpressionModifier(
|
||||
val query: ExpressionLike = "1.0".asExpressionLike(),
|
||||
) : CatchRateModifier {
|
||||
companion object {
|
||||
const val VARIANT = "expression"
|
||||
val runtime = MoLangRuntime().setup()
|
||||
}
|
||||
|
||||
override fun isGuaranteed(): Boolean = false
|
||||
|
||||
override fun value(
|
||||
thrower: LivingEntity,
|
||||
pokemon: Pokemon
|
||||
): Float {
|
||||
if (query.getString().trim() == "1.0") return 1.0f
|
||||
|
||||
val biomeValue = thrower.level().getBiome(thrower.position().toBlockPos()).asBiomeMoLangValue()
|
||||
|
||||
val worldValue = thrower
|
||||
.level()
|
||||
.registryAccess()
|
||||
.registryOrThrow(Registries.DIMENSION)
|
||||
.wrapAsHolder(thrower.level())
|
||||
.asWorldMoLangValue()
|
||||
|
||||
val ballRuntime = runtime
|
||||
.withQueryValue("world", worldValue)
|
||||
.withQueryValue("biome", biomeValue)
|
||||
.withQueryValue("pokemon", pokemon.asStruct())
|
||||
.let { if (thrower is ServerPlayer) it.withPlayerValue("player", thrower) else it }
|
||||
|
||||
return query.resolveFloat(ballRuntime)
|
||||
}
|
||||
|
||||
override fun behavior(
|
||||
thrower: LivingEntity,
|
||||
pokemon: Pokemon
|
||||
): CatchRateModifier.Behavior = CatchRateModifier.Behavior.MULTIPLY
|
||||
|
||||
override fun isValid(
|
||||
thrower: LivingEntity,
|
||||
pokemon: Pokemon
|
||||
): Boolean = true
|
||||
|
||||
override fun modifyCatchRate(
|
||||
currentCatchRate: Float,
|
||||
thrower: LivingEntity,
|
||||
pokemon: Pokemon
|
||||
): Float = this.behavior(thrower, pokemon).mutator(currentCatchRate, this.value(thrower, pokemon))
|
||||
}
|
||||
+4
-2
@@ -19,11 +19,13 @@ import net.minecraft.world.entity.LivingEntity
|
||||
* @since August 9th, 2022
|
||||
*/
|
||||
class GuaranteedModifier : CatchRateModifier {
|
||||
|
||||
companion object {
|
||||
const val VARIANT = "guaranteed"
|
||||
}
|
||||
override fun isGuaranteed() = true
|
||||
override fun value(thrower: LivingEntity, pokemon: Pokemon): Float = 255F
|
||||
override fun behavior(thrower: LivingEntity, pokemon: Pokemon): CatchRateModifier.Behavior = CatchRateModifier.Behavior.MULTIPLY
|
||||
override fun isValid(thrower: LivingEntity, pokemon: Pokemon): Boolean = true
|
||||
override fun modifyCatchRate(currentCatchRate: Float, thrower: LivingEntity, pokemon: Pokemon): Float = this.behavior(thrower, pokemon).mutator(currentCatchRate, this.value(thrower, pokemon))
|
||||
|
||||
}
|
||||
}
|
||||
+11
-9
@@ -22,20 +22,22 @@ import net.minecraft.world.entity.LivingEntity
|
||||
* @property matching Will this multiplier should be applied if the labels match?
|
||||
* @property labels The literal labels being queried.
|
||||
*/
|
||||
class LabelModifier(
|
||||
val multiplier: Float,
|
||||
val matching: Boolean,
|
||||
vararg val labels: String
|
||||
) : CatchRateModifier {
|
||||
data class LabelModifier(val multiplier: Float, val matching: Boolean, val labels: List<String>) : CatchRateModifier {
|
||||
companion object {
|
||||
const val VARIANT = "labels"
|
||||
}
|
||||
|
||||
override fun isGuaranteed(): Boolean = false
|
||||
|
||||
override fun value(thrower: LivingEntity, pokemon: Pokemon): Float = this.multiplier
|
||||
|
||||
override fun behavior(thrower: LivingEntity, pokemon: Pokemon): CatchRateModifier.Behavior = CatchRateModifier.Behavior.MULTIPLY
|
||||
override fun behavior(thrower: LivingEntity, pokemon: Pokemon): CatchRateModifier.Behavior =
|
||||
CatchRateModifier.Behavior.MULTIPLY
|
||||
|
||||
override fun isValid(thrower: LivingEntity, pokemon: Pokemon): Boolean = if (this.matching) pokemon.hasLabels(*this.labels) else !pokemon.hasLabels(*this.labels)
|
||||
override fun isValid(thrower: LivingEntity, pokemon: Pokemon): Boolean =
|
||||
if (this.matching) pokemon.hasLabels(*this.labels.toSet().toTypedArray()) else !pokemon.hasLabels(*this.labels.toSet().toTypedArray())
|
||||
|
||||
override fun modifyCatchRate(currentCatchRate: Float, thrower: LivingEntity, pokemon: Pokemon): Float = this.behavior(thrower, pokemon).mutator(currentCatchRate, this.value(thrower, pokemon))
|
||||
override fun modifyCatchRate(currentCatchRate: Float, thrower: LivingEntity, pokemon: Pokemon): Float =
|
||||
this.behavior(thrower, pokemon).mutator(currentCatchRate, this.value(thrower, pokemon))
|
||||
|
||||
}
|
||||
}
|
||||
+8
-6
@@ -13,19 +13,21 @@ import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class PropertyBasedModifier(
|
||||
val property: PokemonProperties,
|
||||
val multiplier: Float
|
||||
) : CatchRateModifier {
|
||||
data class PropertyBasedModifier(val property: PokemonProperties, val multiplier: Float) : CatchRateModifier {
|
||||
companion object {
|
||||
const val VARIANT = "property"
|
||||
}
|
||||
|
||||
override fun isGuaranteed(): Boolean = false
|
||||
|
||||
override fun value(thrower: LivingEntity, pokemon: Pokemon): Float = this.multiplier
|
||||
|
||||
override fun behavior(thrower: LivingEntity, pokemon: Pokemon): CatchRateModifier.Behavior = CatchRateModifier.Behavior.MULTIPLY
|
||||
override fun behavior(thrower: LivingEntity, pokemon: Pokemon): CatchRateModifier.Behavior =
|
||||
CatchRateModifier.Behavior.MULTIPLY
|
||||
|
||||
override fun isValid(thrower: LivingEntity, pokemon: Pokemon): Boolean = this.property.matches(pokemon)
|
||||
|
||||
override fun modifyCatchRate(currentCatchRate: Float, thrower: LivingEntity, pokemon: Pokemon): Float = this.behavior(thrower, pokemon).mutator(currentCatchRate, this.value(thrower, pokemon))
|
||||
override fun modifyCatchRate(currentCatchRate: Float, thrower: LivingEntity, pokemon: Pokemon): Float =
|
||||
this.behavior(thrower, pokemon).mutator(currentCatchRate, this.value(thrower, pokemon))
|
||||
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.pokeball.catching.modifiers
|
||||
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asBiomeMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asStruct
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asWorldMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.CatchRateModifier
|
||||
import com.cobblemon.mod.common.api.scripting.CobblemonScripts
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.asExpressionLike
|
||||
import com.cobblemon.mod.common.util.toBlockPos
|
||||
import com.cobblemon.mod.common.util.withPlayerValue
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
class ScriptModifier(
|
||||
val location: ResourceLocation
|
||||
) : CatchRateModifier {
|
||||
companion object {
|
||||
const val VARIANT = "script"
|
||||
val runtime = MoLangRuntime().setup()
|
||||
}
|
||||
|
||||
override fun isGuaranteed(): Boolean = false
|
||||
|
||||
override fun value(
|
||||
thrower: LivingEntity,
|
||||
pokemon: Pokemon
|
||||
): Float {
|
||||
val worldValue =
|
||||
thrower
|
||||
.level()
|
||||
.registryAccess()
|
||||
.registryOrThrow(Registries.DIMENSION)
|
||||
.wrapAsHolder(thrower.level())
|
||||
.asWorldMoLangValue()
|
||||
|
||||
val biomeValue = thrower.level().getBiome(thrower.position().toBlockPos()).asBiomeMoLangValue()
|
||||
|
||||
var ballRuntime = runtime
|
||||
.withQueryValue("world", worldValue)
|
||||
.withQueryValue("biome", biomeValue)
|
||||
.withQueryValue("pokemon", pokemon.asStruct())
|
||||
|
||||
if (thrower is ServerPlayer) {
|
||||
ballRuntime = ballRuntime.withPlayerValue("player", thrower)
|
||||
}
|
||||
|
||||
return CobblemonScripts.run(location, ballRuntime)?.asDouble()?.toFloat() ?: 0.0f
|
||||
}
|
||||
|
||||
override fun behavior(
|
||||
thrower: LivingEntity,
|
||||
pokemon: Pokemon
|
||||
): CatchRateModifier.Behavior = CatchRateModifier.Behavior.MULTIPLY
|
||||
|
||||
override fun isValid(
|
||||
thrower: LivingEntity,
|
||||
pokemon: Pokemon
|
||||
): Boolean = true
|
||||
|
||||
override fun modifyCatchRate(
|
||||
currentCatchRate: Float,
|
||||
thrower: LivingEntity,
|
||||
pokemon: Pokemon
|
||||
): Float = this.behavior(thrower, pokemon).mutator(currentCatchRate, this.value(thrower, pokemon))
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.pokeball.catching.modifiers
|
||||
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.CatchRateModifier
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
|
||||
data class SimpleModifier(val value: Float) : CatchRateModifier {
|
||||
companion object {
|
||||
const val VARIANT = "simple"
|
||||
}
|
||||
|
||||
override fun isGuaranteed(): Boolean = false
|
||||
|
||||
override fun value(thrower: LivingEntity, pokemon: Pokemon): Float = this.value
|
||||
|
||||
override fun behavior(thrower: LivingEntity, pokemon: Pokemon): CatchRateModifier.Behavior =
|
||||
CatchRateModifier.Behavior.MULTIPLY
|
||||
|
||||
override fun isValid(thrower: LivingEntity, pokemon: Pokemon): Boolean = true
|
||||
|
||||
override fun modifyCatchRate(
|
||||
currentCatchRate: Float,
|
||||
thrower: LivingEntity,
|
||||
pokemon: Pokemon,
|
||||
): Float = behavior(thrower, pokemon).mutator(currentCatchRate, value(thrower, pokemon))
|
||||
}
|
||||
@@ -25,7 +25,9 @@ import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
|
||||
import com.cobblemon.mod.common.api.tags.CobblemonItemTags
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.item.PokeBallItem
|
||||
import com.cobblemon.mod.common.item.components.PokeBallComponent
|
||||
import com.cobblemon.mod.common.net.messages.client.animation.PlayPosableAnimationPacket
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.pokemon.activestate.ShoulderedState
|
||||
import com.cobblemon.mod.common.pokemon.evolution.variants.ItemInteractionEvolution
|
||||
@@ -138,7 +140,7 @@ interface Evolution : EvolutionLike {
|
||||
val shedPokemon = pokemon.clone(registryAccess = owner.registryAccess())
|
||||
shedPokemon.removeHeldItem()
|
||||
innerShedder.apply(shedPokemon)
|
||||
shedPokemon.caughtBall = ((pokeballStack?.item ?: CobblemonItems.POKE_BALL) as PokeBallItem).pokeBall
|
||||
shedPokemon.caughtBall = pokeballStack?.let { PokeBallComponent.getPokeBall(it) } ?: CobblemonItems.STRANGE_BALL.pokeBall
|
||||
pokemon.storeCoordinates.get()?.store?.add(shedPokemon)
|
||||
CobblemonCriteria.EVOLVE_POKEMON.trigger(owner, EvolvePokemonContext(pokemon.preEvolution!!.species.resourceIdentifier, shedPokemon.species.resourceIdentifier, playerDataManager.getGenericData(owner).advancementData.totalEvolvedCount))
|
||||
// Consume one of the balls (if the player isn't creative)
|
||||
|
||||
+2
-2
@@ -145,7 +145,7 @@ class ReforgedConversion(val base: Path) : CobblemonConverter<CompoundTag> {
|
||||
// result.nickname = this.find(nbt, "Nickname", NbtCompound::getString)
|
||||
|
||||
val ball = this.find(nbt, "CaughtBall", CompoundTag::getString)
|
||||
result.caughtBall = if(ball != null) PokeBalls.getPokeBall(ResourceLocation.parse(ball)) ?: PokeBalls.POKE_BALL else PokeBalls.POKE_BALL
|
||||
result.caughtBall = if(ball != null) PokeBalls.getPokeBall(ResourceLocation.parse(ball)) else PokeBalls.STRANGE_BALL
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -190,4 +190,4 @@ class ReforgedConversion(val base: Path) : CobblemonConverter<CompoundTag> {
|
||||
CAREFUL,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,6 @@ import com.cobblemon.mod.common.net.messages.client.storage.pc.InitializePCPacke
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.MoveClientPCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCPokemonPacket
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.UnlockPCBoxWallpaperPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePCPokemonBatchPacket
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.DataKeys
|
||||
import com.cobblemon.mod.common.util.asTranslated
|
||||
@@ -271,34 +270,6 @@ open class PCStore(
|
||||
}
|
||||
}
|
||||
|
||||
fun moveBatch(moves: List<Triple<UUID, PCPosition, PCPosition>>): Boolean {
|
||||
if (moves.isEmpty() || moves.size > MovePCPokemonBatchPacket.MAX_MOVES) return false
|
||||
if (moves.map { it.second }.toSet().size != moves.size ||
|
||||
moves.map { it.third }.toSet().size != moves.size ||
|
||||
moves.map { it.first }.toSet().size != moves.size
|
||||
) return false
|
||||
if (moves.any { (_, source, target) -> !isValidPosition(source) || !isValidPosition(target) }) return false
|
||||
|
||||
val sourcePositions = moves.mapTo(mutableSetOf()) { it.second }
|
||||
val pokemonMoves = moves.map { (pokemonID, source, target) ->
|
||||
val pokemon = get(source)?.takeIf { it.uuid == pokemonID } ?: return false
|
||||
Triple(source, target, pokemon)
|
||||
}
|
||||
if (pokemonMoves.any { (_, target, _) -> get(target) != null && target !in sourcePositions }) return false
|
||||
|
||||
pokemonMoves.forEach { (source, _, _) -> setAtPosition(source, null) }
|
||||
pokemonMoves.forEach { (_, target, pokemon) -> setAtPosition(target, pokemon) }
|
||||
|
||||
pokemonMoves.forEach { (_, _, pokemon) ->
|
||||
sendPacketToObservers(RemoveClientPokemonPacket(this, pokemon.uuid))
|
||||
}
|
||||
pokemonMoves.forEach { (_, target, pokemon) ->
|
||||
sendPacketToObservers(SetPCPokemonPacket(uuid, target) { pokemon })
|
||||
}
|
||||
pcChangeObservable.emit(Unit)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun loadPositionFromNBT(nbt: CompoundTag): StoreCoordinates<PCPosition> {
|
||||
return StoreCoordinates(this, PCPosition(nbt.getShort(DataKeys.STORE_BOX).toInt(), nbt.getByte(DataKeys.STORE_SLOT).toInt()))
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.InteractionResult
|
||||
import net.minecraft.world.entity.EntityType
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.Item
|
||||
@@ -32,9 +31,13 @@ import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
import net.minecraft.world.item.context.BlockPlaceContext
|
||||
import net.minecraft.world.level.BlockGetter
|
||||
import net.minecraft.world.level.CollisionGetter
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.*
|
||||
import net.minecraft.world.level.block.BaseEntityBlock
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.HorizontalDirectionalBlock
|
||||
import net.minecraft.world.level.block.Mirror
|
||||
import net.minecraft.world.level.block.RenderShape
|
||||
import net.minecraft.world.level.block.Rotation
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
@@ -45,11 +48,9 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty
|
||||
import net.minecraft.world.level.block.state.properties.Property
|
||||
import net.minecraft.world.level.pathfinder.PathComputationType
|
||||
import net.minecraft.world.phys.BlockHitResult
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import net.minecraft.world.phys.shapes.CollisionContext
|
||||
import net.minecraft.world.phys.shapes.Shapes
|
||||
import net.minecraft.world.phys.shapes.VoxelShape
|
||||
import java.util.Optional
|
||||
|
||||
@Suppress("DEPRECATED", "OVERRIDE_DEPRECATION")
|
||||
class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
|
||||
@@ -78,14 +79,6 @@ class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
|
||||
const val MAX_CHARGE_LEVEL = 5
|
||||
val CHARGE_LEVEL: IntegerProperty = IntegerProperty.create("charge", 0, MAX_CHARGE_LEVEL + 1)
|
||||
val NATURAL: BooleanProperty = BooleanProperty.create("natural")
|
||||
|
||||
fun canSetSpawn(level: Level): Boolean {
|
||||
return level.gameRules.getBoolean(CobblemonGameRules.HEALER_SET_SPAWN)
|
||||
}
|
||||
|
||||
fun findStandUpPosition(entityType: EntityType<*>, level: CollisionGetter, pos: BlockPos): Optional<Vec3> {
|
||||
return RespawnAnchorBlock.findStandUpPosition(entityType, level, pos) // Exists if we ever want to make something more custom, but anchor block logic should suffice
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
@@ -165,12 +158,7 @@ class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
|
||||
}
|
||||
val party = serverPlayerEntity.party()
|
||||
val pc = serverPlayerEntity.pc()
|
||||
val healPC = player.level().gameRules.getBoolean(CobblemonGameRules.HEALERS_HEAL_PC)
|
||||
|
||||
// Do spawnpoint stuff
|
||||
if (canSetSpawn(world)) {
|
||||
player.setRespawnPosition(world.dimension(), blockPos, player.yRot, false, true)
|
||||
}
|
||||
val healPC = player.level().gameRules.getBoolean(CobblemonGameRules.HEALERS_HEAL_PC);
|
||||
|
||||
if (party.none() && (!healPC || pc.none())) {
|
||||
player.sendSystemMessage(lang("healingmachine.nopokemon").red(), true)
|
||||
@@ -195,7 +183,6 @@ class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
|
||||
player.sendSystemMessage(lang("healingmachine.notenoughcharge", "${((neededCharge/party.count())*100f).toInt()}%").red(), true)
|
||||
}
|
||||
party.forEach { it.tryRecallWithAnimation() }
|
||||
|
||||
return InteractionResult.CONSUME
|
||||
}
|
||||
|
||||
|
||||
@@ -160,8 +160,8 @@ class TypeGemClusterBlock(
|
||||
&& state.getValue(STAGE) == 3) return false
|
||||
|
||||
val supportPos = pos.relative(state.getValue(FACING).opposite)
|
||||
val supportState = level.getBlockState(supportPos)
|
||||
return supportState.`is`(CobblemonBlockTags.TYPE_GEM_BLOCKS) || supportState.block == CobblemonBlocks.TYPE_GEM_CORE // Cannot grow if not on any gem blocks
|
||||
val supportBlock = level.getBlockState(supportPos).block
|
||||
return CobblemonBlocks.typeGemBlocks().containsValue(supportBlock) || (supportBlock == CobblemonBlocks.TYPE_GEM_CORE) // Cannot grow if not on any gem blocks
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,20 +51,10 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
|
||||
ResourceLocation.parse("cobblemon:dragon_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_DRAGON,
|
||||
ResourceLocation.parse("cobblemon:dark_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_DARK,
|
||||
ResourceLocation.parse("cobblemon:steel_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_STEEL,
|
||||
ResourceLocation.parse("cobblemon:fairy_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_FAIRY,
|
||||
ResourceLocation.parse("minecraft:amethyst_block") to Blocks.SMALL_AMETHYST_BUD
|
||||
ResourceLocation.parse("cobblemon:fairy_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_FAIRY
|
||||
)
|
||||
}
|
||||
|
||||
val AMETHYST_STAGES = listOf(
|
||||
Blocks.SMALL_AMETHYST_BUD,
|
||||
Blocks.MEDIUM_AMETHYST_BUD,
|
||||
Blocks.LARGE_AMETHYST_BUD,
|
||||
Blocks.AMETHYST_CLUSTER
|
||||
)
|
||||
|
||||
private fun isAmethystStage(block: Block) = block in AMETHYST_STAGES
|
||||
|
||||
fun getConnectedGemBlocks(level: BlockGetter, pos: BlockPos): List<Pair<BlockState, BlockPos>> {
|
||||
val connectedGems = mutableListOf<Pair<BlockState, BlockPos>>()
|
||||
val visited = mutableSetOf<BlockPos>()
|
||||
@@ -95,16 +85,12 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
|
||||
Direction.entries.forEach {
|
||||
if (random.nextFloat() < Cobblemon.config.typeGemGrowthChance) {
|
||||
val faceState = level.getBlockState(pos.relative(it))
|
||||
var newState = BLOCK_TO_CLUSTER[BuiltInRegistries.BLOCK.getKey(state.block)]?.defaultBlockState()
|
||||
val randomGrowthType = decideClusterGrowthType(level, pos)
|
||||
val newState = BLOCK_TO_CLUSTER[BuiltInRegistries.BLOCK.getKey(state.block)]?.defaultBlockState()
|
||||
?.setValue(DirectionalBlock.FACING, it)
|
||||
?.setValue(GROWTH_TYPE, randomGrowthType)
|
||||
?: return
|
||||
|
||||
if (newState.hasProperty(GROWTH_TYPE)) {
|
||||
newState = newState.setValue(GROWTH_TYPE, decideClusterGrowthType(level, pos))
|
||||
} else if (getConnectedGemBlocks(level, pos).size > Cobblemon.config.typeGemMaxConnected) {
|
||||
return@forEach
|
||||
}
|
||||
|
||||
if (faceState.`is`(Blocks.AIR)) {
|
||||
level.setBlock(pos.relative(it), newState, 3)
|
||||
}
|
||||
@@ -146,7 +132,7 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
|
||||
if (!visited.add(clusterPos)) continue
|
||||
|
||||
val clusterState = level.getBlockState(clusterPos)
|
||||
if (clusterState.block == expectedCluster && clusterState.hasProperty(GROWTH_TYPE)) {
|
||||
if (clusterState.block == expectedCluster) {
|
||||
clusters += clusterState to clusterPos
|
||||
}
|
||||
}
|
||||
@@ -192,41 +178,13 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
|
||||
Direction.entries.forEach { direction ->
|
||||
val relativePos = pos.relative(direction)
|
||||
val relativeState = level.getBlockState(relativePos)
|
||||
val matchesFace = relativeState.hasProperty(DirectionalBlock.FACING)
|
||||
&& relativeState.getValue(DirectionalBlock.FACING) == direction
|
||||
if (!(forceGrow || (matchesFace && random.nextFloat() < Cobblemon.config.typeGemGrowthChance))) {
|
||||
return@forEach
|
||||
val clusterBlock = relativeState.block as? TypeGemClusterBlock ?: return@forEach
|
||||
|
||||
if ((relativeState.getValue(DirectionalBlock.FACING) == direction &&
|
||||
random.nextFloat() < Cobblemon.config.typeGemGrowthChance) || forceGrow
|
||||
) {
|
||||
clusterBlock.advanceGrowth(relativeState, level, relativePos, random)
|
||||
}
|
||||
|
||||
val block = relativeState.block
|
||||
if (block is TypeGemClusterBlock) {
|
||||
block.advanceGrowth(relativeState, level, relativePos, random)
|
||||
} else if (isAmethystStage(block)) {
|
||||
advanceAmethyst(relativeState, level, relativePos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun advanceAmethyst(state: BlockState, level: LevelAccessor, pos: BlockPos) {
|
||||
val facing = state.getValue(DirectionalBlock.FACING)
|
||||
val supportState = level.getBlockState(pos.relative(facing.opposite))
|
||||
if (!supportState.`is`(CobblemonBlockTags.TYPE_GEM_BLOCKS) && supportState.block != CobblemonBlocks.TYPE_GEM_CORE) {
|
||||
return
|
||||
}
|
||||
|
||||
if (state.block != Blocks.AMETHYST_CLUSTER) {
|
||||
val nextStage = AMETHYST_STAGES[AMETHYST_STAGES.indexOf(state.block) + 1]
|
||||
level.setBlock(pos, nextStage.defaultBlockState().setValue(DirectionalBlock.FACING, facing), 3)
|
||||
return
|
||||
}
|
||||
|
||||
// Fully grown clusters mature into amethyst blocks unless boxed in, mirroring stunted type gems
|
||||
val boxedIn = Direction.entries.any { direction ->
|
||||
direction != facing.opposite
|
||||
&& level.getBlockState(pos.relative(direction)).`is`(CobblemonBlockTags.TYPE_GEM_BLOCKS)
|
||||
}
|
||||
if (!boxedIn) {
|
||||
level.setBlock(pos, Blocks.AMETHYST_BLOCK.defaultBlockState(), 3)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,6 @@ object CobblemonClient {
|
||||
val battleOverlay: BattleOverlay by lazy { BattleOverlay() }
|
||||
val pokedexUsageContext: PokedexUsageContext by lazy { PokedexUsageContext() }
|
||||
val rideControlsOverlay: RideControlsOverlay by lazy { RideControlsOverlay() }
|
||||
var pcHealthToggle: Boolean = false
|
||||
|
||||
fun onLogin() {
|
||||
clientPlayerData = ClientGeneralPlayerData()
|
||||
|
||||
+7
-1
@@ -16,7 +16,9 @@ import com.cobblemon.mod.common.client.render.pokeball.PokeBallPosableState
|
||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
|
||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity.CaptureState
|
||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity.CaptureState.NOT
|
||||
import com.cobblemon.mod.common.util.toRGBA
|
||||
import net.minecraft.network.syncher.EntityDataAccessor
|
||||
import org.joml.Vector4f
|
||||
|
||||
class EmptyPokeBallClientDelegate : PokeBallPosableState(), EntitySideDelegate<EmptyPokeBallEntity> {
|
||||
override val stateEmitter: SettableObservable<CaptureState> = SettableObservable(NOT)
|
||||
@@ -52,4 +54,8 @@ class EmptyPokeBallClientDelegate : PokeBallPosableState(), EntitySideDelegate<E
|
||||
EmptyPokeBallEntity.ASPECTS -> currentAspects = currentEntity.aspects
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getBeamColor(): Vector4f {
|
||||
return currentEntity.pokeBall.beamColor.rgb.toRGBA()
|
||||
}
|
||||
}
|
||||
@@ -29,8 +29,7 @@ class BoxStorageSlot(
|
||||
|
||||
val grabbedSlot = parent.grabbedSlot
|
||||
return if (grabbedSlot == null) {
|
||||
val pokemon = getPokemon()
|
||||
pokemon == null || !parent.isInMultiSelection(pokemon, position)
|
||||
true
|
||||
} else {
|
||||
grabbedSlot.getPokemon() != getPokemon()
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import kotlin.isInitialized
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.FastColor
|
||||
|
||||
class PCGUI(
|
||||
val pc: ClientPC,
|
||||
@@ -99,8 +98,6 @@ class PCGUI(
|
||||
private val buttonWallpaperResource = cobblemonResource("textures/gui/pc/pc_button_set_wallpaper.png")
|
||||
private val buttonInfoArrow = cobblemonResource("textures/gui/pc/info_arrow.png")
|
||||
|
||||
private val buttonHealthToggleResource = cobblemonResource("textures/gui/pc/pc_button_toggle_health.png")
|
||||
|
||||
private val topSpacerResource = cobblemonResource("textures/gui/pc/pc_spacer_top.png")
|
||||
private val bottomSpacerResource = cobblemonResource("textures/gui/pc/pc_spacer_bottom.png")
|
||||
private val rightSpacerResource = cobblemonResource("textures/gui/pc/pc_spacer_right.png")
|
||||
@@ -132,55 +129,6 @@ class PCGUI(
|
||||
var selectPointerOffsetIncrement = false
|
||||
var displayOptions = false
|
||||
|
||||
private var dragStartX: Int? = null
|
||||
private var dragStartY: Int? = null
|
||||
private var dragEndX: Int? = null
|
||||
private var dragEndY: Int? = null
|
||||
private var selectionDragActive = false
|
||||
|
||||
data class SelectionArea(val left: Int, val top: Int, val right: Int, val bottom: Int)
|
||||
|
||||
private data class BoxGridBounds(val left: Int, val top: Int, val right: Int, val bottom: Int) {
|
||||
fun contains(x: Int, y: Int) = x in left..< right && y >= top && y < bottom
|
||||
}
|
||||
|
||||
private fun getBoxGridBounds(): BoxGridBounds {
|
||||
val left = storageWidget.x
|
||||
val top = storageWidget.y
|
||||
return BoxGridBounds(
|
||||
left,
|
||||
top,
|
||||
left + StorageWidget.SCREEN_WIDTH,
|
||||
top + StorageWidget.SCREEN_HEIGHT
|
||||
)
|
||||
}
|
||||
|
||||
fun getSelectionArea(): SelectionArea? {
|
||||
if (!selectionDragActive) return null
|
||||
val startX = dragStartX ?: return null
|
||||
val startY = dragStartY ?: return null
|
||||
val endX = dragEndX ?: return null
|
||||
val endY = dragEndY ?: return null
|
||||
val bounds = getBoxGridBounds()
|
||||
if (!bounds.contains(startX, startY)) return null
|
||||
|
||||
val columns = 6
|
||||
val rows = 5
|
||||
val slotPitch = StorageSlot.SIZE + StorageWidget.BOX_SLOT_PADDING
|
||||
val gridLeft = bounds.left + StorageWidget.BOX_SLOT_START_OFFSET_X
|
||||
val gridTop = bounds.top + StorageWidget.BOX_SLOT_START_OFFSET_Y + if (displayOptions) 5 else 0
|
||||
val startColumn = ((startX - gridLeft) / slotPitch).coerceIn(0, columns - 1)
|
||||
val endColumn = (((endX.coerceIn(bounds.left, bounds.right - 1)) - gridLeft) / slotPitch).coerceIn(0, columns - 1)
|
||||
val startRow = ((startY - gridTop) / slotPitch).coerceIn(0, rows - 1)
|
||||
val endRow = (((endY.coerceIn(bounds.top, bounds.bottom - 1)) - gridTop) / slotPitch).coerceIn(0, rows - 1)
|
||||
return SelectionArea(
|
||||
gridLeft + minOf(startColumn, endColumn) * slotPitch, // left
|
||||
gridTop + minOf(startRow, endRow) * slotPitch, // top
|
||||
gridLeft + (maxOf(startColumn, endColumn) * slotPitch) + StorageSlot.SIZE, // right
|
||||
gridTop + (maxOf(startRow, endRow) * slotPitch) + StorageSlot.SIZE // bottom
|
||||
)
|
||||
}
|
||||
|
||||
override fun renderBlurredBackground(delta: Float) {}
|
||||
|
||||
override fun renderMenuBackground(context: GuiGraphics) {}
|
||||
@@ -271,6 +219,7 @@ class PCGUI(
|
||||
storageWidget.setupStorageSlots()
|
||||
for (button in optionButtons) {
|
||||
button.visible = displayOptions
|
||||
button.highlighted = false
|
||||
}
|
||||
}.also { it.highlighted = displayOptions }
|
||||
)
|
||||
@@ -301,28 +250,12 @@ class PCGUI(
|
||||
configuration.showParty = isVisible
|
||||
wallpaperWidget.visible = !isVisible
|
||||
(it as IconButton).highlighted = !isVisible
|
||||
if (unseenWallpapers.isNotEmpty()) MarkPCBoxWallpapersSeenPacket(unseenWallpapers).sendToServer()
|
||||
if (!unseenWallpapers.isEmpty()) MarkPCBoxWallpapersSeenPacket(unseenWallpapers).sendToServer()
|
||||
}.also {
|
||||
it.visible = displayOptions
|
||||
optionButtons.add(it)
|
||||
})
|
||||
|
||||
val healthButton = this.addRenderableWidget(IconButton(
|
||||
pX = x + 230,
|
||||
pY = y + 31,
|
||||
buttonWidth = 20,
|
||||
buttonHeight = 20,
|
||||
resource = buttonHealthToggleResource,
|
||||
label = "toggle_health_bars",
|
||||
) {
|
||||
CobblemonClient.pcHealthToggle = !CobblemonClient.pcHealthToggle
|
||||
(it as IconButton).highlighted = CobblemonClient.pcHealthToggle
|
||||
}.also {
|
||||
it.visible = displayOptions
|
||||
optionButtons.add(it)
|
||||
})
|
||||
healthButton.highlighted = CobblemonClient.pcHealthToggle
|
||||
|
||||
PokemonSortMode.entries.forEachIndexed { index, sortType ->
|
||||
val typeName = sortType.name.lowercase()
|
||||
this.addRenderableWidget(IconButton(
|
||||
@@ -382,20 +315,6 @@ class PCGUI(
|
||||
super.init()
|
||||
}
|
||||
|
||||
private fun renderSelectionBox(context: GuiGraphics, area: SelectionArea) {
|
||||
context.pose().pushPose()
|
||||
context.pose().translate(0.0, 0.0, 1500.0)
|
||||
val borderColor = FastColor.ARGB32.color(255, 205, 212, 255)
|
||||
val bgColor = FastColor.ARGB32.color(75, 133, 183, 230)
|
||||
val thickness = 1
|
||||
context.fill(area.left, area.top, area.right, area.bottom, bgColor)
|
||||
context.fill(area.left, area.top, area.right, area.top + thickness, borderColor)
|
||||
context.fill(area.left, area.bottom - thickness, area.right, area.bottom, borderColor)
|
||||
context.fill(area.left, area.top, area.left + thickness, area.bottom, borderColor)
|
||||
context.fill(area.right - thickness, area.top, area.right, area.bottom, borderColor)
|
||||
context.pose().popPose()
|
||||
}
|
||||
|
||||
override fun render(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
val matrices = context.pose()
|
||||
renderBackground(context, mouseX, mouseY, delta)
|
||||
@@ -536,20 +455,6 @@ class PCGUI(
|
||||
shadow = true
|
||||
)
|
||||
|
||||
// var dexNo = pokemon.species.nationalPokedexNumber.toString()
|
||||
// while (dexNo.length < 4) {
|
||||
// dexNo = "0$dexNo"
|
||||
// }
|
||||
// drawScaledText(
|
||||
// context = context,
|
||||
// font = CobblemonResources.DEFAULT_LARGE,
|
||||
// text = Component.literal(dexNo).bold(),
|
||||
// x = x + 38,
|
||||
// y = y + 1.5,
|
||||
// shadow = true,
|
||||
// scale = 0.85f
|
||||
// )
|
||||
|
||||
drawScaledText(
|
||||
context = context,
|
||||
font = CobblemonResources.DEFAULT_LARGE,
|
||||
@@ -780,14 +685,12 @@ class PCGUI(
|
||||
scale = SCALE
|
||||
)
|
||||
|
||||
if (optionButtons.isNotEmpty() && displayOptions) {
|
||||
if (!optionButtons.isEmpty() && displayOptions) {
|
||||
for (button in optionButtons) button.showAlt = hasShiftDown()
|
||||
}
|
||||
|
||||
super.render(context, mouseX, mouseY, delta)
|
||||
|
||||
getSelectionArea()?.let { renderSelectionBox(context, it) }
|
||||
|
||||
// Item Tooltip
|
||||
if (pokemon != null) {
|
||||
val displayedItem = if (showCosmeticItem) pokemon.cosmeticItem else pokemon.heldItemNoCopy()
|
||||
@@ -809,20 +712,6 @@ class PCGUI(
|
||||
}
|
||||
|
||||
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||
storageWidget.clearPendingStorageSlotClick()
|
||||
selectionDragActive = false
|
||||
val clickX = mouseX.toInt()
|
||||
val clickY = mouseY.toInt()
|
||||
if (storageWidget.multiSelection == null && button == 0 &&
|
||||
getBoxGridBounds().contains(clickX, clickY) &&
|
||||
storageWidget.pastureWidget == null) {
|
||||
dragStartX = clickX
|
||||
dragStartY = clickY
|
||||
} else {
|
||||
dragStartX = null
|
||||
dragStartY = null
|
||||
}
|
||||
|
||||
// Trigger child component function as they will need to check the entire screen click area
|
||||
if (::boxNameWidget.isInitialized) boxNameWidget.mouseClicked(mouseX, mouseY, button)
|
||||
return super.mouseClicked(mouseX, mouseY, button)
|
||||
@@ -851,43 +740,9 @@ class PCGUI(
|
||||
storageWidget.pastureWidget?.let { pasture ->
|
||||
if (pasture.pastureScrollList.isHovered) pasture.pastureScrollList.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
|
||||
}
|
||||
if (button == 0 && storageWidget.pastureWidget == null) {
|
||||
val startX = dragStartX
|
||||
val startY = dragStartY
|
||||
if (startX != null && startY != null) {
|
||||
val offsetX = mouseX - startX
|
||||
val offsetY = mouseY - startY
|
||||
if (offsetX * offsetX + offsetY * offsetY >= 25.0) {
|
||||
selectionDragActive = true
|
||||
storageWidget.clearPendingStorageSlotClick()
|
||||
dragEndX = mouseX.toInt()
|
||||
dragEndY = mouseY.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
|
||||
}
|
||||
|
||||
override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
||||
val handled = super.mouseReleased(mouseX, mouseY, button)
|
||||
if (button == 0) {
|
||||
if (selectionDragActive) {
|
||||
dragEndX = mouseX.toInt()
|
||||
dragEndY = mouseY.toInt()
|
||||
storageWidget.updateSelection()
|
||||
storageWidget.clearPendingStorageSlotClick()
|
||||
} else {
|
||||
storageWidget.completePendingStorageSlotClick(mouseX, mouseY)
|
||||
}
|
||||
}
|
||||
dragStartX = null
|
||||
dragStartY = null
|
||||
dragEndX = null
|
||||
dragEndY = null
|
||||
selectionDragActive = false
|
||||
return handled
|
||||
}
|
||||
|
||||
override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
|
||||
val boxNameFocused = this::boxNameWidget.isInitialized && boxNameWidget.isFocused
|
||||
val filterFocused = this::filterWidget.isInitialized && filterWidget.isFocused
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.cobblemon.mod.common.client.gui.pc
|
||||
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
|
||||
data class PCMultiSelection(
|
||||
private val grid: MutableList<MutableList<Pokemon?>> = mutableListOf(),
|
||||
val sourceBox: Int = 0,
|
||||
val sourceColumn: Int = 0,
|
||||
val sourceRow: Int = 0
|
||||
) {
|
||||
fun getHorizontalSize(): Int = grid.firstOrNull()?.size ?: 0
|
||||
fun getVerticalSize(): Int = grid.size
|
||||
|
||||
constructor(horizontalSize: Int, verticalSize: Int, sourceBox: Int, sourceColumn: Int, sourceRow: Int) : this(
|
||||
MutableList(verticalSize) { MutableList<Pokemon?>(horizontalSize) { null } },
|
||||
sourceBox,
|
||||
sourceColumn,
|
||||
sourceRow
|
||||
)
|
||||
|
||||
fun getPokemon(x: Int, y: Int): Pokemon? {
|
||||
return grid[y][x]
|
||||
}
|
||||
|
||||
fun setPokemon(x: Int, y: Int, pokemon: Pokemon?) {
|
||||
grid[y][x] = pokemon
|
||||
}
|
||||
|
||||
fun pokemonEntries(): List<Triple<Int, Int, Pokemon>> {
|
||||
return grid.flatMapIndexed { y, row ->
|
||||
row.mapIndexedNotNull { x, pokemon -> pokemon?.let { Triple(x, y, it) } }
|
||||
}
|
||||
}
|
||||
|
||||
fun getPokemonCount(): Int = pokemonEntries().size
|
||||
|
||||
}
|
||||
@@ -45,13 +45,11 @@ class ReleaseButton(
|
||||
vOffset = if (isHovered(mouseX.toDouble(), mouseY.toDouble())) HEIGHT else 0,
|
||||
textureHeight = HEIGHT * 2
|
||||
)
|
||||
val pokemonCount = parent.multiSelection?.getPokemonCount() ?: 0
|
||||
|
||||
drawScaledText(
|
||||
context = context,
|
||||
font = CobblemonResources.DEFAULT_LARGE,
|
||||
text = if (pokemonCount > 1)
|
||||
{ lang("ui.pc.release_all").bold() } else { lang("ui.pc.release").bold() },
|
||||
text = lang("ui.pc.release").bold(),
|
||||
x = x + (WIDTH / 2),
|
||||
y = y + 3.5,
|
||||
centered = true,
|
||||
|
||||
@@ -10,11 +10,10 @@ package com.cobblemon.mod.common.client.gui.pc
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.api.gui.blitk
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
|
||||
import com.cobblemon.mod.common.client.gui.PokemonGUIAnimationStyle
|
||||
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
|
||||
import com.cobblemon.mod.common.client.gui.pasture.PasturePCGUIConfiguration
|
||||
import com.cobblemon.mod.common.client.gui.PokemonGUIAnimationStyle
|
||||
import com.cobblemon.mod.common.client.render.drawScaledText
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState
|
||||
import com.cobblemon.mod.common.client.render.renderScaledGuiItemIcon
|
||||
@@ -23,19 +22,13 @@ import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
|
||||
import juuxel.adorn.util.Colors
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.gui.components.Button
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.sounds.SoundManager
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.util.Mth
|
||||
import org.joml.Quaternionf
|
||||
import org.joml.Vector3f
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
open class StorageSlot(
|
||||
x: Int, y: Int,
|
||||
@@ -61,17 +54,9 @@ open class StorageSlot(
|
||||
}
|
||||
|
||||
override fun renderWidget(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
val selectionArea = parent.pcGui.getSelectionArea()
|
||||
if (selectionArea != null && parent.getSelectedPokemon(selectionArea).contains(this)) {
|
||||
val highlightColor = 0x40FFFFFF
|
||||
context.fill(x + 1, y, x + (SIZE - 1), y + SIZE, highlightColor)
|
||||
context.fill(x, y + 1, x + 1, y + (SIZE - 1), highlightColor)
|
||||
context.fill(x + SIZE - 1, y + 1, x + SIZE, y + (SIZE - 1), highlightColor)
|
||||
}
|
||||
if (shouldRender()) {
|
||||
renderSlot(context, x, y, delta)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun renderSlot(context: GuiGraphics, posX: Int, posY: Int, partialTicks: Float) {
|
||||
@@ -145,23 +130,6 @@ open class StorageSlot(
|
||||
matrixStack = matrices
|
||||
)
|
||||
}
|
||||
|
||||
// Pokemon health
|
||||
// Taken from vanilla durability rendering
|
||||
val currentHealth = pokemon.currentHealth
|
||||
val maxHealth = pokemon.maxHealth.toFloat()
|
||||
if (currentHealth < maxHealth && CobblemonClient.pcHealthToggle) {
|
||||
val damageValue = maxHealth - currentHealth
|
||||
val f = max(0.0f, (maxHealth - (maxHealth - currentHealth)) / maxHealth)
|
||||
val color = Mth.hsvToRgb(f / 3.0f, 1.0f, 1.0f)
|
||||
val totalWidth = 12
|
||||
val width = (totalWidth - damageValue * totalWidth / pokemon.maxHealth.toFloat()).roundToInt();
|
||||
val k = posX + 1
|
||||
val l = posY + 6
|
||||
val bgColor = if (this is PartyStorageSlot) Colors.BLACK else 0xFF3E3E3E.toInt()
|
||||
context.fill(RenderType.guiOverlay(), k, l, k + totalWidth, l + 1, bgColor)
|
||||
context.fill(RenderType.guiOverlay(), k, l, k + width, l + 1, color or bgColor)
|
||||
}
|
||||
matrices.popPose()
|
||||
}
|
||||
|
||||
|
||||
@@ -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.storage.StorePosition
|
||||
import com.cobblemon.mod.common.api.storage.party.PartyPosition
|
||||
import com.cobblemon.mod.common.api.storage.pc.PCPosition
|
||||
import com.cobblemon.mod.common.api.text.bold
|
||||
@@ -38,9 +39,8 @@ import net.minecraft.client.gui.components.Button
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import java.util.UUID
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePCPokemonBatchPacket.PCPokemonMove
|
||||
|
||||
class StorageWidget(
|
||||
pX: Int, pY: Int,
|
||||
@@ -77,14 +77,9 @@ class StorageWidget(
|
||||
|
||||
var displayConfirmRelease = false
|
||||
var screenLoaded = false
|
||||
var selectedPosition: PartyPosition? = null
|
||||
var selectedPosition: StorePosition? = null
|
||||
var grabbedSlot: GrabbedStorageSlot? = null
|
||||
|
||||
var multiSelection: PCMultiSelection? = null
|
||||
private val multiGrabbedSlots = mutableMapOf<UUID, GrabbedStorageSlot>()
|
||||
private var pendingStorageSlotClick: Button? = null
|
||||
private var movePending = false
|
||||
|
||||
var box = 0
|
||||
set(value) {
|
||||
field =
|
||||
@@ -118,22 +113,16 @@ class StorageWidget(
|
||||
subKey = "ui.generic.yes",
|
||||
onPress = {
|
||||
if (canDeleteSelected() && displayConfirmRelease) {
|
||||
val selection = multiSelection
|
||||
if (selection != null) {
|
||||
selection.pokemonEntries().forEach { (column, row, pokemon) ->
|
||||
val position = PCPosition(
|
||||
selection.sourceBox,
|
||||
(selection.sourceRow + row) * 6 + selection.sourceColumn + column
|
||||
)
|
||||
CobblemonNetwork.sendToServer(ReleasePCPokemonPacket(pokemon.uuid, position))
|
||||
}
|
||||
} else {
|
||||
val position = selectedPosition ?: return@ReleaseConfirmButton
|
||||
val pokemon = getSelectedPokemon() ?: return@ReleaseConfirmButton
|
||||
val position = selectedPosition ?: return@ReleaseConfirmButton
|
||||
val pokemon = getSelectedPokemon() ?: return@ReleaseConfirmButton
|
||||
|
||||
CobblemonNetwork.sendToServer(ReleasePartyPokemonPacket(pokemon.uuid, position))
|
||||
val packet = when (position) {
|
||||
is PartyPosition -> ReleasePartyPokemonPacket(pokemon.uuid, position)
|
||||
is PCPosition -> ReleasePCPokemonPacket(pokemon.uuid, position)
|
||||
else -> return@ReleaseConfirmButton
|
||||
}
|
||||
|
||||
CobblemonNetwork.sendToServer(packet)
|
||||
playSound(CobblemonSounds.PC_RELEASE)
|
||||
resetSelected()
|
||||
displayConfirmRelease = false
|
||||
@@ -160,8 +149,9 @@ class StorageWidget(
|
||||
}
|
||||
|
||||
fun canDeleteSelected(): Boolean {
|
||||
multiSelection?.let { return it.pokemonEntries().isNotEmpty() }
|
||||
return party.filterNotNull().size > 1 && selectedPosition != null && grabbedSlot != null
|
||||
return !(selectedPosition is PartyPosition && party.filterNotNull().size <= 1)
|
||||
&& selectedPosition != null
|
||||
&& grabbedSlot != null
|
||||
}
|
||||
|
||||
fun setupStorageSlots() {
|
||||
@@ -180,7 +170,7 @@ class StorageWidget(
|
||||
parent = this,
|
||||
pc = pc,
|
||||
position = PCPosition(box, index),
|
||||
onPress = { pendingStorageSlotClick = it }
|
||||
onPress = { this.onStorageSlotClicked(it) }
|
||||
).also { widget ->
|
||||
this.addWidget(widget)
|
||||
this.boxSlots.add(widget)
|
||||
@@ -210,7 +200,7 @@ class StorageWidget(
|
||||
parent = this,
|
||||
party = party,
|
||||
position = PartyPosition(partyIndex),
|
||||
onPress = { pendingStorageSlotClick = it }
|
||||
onPress = { this.onStorageSlotClicked(it) }
|
||||
).also { widget ->
|
||||
this.addWidget(widget)
|
||||
this.partySlots.add(widget)
|
||||
@@ -220,117 +210,14 @@ class StorageWidget(
|
||||
|
||||
private fun getSelectedPokemon(): Pokemon? {
|
||||
val selectedPosition = this.selectedPosition ?: return null
|
||||
return party.get(selectedPosition)
|
||||
}
|
||||
|
||||
fun getSelectedPokemon(area: PCGUI.SelectionArea): List<BoxStorageSlot> {
|
||||
return boxSlots.filter { slot ->
|
||||
slot.x < area.right && slot.x + StorageSlot.SIZE > area.left &&
|
||||
slot.y < area.bottom && slot.y + StorageSlot.SIZE > area.top &&
|
||||
slot.getPokemon()?.let(pcGui.search::passes) == true
|
||||
return when (selectedPosition) {
|
||||
is PCPosition -> pc.get(selectedPosition)
|
||||
is PartyPosition -> party.get(selectedPosition)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun clearPendingStorageSlotClick() {
|
||||
pendingStorageSlotClick = null
|
||||
}
|
||||
|
||||
fun completePendingStorageSlotClick(mouseX: Double, mouseY: Double) {
|
||||
val button = pendingStorageSlotClick ?: return
|
||||
pendingStorageSlotClick = null
|
||||
if (button.isMouseOver(mouseX, mouseY)) {
|
||||
onStorageSlotClicked(button)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateSelection() {
|
||||
val area = pcGui.getSelectionArea()
|
||||
if (area == null) {
|
||||
multiSelection = null
|
||||
return
|
||||
}
|
||||
|
||||
selectedPosition = null
|
||||
grabbedSlot = null
|
||||
pcGui.setPreviewPokemon(null)
|
||||
|
||||
val selectedSlots = getSelectedPokemon(area)
|
||||
if (selectedSlots.isEmpty()) {
|
||||
multiSelection = null
|
||||
return
|
||||
}
|
||||
|
||||
val minColumn = selectedSlots.minOf { it.position.slot % 6 }
|
||||
val maxColumn = selectedSlots.maxOf { it.position.slot % 6 }
|
||||
val minRow = selectedSlots.minOf { it.position.slot / 6 }
|
||||
val maxRow = selectedSlots.maxOf { it.position.slot / 6 }
|
||||
val selection = PCMultiSelection(maxColumn - minColumn + 1, maxRow - minRow + 1, box, minColumn, minRow)
|
||||
|
||||
selectedSlots.forEach { slot ->
|
||||
val pokemon = slot.getPokemon() ?: return@forEach
|
||||
val slotIndex = slot.position.slot
|
||||
val column = slotIndex % 6
|
||||
val row = slotIndex / 6
|
||||
if (column in minColumn..maxColumn && row in minRow..maxRow) {
|
||||
selection.setPokemon(column - minColumn, row - minRow, pokemon)
|
||||
}
|
||||
}
|
||||
playSound(CobblemonSounds.PC_GRAB)
|
||||
|
||||
multiSelection = selection
|
||||
}
|
||||
|
||||
private fun moveMultiSelectionTo(destination: PCPosition): Boolean {
|
||||
val selection = multiSelection ?: return false
|
||||
|
||||
val width = selection.getHorizontalSize()
|
||||
val height = selection.getVerticalSize()
|
||||
val destinationColumn = destination.slot % 6
|
||||
val destinationRow = destination.slot / 6
|
||||
if (destinationColumn + width > 6 || destinationRow + height > 5) return false
|
||||
|
||||
val moves = mutableListOf<PCPokemonMove>()
|
||||
val selectedSources = mutableSetOf<PCPosition>()
|
||||
for (row in 0 until height) {
|
||||
for (column in 0 until width) {
|
||||
val pokemon = selection.getPokemon(column, row) ?: continue
|
||||
val source = PCPosition(selection.sourceBox, (selection.sourceRow + row) * 6 + selection.sourceColumn + column)
|
||||
val target = PCPosition(destination.box, (destinationRow + row) * 6 + destinationColumn + column)
|
||||
selectedSources.add(source)
|
||||
moves.add(PCPokemonMove(pokemon.uuid, source, target))
|
||||
}
|
||||
}
|
||||
|
||||
if (moves.isEmpty()) return false
|
||||
|
||||
for (row in 0 until height) {
|
||||
for (column in 0 until width) {
|
||||
if (selection.getPokemon(column, row) == null) continue
|
||||
val target = PCPosition(destination.box, (destinationRow + row) * 6 + destinationColumn + column)
|
||||
val displacedPokemon = pc.get(target) ?: continue
|
||||
if (target in selectedSources) continue
|
||||
|
||||
val displacedSource = PCPosition(
|
||||
selection.sourceBox,
|
||||
(selection.sourceRow + row) * 6 + selection.sourceColumn + column
|
||||
)
|
||||
if (pc.get(displacedSource) != null && displacedSource !in selectedSources) return false
|
||||
moves.add(PCPokemonMove(displacedPokemon.uuid, target, displacedSource))
|
||||
}
|
||||
}
|
||||
|
||||
if (moves.map { it.newPosition }.toSet().size != moves.size) return false
|
||||
MovePCPokemonBatchPacket(moves).sendToServer()
|
||||
return true
|
||||
}
|
||||
|
||||
fun isInMultiSelection(pokemon: Pokemon, position: PCPosition): Boolean {
|
||||
val selection = multiSelection ?: return false
|
||||
return selection.sourceBox == position.box && selection.pokemonEntries().any { it.third == pokemon }
|
||||
}
|
||||
|
||||
override fun renderWidget(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
updatePendingMove()
|
||||
val matrices = context.pose()
|
||||
// Party Label
|
||||
if (pcGui.configuration.showParty) {
|
||||
@@ -353,14 +240,11 @@ class StorageWidget(
|
||||
shadow = true
|
||||
)
|
||||
|
||||
val pokemonCount = multiSelection?.getPokemonCount() ?: 0
|
||||
|
||||
if (canDeleteSelected() && displayConfirmRelease) {
|
||||
drawScaledText(
|
||||
context = context,
|
||||
font = CobblemonResources.DEFAULT_LARGE,
|
||||
text = if (pokemonCount > 1)
|
||||
{ lang("ui.pc.release_all").bold() } else { lang("ui.pc.release").bold() },
|
||||
text = lang("ui.pc.release").bold(),
|
||||
x = x + 223,
|
||||
y = y + 119,
|
||||
centered = true
|
||||
@@ -424,7 +308,6 @@ class StorageWidget(
|
||||
slot.render(context, mouseX, mouseY, delta)
|
||||
val pokemon = slot.getPokemon()
|
||||
if (grabbedSlot == null && slot.isHovered(mouseX, mouseY)
|
||||
&& multiSelection == null
|
||||
&& pokemon != null && pokemon != pcGui.previewPokemon
|
||||
) {
|
||||
pcGui.setPreviewPokemon(pokemon, pcGui.isPreviewInParty ?: false)
|
||||
@@ -441,7 +324,6 @@ class StorageWidget(
|
||||
slot.render(context, mouseX, mouseY, delta)
|
||||
val pokemon = slot.getPokemon()
|
||||
if (grabbedSlot == null && slot.isHovered(mouseX, mouseY)
|
||||
&& multiSelection == null
|
||||
&& pokemon != null && pokemon != pcGui.previewPokemon
|
||||
) {
|
||||
pcGui.setPreviewPokemon(pokemon, pcGui.isPreviewInParty ?: true)
|
||||
@@ -453,32 +335,10 @@ class StorageWidget(
|
||||
pastureWidget?.render(context, mouseX, mouseY, delta)
|
||||
matrices.pushPose()
|
||||
matrices.translate(0.0, 0.0, 1000.0)
|
||||
renderSelectedPokemon(context, mouseX, mouseY, delta)
|
||||
grabbedSlot?.render(context, mouseX, mouseY, delta)
|
||||
matrices.popPose()
|
||||
}
|
||||
|
||||
private fun renderSelectedPokemon(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
if (movePending) return
|
||||
val selection = multiSelection
|
||||
if (selection == null) {
|
||||
grabbedSlot?.render(context, mouseX, mouseY, delta)
|
||||
return
|
||||
}
|
||||
|
||||
val slotOffset = StorageSlot.SIZE + BOX_SLOT_PADDING
|
||||
selection.pokemonEntries().forEach { (column, row, pokemon) ->
|
||||
val grabbed = multiGrabbedSlots.getOrPut(pokemon.uuid) {
|
||||
GrabbedStorageSlot(0, 0, this, pokemon)
|
||||
}
|
||||
grabbed.render(
|
||||
context,
|
||||
mouseX + column * slotOffset,
|
||||
mouseY + row * slotOffset,
|
||||
delta
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun mouseClicked(pMouseX: Double, pMouseY: Double, pButton: Int): Boolean {
|
||||
if (displayConfirmRelease) {
|
||||
if (releaseYesButton.isHovered(pMouseX, pMouseY)) releaseYesButton.mouseClicked(pMouseX, pMouseY, pButton)
|
||||
@@ -511,55 +371,23 @@ class StorageWidget(
|
||||
else -> return
|
||||
}
|
||||
|
||||
val clickedPokemon = when (clickedPosition) {
|
||||
is PCPosition -> pc.get(clickedPosition)
|
||||
is PartyPosition -> party.get(clickedPosition)
|
||||
else -> null
|
||||
}
|
||||
|
||||
multiSelection?.let { selection ->
|
||||
when (clickedPosition) {
|
||||
is PCPosition -> {
|
||||
if (clickedPosition.box == selection.sourceBox &&
|
||||
clickedPosition.slot == selection.sourceRow * 6 + selection.sourceColumn
|
||||
) {
|
||||
resetSelected()
|
||||
} else if (moveMultiSelectionTo(clickedPosition)) {
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
movePending = true
|
||||
}
|
||||
}
|
||||
is PartyPosition -> {
|
||||
val selectedPokemon = selection.pokemonEntries().singleOrNull() ?: return
|
||||
val (column, row, pokemon) = selectedPokemon
|
||||
val source = PCPosition(
|
||||
selection.sourceBox,
|
||||
(selection.sourceRow + row) * 6 + selection.sourceColumn + column
|
||||
)
|
||||
if (pc.get(source) !== pokemon) return
|
||||
val packet = clickedPokemon?.let {
|
||||
SwapPCPartyPokemonPacket(it.uuid, clickedPosition, pokemon.uuid, source)
|
||||
} ?: MovePCPokemonToPartyPacket(pokemon.uuid, source, clickedPosition)
|
||||
packet.sendToServer()
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
movePending = true
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Reset release confirmation
|
||||
displayConfirmRelease = false
|
||||
|
||||
// Clicking on itself, so unselect position
|
||||
if (selectedPosition == clickedPosition) {
|
||||
if (this.selectedPosition != null && this.selectedPosition == clickedPosition) {
|
||||
if (grabbedSlot != null) playSound(CobblemonSounds.PC_DROP)
|
||||
resetSelected()
|
||||
return
|
||||
}
|
||||
|
||||
// Check for selecting a Pokémon
|
||||
val clickedPokemon = when(button) {
|
||||
is BoxStorageSlot -> pc.get(clickedPosition as PCPosition)
|
||||
is PartyStorageSlot -> party.get(clickedPosition as PartyPosition)
|
||||
else -> null
|
||||
}
|
||||
|
||||
val selectOverride = pcGui.configuration.selectOverride
|
||||
if (selectOverride != null) {
|
||||
selectOverride(pcGui, clickedPosition, clickedPokemon)
|
||||
@@ -592,47 +420,59 @@ class StorageWidget(
|
||||
}
|
||||
}
|
||||
|
||||
if (clickedPosition is PCPosition) {
|
||||
val column = clickedPosition.slot % 6
|
||||
val row = clickedPosition.slot / 6
|
||||
multiSelection = PCMultiSelection(1, 1, clickedPosition.box, column, row).also {
|
||||
it.setPokemon(0, 0, clickedPokemon)
|
||||
}
|
||||
playSound(CobblemonSounds.PC_GRAB)
|
||||
return
|
||||
} else if (clickedPosition is PartyPosition) {
|
||||
this.selectedPosition = clickedPosition
|
||||
this.pcGui.setPreviewPokemon(clickedPokemon, pcGui.isPreviewInParty ?: false)
|
||||
grabbedSlot = GrabbedStorageSlot(
|
||||
x = button.x,
|
||||
y = button.y,
|
||||
parent = this,
|
||||
pokemon = clickedPokemon
|
||||
)
|
||||
playSound(CobblemonSounds.PC_GRAB)
|
||||
}
|
||||
this.selectedPosition = clickedPosition
|
||||
this.pcGui.setPreviewPokemon(clickedPokemon, pcGui.isPreviewInParty ?: false)
|
||||
grabbedSlot = GrabbedStorageSlot(
|
||||
x = button.x,
|
||||
y = button.y,
|
||||
parent = this,
|
||||
pokemon = clickedPokemon
|
||||
)
|
||||
playSound(CobblemonSounds.PC_GRAB)
|
||||
|
||||
}
|
||||
} else {
|
||||
val sourcePosition = selectedPosition ?: return
|
||||
val selectedPokemon = party.get(sourcePosition) ?: return
|
||||
// Handle movement within the Box
|
||||
val selectedPokemon = when(this.selectedPosition) {
|
||||
is PCPosition -> pc.get(this.selectedPosition as PCPosition)
|
||||
is PartyPosition -> party.get(this.selectedPosition as PartyPosition)
|
||||
else -> null
|
||||
} ?: return
|
||||
|
||||
// Box to Box
|
||||
if (this.selectedPosition is PCPosition && clickedPosition is PCPosition) {
|
||||
val packet = clickedPokemon?.let { SwapPCPokemonPacket(it.uuid, clickedPosition, selectedPokemon.uuid, this.selectedPosition as PCPosition) }
|
||||
?: MovePCPokemonPacket(selectedPokemon.uuid, selectedPosition as PCPosition, clickedPosition)
|
||||
packet.sendToServer()
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
resetSelected()
|
||||
}
|
||||
// Box to Party
|
||||
else if (this.selectedPosition is PCPosition && clickedPosition is PartyPosition) {
|
||||
val packet = clickedPokemon?.let { SwapPCPartyPokemonPacket(clickedPokemon.uuid, clickedPosition, selectedPokemon.uuid, this.selectedPosition as PCPosition) }
|
||||
?: MovePCPokemonToPartyPacket(selectedPokemon.uuid, this.selectedPosition as PCPosition, clickedPosition)
|
||||
packet.sendToServer()
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
resetSelected()
|
||||
}
|
||||
// Party to Box
|
||||
if (clickedPosition is PCPosition) {
|
||||
else if (this.selectedPosition is PartyPosition && clickedPosition is PCPosition) {
|
||||
if (ServerSettings.preventCompletePartyDeposit && this.party.filterNotNull().size == 1 && clickedPokemon == null) {
|
||||
return
|
||||
}
|
||||
val packet = clickedPokemon?.let { SwapPCPartyPokemonPacket(selectedPokemon.uuid, sourcePosition, clickedPokemon.uuid, clickedPosition) }
|
||||
?: MovePartyPokemonToPCPacket(selectedPokemon.uuid, sourcePosition, clickedPosition)
|
||||
val packet = clickedPokemon?.let { SwapPCPartyPokemonPacket(selectedPokemon.uuid, this.selectedPosition as PartyPosition, clickedPokemon.uuid, clickedPosition) }
|
||||
?: MovePartyPokemonToPCPacket(selectedPokemon.uuid, this.selectedPosition as PartyPosition, clickedPosition)
|
||||
packet.sendToServer()
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
movePending = true
|
||||
resetSelected()
|
||||
}
|
||||
// Party to Party
|
||||
else if (clickedPosition is PartyPosition) {
|
||||
val packet = clickedPokemon?.let { SwapPartyPokemonPacket(it.uuid, clickedPosition, selectedPokemon.uuid, sourcePosition) }
|
||||
?: MovePartyPokemonPacket(selectedPokemon.uuid, sourcePosition, clickedPosition)
|
||||
else if (this.selectedPosition is PartyPosition && clickedPosition is PartyPosition) {
|
||||
val packet = clickedPokemon?.let { SwapPartyPokemonPacket(it.uuid, clickedPosition, selectedPokemon.uuid, this.selectedPosition as PartyPosition) }
|
||||
?: MovePartyPokemonPacket(selectedPokemon.uuid, selectedPosition as PartyPosition, clickedPosition)
|
||||
packet.sendToServer()
|
||||
playSound(CobblemonSounds.PC_DROP)
|
||||
movePending = true
|
||||
resetSelected()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -640,36 +480,6 @@ class StorageWidget(
|
||||
fun resetSelected() {
|
||||
selectedPosition = null
|
||||
grabbedSlot = null
|
||||
multiSelection = null
|
||||
multiGrabbedSlots.clear()
|
||||
pcGui.setPreviewPokemon(null)
|
||||
}
|
||||
|
||||
// annoyingly complex solution, but server/client desync causes flashing when moving pokemon. this should fix it
|
||||
// if you can think of a simpler solution, feel free to implement it
|
||||
private fun updatePendingMove() {
|
||||
if (!movePending) return
|
||||
val selection = multiSelection
|
||||
|
||||
if (selection != null) {
|
||||
val updated = selection.pokemonEntries().any { (column, row, pokemon) ->
|
||||
val source = PCPosition(selection.sourceBox, (selection.sourceRow + row) * 6 + selection.sourceColumn + column)
|
||||
pc.get(source)?.uuid != pokemon.uuid
|
||||
}
|
||||
if (updated) {
|
||||
movePending = false
|
||||
resetSelected()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val source = selectedPosition
|
||||
val pokemon = grabbedSlot?.getPokemon()
|
||||
if (source != null && pokemon != null) {
|
||||
if (party.get(source)?.uuid != pokemon.uuid) {
|
||||
movePending = false
|
||||
resetSelected()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -20,7 +20,7 @@ object BattleCaptureStartHandler : ClientNetworkPacketHandler<BattleCaptureStart
|
||||
val battle = CobblemonClient.battle ?: return
|
||||
val targetPokemon = battle.getPokemonFromPNX(packet.targetPNX)
|
||||
val tile = targetPokemon.second
|
||||
val pokeBall = PokeBalls.getPokeBall(packet.pokeBallType) ?: PokeBalls.POKE_BALL
|
||||
val pokeBall = PokeBalls.getPokeBall(packet.pokeBallType)
|
||||
tile.ballCapturing = ClientBallDisplay(pokeBall, packet.aspects).also { it.start() }
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -133,11 +133,11 @@ class PokeBobberEntityRenderer(context: EntityRendererProvider.Context?) : Entit
|
||||
val pokeBobberBaitItemStack = fishingBobberEntity.entityData.get(PokeRodFishingBobberEntity.POKEBOBBER_BAIT)
|
||||
val pokeRodId = ResourceLocation.tryParse(pokeRodIdStr)
|
||||
val pokeRod = PokeRods.getPokeRod(pokeRodId!!)
|
||||
val ballItem = PokeBalls.getPokeBall(pokeRod?.pokeBallId!!)!!.item
|
||||
val ballItem = PokeBalls.getPokeBall(pokeRod?.pokeBallId!!)!!.stack
|
||||
|
||||
// render the pokebobber
|
||||
Minecraft.getInstance().itemRenderer.renderStatic(
|
||||
ballItem.defaultInstance,
|
||||
ballItem,
|
||||
ItemDisplayContext.GROUND,
|
||||
light,
|
||||
OverlayTexture.NO_OVERLAY,
|
||||
|
||||
+50
-50
@@ -25,55 +25,55 @@ object CobblemonModelPredicateRegistry {
|
||||
|
||||
fun registerPredicates() {
|
||||
|
||||
val rods = listOf(
|
||||
CobblemonItems.AZURE_ROD,
|
||||
CobblemonItems.BEAST_ROD,
|
||||
CobblemonItems.CHERISH_ROD,
|
||||
CobblemonItems.CITRINE_ROD,
|
||||
CobblemonItems.DIVE_ROD,
|
||||
CobblemonItems.DREAM_ROD,
|
||||
CobblemonItems.DUSK_ROD,
|
||||
CobblemonItems.FAST_ROD,
|
||||
CobblemonItems.FRIEND_ROD,
|
||||
CobblemonItems.GREAT_ROD,
|
||||
CobblemonItems.HEAL_ROD,
|
||||
CobblemonItems.HEAVY_ROD,
|
||||
CobblemonItems.LEVEL_ROD,
|
||||
CobblemonItems.LOVE_ROD,
|
||||
CobblemonItems.LURE_ROD,
|
||||
CobblemonItems.LUXURY_ROD,
|
||||
CobblemonItems.MASTER_ROD,
|
||||
CobblemonItems.MOON_ROD,
|
||||
CobblemonItems.NEST_ROD,
|
||||
CobblemonItems.NET_ROD,
|
||||
CobblemonItems.PARK_ROD,
|
||||
CobblemonItems.POKE_ROD,
|
||||
CobblemonItems.PREMIER_ROD,
|
||||
CobblemonItems.QUICK_ROD,
|
||||
CobblemonItems.REPEAT_ROD,
|
||||
CobblemonItems.ROSEATE_ROD,
|
||||
CobblemonItems.SAFARI_ROD,
|
||||
CobblemonItems.SLATE_ROD,
|
||||
CobblemonItems.SPORT_ROD,
|
||||
CobblemonItems.TIMER_ROD,
|
||||
CobblemonItems.ULTRA_ROD,
|
||||
CobblemonItems.VERDANT_ROD,
|
||||
CobblemonItems.ANCIENT_AZURE_ROD,
|
||||
CobblemonItems.ANCIENT_CITRINE_ROD,
|
||||
CobblemonItems.ANCIENT_FEATHER_ROD,
|
||||
CobblemonItems.ANCIENT_GIGATON_ROD,
|
||||
CobblemonItems.ANCIENT_GREAT_ROD,
|
||||
CobblemonItems.ANCIENT_HEAVY_ROD,
|
||||
CobblemonItems.ANCIENT_IVORY_ROD,
|
||||
CobblemonItems.ANCIENT_JET_ROD,
|
||||
CobblemonItems.ANCIENT_LEADEN_ROD,
|
||||
CobblemonItems.ANCIENT_ORIGIN_ROD,
|
||||
CobblemonItems.ANCIENT_POKE_ROD,
|
||||
CobblemonItems.ANCIENT_ROSEATE_ROD,
|
||||
CobblemonItems.ANCIENT_SLATE_ROD,
|
||||
CobblemonItems.ANCIENT_ULTRA_ROD,
|
||||
CobblemonItems.ANCIENT_VERDANT_ROD,
|
||||
CobblemonItems.ANCIENT_WING_ROD
|
||||
val rods = listOf<PokerodItem>(
|
||||
// CobblemonItems.AZURE_ROD,
|
||||
// CobblemonItems.BEAST_ROD,
|
||||
// CobblemonItems.CHERISH_ROD,
|
||||
// CobblemonItems.CITRINE_ROD,
|
||||
// CobblemonItems.DIVE_ROD,
|
||||
// CobblemonItems.DREAM_ROD,
|
||||
// CobblemonItems.DUSK_ROD,
|
||||
// CobblemonItems.FAST_ROD,
|
||||
// CobblemonItems.FRIEND_ROD,
|
||||
// CobblemonItems.GREAT_ROD,
|
||||
// CobblemonItems.HEAL_ROD,
|
||||
// CobblemonItems.HEAVY_ROD,
|
||||
// CobblemonItems.LEVEL_ROD,
|
||||
// CobblemonItems.LOVE_ROD,
|
||||
// CobblemonItems.LURE_ROD,
|
||||
// CobblemonItems.LUXURY_ROD,
|
||||
// CobblemonItems.MASTER_ROD,
|
||||
// CobblemonItems.MOON_ROD,
|
||||
// CobblemonItems.NEST_ROD,
|
||||
// CobblemonItems.NET_ROD,
|
||||
// CobblemonItems.PARK_ROD,
|
||||
// CobblemonItems.POKE_ROD,
|
||||
// CobblemonItems.PREMIER_ROD,
|
||||
// CobblemonItems.QUICK_ROD,
|
||||
// CobblemonItems.REPEAT_ROD,
|
||||
// CobblemonItems.ROSEATE_ROD,
|
||||
// CobblemonItems.SAFARI_ROD,
|
||||
// CobblemonItems.SLATE_ROD,
|
||||
// CobblemonItems.SPORT_ROD,
|
||||
// CobblemonItems.TIMER_ROD,
|
||||
// CobblemonItems.ULTRA_ROD,
|
||||
// CobblemonItems.VERDANT_ROD,
|
||||
// CobblemonItems.ANCIENT_AZURE_ROD,
|
||||
// CobblemonItems.ANCIENT_CITRINE_ROD,
|
||||
// CobblemonItems.ANCIENT_FEATHER_ROD,
|
||||
// CobblemonItems.ANCIENT_GIGATON_ROD,
|
||||
// CobblemonItems.ANCIENT_GREAT_ROD,
|
||||
// CobblemonItems.ANCIENT_HEAVY_ROD,
|
||||
// CobblemonItems.ANCIENT_IVORY_ROD,
|
||||
// CobblemonItems.ANCIENT_JET_ROD,
|
||||
// CobblemonItems.ANCIENT_LEADEN_ROD,
|
||||
// CobblemonItems.ANCIENT_ORIGIN_ROD,
|
||||
// CobblemonItems.ANCIENT_POKE_ROD,
|
||||
// CobblemonItems.ANCIENT_ROSEATE_ROD,
|
||||
// CobblemonItems.ANCIENT_SLATE_ROD,
|
||||
// CobblemonItems.ANCIENT_ULTRA_ROD,
|
||||
// CobblemonItems.ANCIENT_VERDANT_ROD,
|
||||
// CobblemonItems.ANCIENT_WING_ROD
|
||||
)
|
||||
|
||||
rods.forEach { rod ->
|
||||
@@ -186,4 +186,4 @@ object CobblemonModelPredicateRegistry {
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.pokeball
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.frame.ModelFrame
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Bone
|
||||
import net.minecraft.client.model.geom.ModelPart
|
||||
|
||||
open class PokeBallPosableModel(root: Bone) : PosableModel(root), ModelFrame {
|
||||
@Transient
|
||||
override val rootPart =
|
||||
(root as ModelPart)
|
||||
.children.entries
|
||||
.first()
|
||||
.let { root.registerChildWithAllChildren(it.key) }
|
||||
|
||||
val rootBone: String = (root as ModelPart).children.entries.first().key
|
||||
}
|
||||
+2
-2
@@ -13,11 +13,11 @@ import com.cobblemon.mod.common.client.render.models.blockbench.repository.Rende
|
||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
|
||||
import net.minecraft.world.entity.Entity
|
||||
|
||||
class PosablePokeBallModel : PosableEntityModel<EmptyPokeBallEntity>() {
|
||||
class PosablePokeBallEntityModel : PosableEntityModel<EmptyPokeBallEntity>() {
|
||||
override fun setupEntityTypeContext(entity: Entity?) {
|
||||
super.setupEntityTypeContext(entity)
|
||||
if (entity is EmptyPokeBallEntity) {
|
||||
context.put(RenderContext.ASPECTS, entity.aspects)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-56
@@ -20,9 +20,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.*
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.bedrock.animation.BedrockAnimationRepository
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.blockentity.BlockEntityModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.fossil.FossilModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokeball.AncientPokeBallModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokeball.BeastBallModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokeball.PokeBallModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokeball.PokeBallPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PokemonPosableModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen1.*
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.gen2.*
|
||||
@@ -88,7 +86,7 @@ object VaryingModelRepository {
|
||||
"bedrock/fossils/posers" to FossilModel::class.java,
|
||||
"bedrock/block_entities/posers" to BlockEntityModel::class.java,
|
||||
"bedrock/npcs/posers" to PosableModel::class.java,
|
||||
"bedrock/poke_balls/posers" to PosableModel::class.java,
|
||||
"bedrock/poke_balls/posers" to PokeBallPosableModel::class.java,
|
||||
"bedrock/generic/posers" to PosableModel::class.java,
|
||||
)
|
||||
|
||||
@@ -116,6 +114,7 @@ object VaryingModelRepository {
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
.registerTypeAdapter(PosableModel::class.java, JsonModelAdapter(::PosableModel))
|
||||
.registerTypeAdapter(PokemonPosableModel::class.java, JsonModelAdapter(::PokemonPosableModel))
|
||||
.registerTypeAdapter(PokeBallPosableModel::class.java, JsonModelAdapter(::PokeBallPosableModel))
|
||||
.registerTypeAdapter(FossilModel::class.java, JsonModelAdapter(::FossilModel))
|
||||
.registerTypeAdapter(BlockEntityModel::class.java, JsonModelAdapter(::BlockEntityModel))
|
||||
.registerTypeAdapter(Pose::class.java, PoseAdapter { JsonModelAdapter.model!! })
|
||||
@@ -155,8 +154,8 @@ object VaryingModelRepository {
|
||||
return {
|
||||
var boneName = jsonObject.getAsJsonPrimitive("rootBone")
|
||||
JsonModelAdapter.modelPart = if (boneName != null && it.children[boneName.asString] != null) it.children[boneName.asString] else it.children[fileName] ?: it.children.entries.filter { LocatorAccess.PREFIX !in it.key }.first().value
|
||||
gson.fromJson(jsonObject, poserClass).also {
|
||||
it.poses.forEach { (poseName, pose) -> pose.poseName = poseName }
|
||||
gson.fromJson(jsonObject, poserClass).also { model ->
|
||||
model.poses.forEach { (poseName, pose) -> pose.poseName = poseName }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,55 +168,6 @@ object VaryingModelRepository {
|
||||
}
|
||||
|
||||
fun registerInBuiltPosers() {
|
||||
inbuilt("azure_ball", ::PokeBallModel)
|
||||
inbuilt("beast_ball", ::BeastBallModel)
|
||||
inbuilt("cherish_ball", ::PokeBallModel)
|
||||
inbuilt("citrine_ball", ::PokeBallModel)
|
||||
inbuilt("dive_ball", ::PokeBallModel)
|
||||
inbuilt("dream_ball", ::PokeBallModel)
|
||||
inbuilt("dusk_ball", ::PokeBallModel)
|
||||
inbuilt("fast_ball", ::PokeBallModel)
|
||||
inbuilt("friend_ball", ::PokeBallModel)
|
||||
inbuilt("great_ball", ::PokeBallModel)
|
||||
inbuilt("heal_ball", ::PokeBallModel)
|
||||
inbuilt("heavy_ball", ::PokeBallModel)
|
||||
inbuilt("level_ball", ::PokeBallModel)
|
||||
inbuilt("love_ball", ::PokeBallModel)
|
||||
inbuilt("lure_ball", ::PokeBallModel)
|
||||
inbuilt("luxury_ball", ::PokeBallModel)
|
||||
inbuilt("master_ball", ::PokeBallModel)
|
||||
inbuilt("moon_ball", ::PokeBallModel)
|
||||
inbuilt("nest_ball", ::PokeBallModel)
|
||||
inbuilt("net_ball", ::PokeBallModel)
|
||||
inbuilt("park_ball", ::PokeBallModel)
|
||||
inbuilt("poke_ball", ::PokeBallModel)
|
||||
inbuilt("premier_ball", ::PokeBallModel)
|
||||
inbuilt("quick_ball", ::PokeBallModel)
|
||||
inbuilt("repeat_ball", ::PokeBallModel)
|
||||
inbuilt("roseate_ball", ::PokeBallModel)
|
||||
inbuilt("safari_ball", ::PokeBallModel)
|
||||
inbuilt("slate_ball", ::PokeBallModel)
|
||||
inbuilt("sport_ball", ::PokeBallModel)
|
||||
inbuilt("strange_ball", ::PokeBallModel)
|
||||
inbuilt("timer_ball", ::PokeBallModel)
|
||||
inbuilt("ultra_ball", ::PokeBallModel)
|
||||
inbuilt("verdant_ball", ::PokeBallModel)
|
||||
inbuilt("ancient_poke_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_citrine_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_verdant_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_azure_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_roseate_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_slate_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_ivory_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_great_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_ultra_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_feather_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_wing_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_jet_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_heavy_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_leaden_ball", ::AncientPokeBallModel)
|
||||
inbuilt("ancient_gigaton_ball", ::AncientPokeBallModel)
|
||||
|
||||
inbuilt("squirtle", ::SquirtleModel)
|
||||
inbuilt("wartortle", ::WartortleModel)
|
||||
inbuilt("metapod", ::MetapodModel)
|
||||
@@ -666,4 +616,4 @@ object VaryingModelRepository {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-7
@@ -12,8 +12,7 @@ import com.cobblemon.mod.common.api.reactive.Observable
|
||||
import com.cobblemon.mod.common.api.reactive.SettableObservable
|
||||
import com.cobblemon.mod.common.api.scheduling.Schedulable
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokeball.AncientPokeBallModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokeball.PokeBallModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokeball.PokeBallPosableModel
|
||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
|
||||
import kotlin.random.Random
|
||||
|
||||
@@ -21,18 +20,21 @@ import kotlin.random.Random
|
||||
abstract class PokeBallPosableState : PosableState(), Schedulable {
|
||||
abstract val stateEmitter: SettableObservable<EmptyPokeBallEntity.CaptureState>
|
||||
abstract val shakeEmitter: Observable<Unit>
|
||||
protected open val group: String
|
||||
get() = if (this.currentModel is AncientPokeBallModel) "ancient_poke_ball" else "poke_ball"
|
||||
|
||||
protected open var lastKnownState: EmptyPokeBallEntity.CaptureState? = null
|
||||
|
||||
open fun initSubscriptions() {
|
||||
stateEmitter.subscribe { state ->
|
||||
|
||||
// if we fail to cast, provide default bone name.
|
||||
val group = (currentModel as? PokeBallPosableModel)?.rootBone ?: "poke_ball"
|
||||
|
||||
when (state) {
|
||||
EmptyPokeBallEntity.CaptureState.HIT -> {
|
||||
doLater {
|
||||
val model = this.currentModel!!
|
||||
after(seconds = 0.2F) {
|
||||
if (model is PokeBallModel && stateEmitter.get() == EmptyPokeBallEntity.CaptureState.HIT) {
|
||||
if (model is PokeBallPosableModel && stateEmitter.get() == EmptyPokeBallEntity.CaptureState.HIT) {
|
||||
doLater latest@{
|
||||
model.moveToPose(this, model.poses["open"]!!)
|
||||
after(seconds = 1.75F) {
|
||||
@@ -60,7 +62,7 @@ abstract class PokeBallPosableState : PosableState(), Schedulable {
|
||||
shakeEmitter
|
||||
.pipe(Observable.emitWhile { stateEmitter.get() == EmptyPokeBallEntity.CaptureState.SHAKE })
|
||||
.subscribe {
|
||||
val bob = "bob${Random.Default.nextInt(6) + 1}"
|
||||
val bob = "bob${Random.nextInt(6) + 1}"
|
||||
doLater { setActiveAnimations(currentModel!!.bedrockStateful(group, bob)) }
|
||||
}
|
||||
}
|
||||
@@ -79,4 +81,4 @@ abstract class PokeBallPosableState : PosableState(), Schedulable {
|
||||
this.lastKnownState = state
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -9,7 +9,7 @@
|
||||
package com.cobblemon.mod.common.client.render.pokeball
|
||||
|
||||
import com.cobblemon.mod.common.client.entity.EmptyPokeBallClientDelegate
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokeball.PosablePokeBallModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.pokeball.PosablePokeBallEntityModel
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
|
||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
|
||||
@@ -24,7 +24,7 @@ import net.minecraft.client.renderer.texture.OverlayTexture
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
|
||||
class PokeBallRenderer(context: EntityRendererProvider.Context) : EntityRenderer<EmptyPokeBallEntity>(context) {
|
||||
val model = PosablePokeBallModel()
|
||||
val model = PosablePokeBallEntityModel()
|
||||
|
||||
override fun getTextureLocation(pEntity: EmptyPokeBallEntity): ResourceLocation {
|
||||
return VaryingModelRepository.getTexture(pEntity.pokeBall.name, pEntity.delegate as EmptyPokeBallClientDelegate)
|
||||
@@ -58,4 +58,4 @@ class PokeBallRenderer(context: EntityRendererProvider.Context) : EntityRenderer
|
||||
poseStack.popPose()
|
||||
super.render(entity, yaw, partialTicks, poseStack, buffer, packedLight)
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-4
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.OrientationControllable
|
||||
import com.cobblemon.mod.common.api.pokedex.PokedexEntryProgress
|
||||
import com.cobblemon.mod.common.client.CobblemonClient
|
||||
import com.cobblemon.mod.common.client.battle.ClientBallDisplay
|
||||
import com.cobblemon.mod.common.client.entity.EmptyPokeBallClientDelegate
|
||||
import com.cobblemon.mod.common.client.entity.NPCClientDelegate
|
||||
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
|
||||
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate.Companion.BEAM_EXTEND_TIME
|
||||
@@ -43,6 +44,7 @@ import com.cobblemon.mod.common.util.lang
|
||||
import com.cobblemon.mod.common.util.math.DoubleRange
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import com.cobblemon.mod.common.util.math.remap
|
||||
import com.cobblemon.mod.common.util.toRGBA
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.math.Axis
|
||||
import net.minecraft.ChatFormatting
|
||||
@@ -320,6 +322,11 @@ class PokemonRenderer(
|
||||
val pokemonPosition = entity.position().add(0.0, entity.bbHeight / 2.0 * clientDelegate.activeSendoutScale.toDouble(), 0.0)
|
||||
val recallBallOrigin = (beamTarget as? Player)?.let { RecallArmAnimationTracker.get(it.uuid)?.beamOrigin }
|
||||
|
||||
val beamColorVec4f = when(beamTarget) {
|
||||
is EmptyPokeBallEntity -> (beamTarget.delegate as EmptyPokeBallClientDelegate).getBeamColor()
|
||||
else -> entity.pokemon.caughtBall.beamColor.rgb.toRGBA()
|
||||
}
|
||||
|
||||
val beamSourcePosition = when {
|
||||
// cover the recall ball origin presence
|
||||
recallBallOrigin != null -> recallBallOrigin
|
||||
@@ -385,10 +392,10 @@ class PokemonRenderer(
|
||||
partialTicks = partialTicks,
|
||||
totalLevelTime = entity.level().gameTime,
|
||||
height = pokemonPosition.distanceTo(beamSourcePosition.add(offset)).toFloat() * ratio,
|
||||
red = recallBeamColour.x,
|
||||
green = recallBeamColour.y,
|
||||
blue = recallBeamColour.z,
|
||||
alpha = recallBeamColour.w,
|
||||
red = beamColorVec4f.x,
|
||||
green = beamColorVec4f.y,
|
||||
blue = beamColorVec4f.z,
|
||||
alpha = beamColorVec4f.w,
|
||||
beamRadius = 0.03F,
|
||||
glowRadius = 0.07F,
|
||||
glowAlpha = 0.4F
|
||||
|
||||
+3
-3
@@ -30,7 +30,7 @@ object FishingRodTooltipGenerator : TooltipGenerator() {
|
||||
val baitComponent = stack.get(CobblemonItemComponents.BAIT)
|
||||
|
||||
// Add the description of the Poke Ball used in the rod
|
||||
ball.item.description.let {
|
||||
ball.stack.item.description.let {
|
||||
val bobberDescription = Component.translatable(
|
||||
"cobblemon.pokerod.bobber",
|
||||
it.copy().gray()
|
||||
@@ -40,7 +40,7 @@ object FishingRodTooltipGenerator : TooltipGenerator() {
|
||||
|
||||
val client = Minecraft.getInstance()
|
||||
val itemRegistry = client.level?.registryAccess()?.registryOrThrow(Registries.ITEM)
|
||||
itemRegistry?.let { registry ->
|
||||
itemRegistry?.let {
|
||||
baitComponent?.stack?.item?.description
|
||||
?.let { // maybe this can be simplified to not use the FishingBaits to get the stack and just use PokerodItem to get the stack since we have it already
|
||||
val baitDescription = "cobblemon.pokerod.bait".asTranslated(it.copy().gray(), PokerodItem.getBaitStackOnRod(stack).count)
|
||||
@@ -77,4 +77,4 @@ object FishingRodTooltipGenerator : TooltipGenerator() {
|
||||
|
||||
return resultLines
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
-18
@@ -8,6 +8,7 @@
|
||||
|
||||
package com.cobblemon.mod.common.entity.pokeball
|
||||
|
||||
import com.bedrockk.molang.runtime.MoLangRuntime
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
@@ -18,7 +19,9 @@ import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.pokeball.PokeBallCaptureCalculatedEvent
|
||||
import com.cobblemon.mod.common.api.events.pokeball.ThrownPokeballHitEvent
|
||||
import com.cobblemon.mod.common.api.events.pokemon.PokemonCapturedEvent
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
|
||||
import com.cobblemon.mod.common.api.net.serializers.StringSetDataSerializer
|
||||
import com.cobblemon.mod.common.api.net.serializers.Vec3DataSerializer
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
@@ -49,7 +52,16 @@ import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokeballPacket
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.pokemon.ai.PokemonBrain
|
||||
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import com.cobblemon.mod.common.util.asArrayValue
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.isServerSide
|
||||
import com.cobblemon.mod.common.util.lang
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import com.cobblemon.mod.common.util.playSoundServer
|
||||
import com.cobblemon.mod.common.util.sendParticlesServer
|
||||
import com.cobblemon.mod.common.util.setPositionSafely
|
||||
import com.cobblemon.mod.common.util.update
|
||||
import com.cobblemon.mod.common.util.withQueryValue
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.core.particles.ParticleTypes
|
||||
@@ -65,7 +77,10 @@ import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundEvents
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.util.Mth.PI
|
||||
import net.minecraft.world.entity.*
|
||||
import net.minecraft.world.entity.EntityDimensions
|
||||
import net.minecraft.world.entity.EntityType
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.Pose
|
||||
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity
|
||||
import net.minecraft.world.entity.projectile.ThrowableItemProjectile
|
||||
import net.minecraft.world.item.Item
|
||||
@@ -97,7 +112,9 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
const val SECONDS_BETWEEN_SHAKES = 1.25F
|
||||
const val SECONDS_BEFORE_SHAKE = 1F
|
||||
|
||||
val DIMENSIONS = EntityDimensions.fixed(0.4F, 0.4F)
|
||||
val DIMENSIONS: EntityDimensions = EntityDimensions.fixed(0.4F, 0.4F)
|
||||
|
||||
val runtime = MoLangRuntime().setup()
|
||||
}
|
||||
|
||||
val dataTrackerEmitter = SimpleObservable<EntityDataAccessor<*>>()
|
||||
@@ -125,7 +142,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
.addFunction("thrower") { owner?.asMostSpecificMoLangValue() ?: DoubleValue.ZERO }
|
||||
|
||||
override fun defineSynchedData(builder: SynchedEntityData.Builder) {
|
||||
pokeBall = PokeBalls.POKE_BALL
|
||||
pokeBall = PokeBalls.STRANGE_BALL
|
||||
super.defineSynchedData(builder)
|
||||
builder.define(CAPTURE_STATE, CaptureState.NOT.ordinal.toByte())
|
||||
builder.define(ASPECTS, emptySet())
|
||||
@@ -158,7 +175,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
addPosableFunctions(struct)
|
||||
}
|
||||
|
||||
constructor(world: Level) : this(pokeBall = PokeBalls.POKE_BALL, world = world)
|
||||
constructor(world: Level) : this(pokeBall = PokeBalls.STRANGE_BALL, world = world)
|
||||
constructor(
|
||||
pokeBall: PokeBall,
|
||||
world: Level,
|
||||
@@ -176,7 +193,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
this.pokeBall = pokeBall
|
||||
}
|
||||
|
||||
var pokeBall: PokeBall = PokeBalls.POKE_BALL
|
||||
var pokeBall: PokeBall = PokeBalls.STRANGE_BALL
|
||||
|
||||
override fun onHitBlock(hitResult: BlockHitResult) {
|
||||
if (captureState == CaptureState.NOT) {
|
||||
@@ -187,7 +204,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
discard()
|
||||
val player = this.owner as? ServerPlayer
|
||||
if (player?.isCreative == false) {
|
||||
spawnAtLocation(defaultItem)
|
||||
spawnAtLocation(pokeBall.stack())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -245,7 +262,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
lang(
|
||||
"capture.attempted_capture",
|
||||
throwerActor.getName(),
|
||||
pokeBall.item().description,
|
||||
pokeBall.item().getDescriptionId(pokeBall.stack),
|
||||
pokemonEntity.exposedSpecies.translatedName
|
||||
).yellow()
|
||||
)
|
||||
@@ -284,7 +301,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
val owner = owner
|
||||
discard()
|
||||
val player = owner?.takeIf { it is ServerPlayer } as? ServerPlayer
|
||||
if (player?.isCreative != true) spawnAtLocation(defaultItem)
|
||||
if (player?.isCreative != true) spawnAtLocation(pokeBall.stack())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -296,7 +313,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
delegate.tick(this)
|
||||
|
||||
if (level().isServerSide()) {
|
||||
|
||||
|
||||
|
||||
if (this.tickCount > 600 && this.capturingPokemon == null) {
|
||||
this.remove(RemovalReason.DISCARDED)
|
||||
@@ -346,7 +363,8 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
// Do a capture
|
||||
val pokemon = capturingPokemon ?: return
|
||||
val player = this.owner as? ServerPlayer ?: return
|
||||
val captureTime = if (pokeBall.ancient == true) 1.8F else 1F
|
||||
|
||||
val captureTime = if (pokeBall.ancient) 1.8F else 1F
|
||||
after(seconds = captureTime) {
|
||||
// Dupes occurred by double-adding Pokémon, this hopefully prevents it triple-condom style
|
||||
// wtf did I just read above me
|
||||
@@ -355,8 +373,13 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
discard()
|
||||
captureFuture.complete(true)
|
||||
val party = player.party()
|
||||
|
||||
val effectsRuntime = runtime
|
||||
.withQueryValue("pokeball", struct)
|
||||
.withQueryValue("pokemon", pokemon.asMoLangValue())
|
||||
|
||||
pokemon.pokemon.caughtBall = pokeBall
|
||||
pokeBall.effects.forEach { effect -> effect.apply(player, pokemon.pokemon) }
|
||||
pokeBall.effects.forEach { effect -> effect.resolve(effectsRuntime) }
|
||||
party.add(pokemon.pokemon)
|
||||
val leashHolder = pokemon.leashHolder
|
||||
|
||||
@@ -380,7 +403,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
}
|
||||
// Emits a shake by changing the value to the opposite of what it currently is. Sends an update to the client basically.
|
||||
// We could replace this with a packet, but it feels awfully excessive when we already have 5 bajillion packets.
|
||||
if (this.pokeBall.ancient) {
|
||||
if (pokeBall.ancient) {
|
||||
when (captureResult.numberOfShakes) {
|
||||
1 -> ancientBallShake(setOf("q.bedrock_stateful('ancient_poke_ball', 'weirdhop')"))
|
||||
2 -> ancientBallShake(setOf("q.bedrock_stateful('ancient_poke_ball', 'bighop')"))
|
||||
@@ -395,7 +418,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
private fun breakFree() {
|
||||
val pokemon = capturingPokemon ?: return
|
||||
pokemon.setPositionSafely(position())
|
||||
|
||||
|
||||
pokemon.beamMode = 2
|
||||
pokemon.isInvisible = false
|
||||
pokemon.isSilent = false
|
||||
@@ -425,8 +448,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
|
||||
after(seconds = 0.1F) {
|
||||
captureFuture.complete(false)
|
||||
val ballType =
|
||||
this.pokeBall.name.path.lowercase().replace("_", "")
|
||||
val ballType = pokeBall.name.path.lowercase().replace("_", "")
|
||||
val mode = "casual"
|
||||
val sendflash =
|
||||
BedrockParticleOptionsRepository.getEffect(cobblemonResource("${ballType}/${mode}/sendflash"))
|
||||
@@ -443,7 +465,7 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
|
||||
override fun getDefaultItem(): Item = pokeBall.item()
|
||||
|
||||
override fun getDimensions(pPose: Pose) = DIMENSIONS
|
||||
override fun getDimensions(pPose: Pose): EntityDimensions = DIMENSIONS
|
||||
|
||||
private fun attemptCatch(pokemonEntity: PokemonEntity) {
|
||||
pokemonEntity.busyLocks.add(this)
|
||||
@@ -551,4 +573,4 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
|
||||
|
||||
override fun waterDrag(): Float = this.pokeBall.waterDragValue
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2744,9 +2744,4 @@ open class PokemonEntity(
|
||||
}
|
||||
|
||||
fun hasRider() = this.passengers.any { it is LivingEntity }
|
||||
|
||||
override fun playStepSound(pos: BlockPos, state: BlockState) {
|
||||
if (this.pokemon.species.silenceStepSounds) return
|
||||
super.playStepSound(pos, state)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,42 +8,31 @@
|
||||
|
||||
package com.cobblemon.mod.common.item
|
||||
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
|
||||
import com.cobblemon.mod.common.item.components.PokeBallComponent
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.util.isServerSide
|
||||
import com.cobblemon.mod.common.util.math.geometry.toRadians
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.InteractionHand
|
||||
import net.minecraft.world.InteractionResultHolder
|
||||
import net.minecraft.world.item.Rarity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.Level
|
||||
import kotlin.math.cos
|
||||
|
||||
class PokeBallItem(
|
||||
val pokeBall: PokeBall
|
||||
) : CobblemonItem(Properties().apply {
|
||||
when (pokeBall.name) {
|
||||
// Master balls are a netherite product and should be fire immune
|
||||
PokeBalls.MASTER_BALL.name -> fireResistant().rarity(Rarity.EPIC)
|
||||
PokeBalls.CHERISH_BALL.name -> rarity(Rarity.EPIC)
|
||||
PokeBalls.ANCIENT_ORIGIN_BALL.name -> rarity(Rarity.EPIC)
|
||||
PokeBalls.BEAST_BALL.name -> rarity(Rarity.RARE)
|
||||
}
|
||||
}) {
|
||||
class PokeBallItem(var pokeBall: PokeBall) : CobblemonItem(pokeBall.itemProperties()) {
|
||||
|
||||
override fun use(world: Level, player: Player, usedHand: InteractionHand): InteractionResultHolder<ItemStack> {
|
||||
val itemStack = player.getItemInHand(usedHand)
|
||||
if (world.isServerSide()) {
|
||||
throwPokeBall(world, player as ServerPlayer)
|
||||
throwPokeBall(world, player as ServerPlayer, PokeBallComponent.getPokeBall(itemStack))
|
||||
}
|
||||
itemStack.consume(1, player)
|
||||
return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide)
|
||||
}
|
||||
|
||||
private fun throwPokeBall(world: Level, player: ServerPlayer) {
|
||||
private fun throwPokeBall(world: Level, player: ServerPlayer, pokeBall: PokeBall) {
|
||||
val pokeBallEntity = EmptyPokeBallEntity(pokeBall, player.level(), player).apply {
|
||||
val overhandFactor: Float = if (player.xRot < 0) {
|
||||
5f * cos(player.xRot.toRadians())
|
||||
@@ -57,4 +46,7 @@ class PokeBallItem(
|
||||
}
|
||||
world.addFreshEntity(pokeBallEntity)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDescriptionId(itemStack: ItemStack): String =
|
||||
PokeBallComponent.getPokeBall(itemStack).name.toLanguageKey("item")
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Cobblemon Contributors
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.item.components
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonItemComponents
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.item.PokeBallItem
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import io.netty.buffer.ByteBuf
|
||||
import net.minecraft.network.codec.ByteBufCodecs
|
||||
import net.minecraft.network.codec.StreamCodec
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
data class PokeBallComponent(val name: ResourceLocation) {
|
||||
companion object {
|
||||
val CODEC: Codec<PokeBallComponent> = RecordCodecBuilder.create {
|
||||
it
|
||||
.group(ResourceLocation.CODEC.fieldOf("type").forGetter(PokeBallComponent::name))
|
||||
.apply(it, ::PokeBallComponent)
|
||||
}
|
||||
|
||||
val PACKET_CODEC: StreamCodec<ByteBuf, PokeBallComponent> = ByteBufCodecs.fromCodec(CODEC)
|
||||
|
||||
@JvmStatic
|
||||
fun getPokeBall(stack: ItemStack): PokeBall {
|
||||
return stack.get(CobblemonItemComponents.POKE_BALL)?.name?.let(PokeBalls::getPokeBall)
|
||||
?: (stack.item as? PokeBallItem)?.pokeBall
|
||||
?: PokeBalls.STRANGE_BALL
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setPokeBall(stack: ItemStack, ball: PokeBall): ItemStack {
|
||||
stack.set(CobblemonItemComponents.POKE_BALL, PokeBallComponent(ball.name))
|
||||
return stack
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createStack(ball: PokeBall?): ItemStack {
|
||||
var result = PokeBalls.STRANGE_BALL
|
||||
if (ball == null) {
|
||||
Cobblemon.LOGGER.error("Attempted to create poke ball stack with null config, falling to strange ball.")
|
||||
} else {
|
||||
result = ball
|
||||
}
|
||||
val stack = ItemStack(CobblemonItems.STRANGE_BALL)
|
||||
return setPokeBall(stack, result)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val ball: PokeBall
|
||||
get() = PokeBalls.getPokeBall(name)
|
||||
}
|
||||
@@ -11,10 +11,12 @@ package com.cobblemon.mod.common.item.group
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonItemComponents
|
||||
import com.cobblemon.mod.common.CobblemonItems
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
||||
import com.cobblemon.mod.common.api.tms.TechnicalMachines
|
||||
import com.cobblemon.mod.common.block.TypeGemClusterBlock
|
||||
import com.cobblemon.mod.common.item.AprijuiceItem
|
||||
import com.cobblemon.mod.common.item.components.PokeBallComponent
|
||||
import com.cobblemon.mod.common.item.components.RideBoostsComponent
|
||||
import com.cobblemon.mod.common.item.components.TMMoveComponent
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
@@ -942,7 +944,12 @@ object CobblemonItemGroups {
|
||||
}
|
||||
|
||||
private fun utilityItemEntries(displayContext: ItemDisplayParameters, entries: Output) {
|
||||
CobblemonItems.pokeBalls.forEach(entries::accept)
|
||||
CobblemonItems.pokeBalls.values.forEach(entries::accept)
|
||||
|
||||
PokeBalls.all()
|
||||
.filter { ball -> CobblemonItems.pokeBalls.keys.none { it == ball.name } }
|
||||
.forEach { entries.accept(PokeBallComponent.createStack(it)) }
|
||||
|
||||
CobblemonItems.pokeRods.forEach(entries::accept)
|
||||
CobblemonItems.pokedexes.forEach(entries::accept)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
package com.cobblemon.mod.common.item.interactive
|
||||
|
||||
import com.cobblemon.mod.common.CobblemonItemComponents
|
||||
import com.cobblemon.mod.common.item.components.FoodComponent
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import net.minecraft.sounds.SoundEvents
|
||||
@@ -24,15 +23,10 @@ import net.minecraft.world.level.Level
|
||||
class PonigiriItem : Item(
|
||||
Properties().stacksTo(64)
|
||||
.food(FoodProperties.Builder()
|
||||
.nutrition(NUTRITION)
|
||||
.saturationModifier(SATURATION_MODIFIER)
|
||||
.nutrition(2)
|
||||
.saturationModifier(0.55f)
|
||||
.build())
|
||||
) {
|
||||
companion object {
|
||||
const val NUTRITION = 2
|
||||
const val SATURATION_MODIFIER = 0.55f
|
||||
}
|
||||
|
||||
override fun getName(stack: ItemStack): Component {
|
||||
|
||||
val ingredients = stack.get(CobblemonItemComponents.INGREDIENT)
|
||||
@@ -65,9 +59,4 @@ class PonigiriItem : Item(
|
||||
override fun getEatingSound(): SoundEvent {
|
||||
return SoundEvents.GENERIC_EAT
|
||||
}
|
||||
|
||||
fun getFoodValues(stack: ItemStack): Pair<Int, Float> {
|
||||
val (hunger, saturation) = stack.getOrDefault(CobblemonItemComponents.FOOD, FoodComponent(NUTRITION, SATURATION_MODIFIER))
|
||||
return hunger to saturation
|
||||
}
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.pokeballs
|
||||
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.net.messages.client.data.DataRegistrySyncPacket
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.cobblemon.mod.common.util.adapters.CobblemonCatchRateModifierAdapter
|
||||
import com.cobblemon.mod.common.util.adapters.RegistryAccessResolver
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import java.awt.Color
|
||||
|
||||
class PokeBallsRegistrySyncPacket(balls: Map<ResourceLocation, PokeBall>) : DataRegistrySyncPacket<PokeBall, PokeBallsRegistrySyncPacket>(balls.values) {
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("poke_balls")
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): PokeBallsRegistrySyncPacket {
|
||||
return PokeBallsRegistrySyncPacket(emptyMap()).apply { decodeBuffer(buffer) }
|
||||
}
|
||||
}
|
||||
|
||||
override val id = ID
|
||||
|
||||
override fun encodeEntry(buffer: RegistryFriendlyByteBuf, entry: PokeBall) {
|
||||
buffer.writeResourceLocation(entry.name)
|
||||
buffer.writeResourceLocation(entry.model2d)
|
||||
buffer.writeResourceLocation(entry.model3d)
|
||||
buffer.writeFloat(entry.throwPower)
|
||||
buffer.writeFloat(entry.waterDragValue)
|
||||
buffer.writeBoolean(entry.ancient)
|
||||
buffer.writeInt(entry.beamColor.rgb)
|
||||
CobblemonCatchRateModifierAdapter.encode(entry.catchRateModifier, buffer)
|
||||
}
|
||||
|
||||
override fun decodeEntry(buffer: RegistryFriendlyByteBuf): PokeBall {
|
||||
val name = buffer.readResourceLocation()
|
||||
val model2d = buffer.readResourceLocation()
|
||||
val model3d = buffer.readResourceLocation()
|
||||
val throwPower = buffer.readFloat()
|
||||
val waterDrag = buffer.readFloat()
|
||||
val ancient = buffer.readBoolean()
|
||||
val color = Color(buffer.readInt())
|
||||
val catchRateModifier = CobblemonCatchRateModifierAdapter.decode(buffer)
|
||||
|
||||
return PokeBall(
|
||||
name = name,
|
||||
model2d = model2d,
|
||||
model3d = model3d,
|
||||
throwPower = throwPower,
|
||||
waterDragValue = waterDrag,
|
||||
ancient = ancient,
|
||||
beamColor = color,
|
||||
catchRateModifier = catchRateModifier,
|
||||
effects = listOf(),
|
||||
)
|
||||
}
|
||||
|
||||
override fun synchronizeDecoded(entries: Collection<PokeBall>) {
|
||||
PokeBalls.reload(entries.associateBy { it.name }, RegistryAccessResolver.getAccess())
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -30,8 +30,8 @@ class CaughtBallUpdatePacket(pokemon: () -> Pokemon?, value: PokeBall): SingleUp
|
||||
val ID = cobblemonResource("caught_ball_update")
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): CaughtBallUpdatePacket {
|
||||
val pokemon = decodePokemon(buffer)
|
||||
val pokeBall = PokeBalls.getPokeBall(buffer.readIdentifier()) ?: PokeBalls.POKE_BALL
|
||||
val pokeBall = PokeBalls.getPokeBall(buffer.readIdentifier())
|
||||
return CaughtBallUpdatePacket(pokemon, pokeBall)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +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://www.mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.messages.server.storage.pc
|
||||
|
||||
import com.cobblemon.mod.common.api.net.NetworkPacket
|
||||
import com.cobblemon.mod.common.api.storage.pc.PCPosition
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.readPCPosition
|
||||
import com.cobblemon.mod.common.util.writePCPosition
|
||||
import java.util.UUID
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
|
||||
class MovePCPokemonBatchPacket(val moves: List<PCPokemonMove>) : NetworkPacket<MovePCPokemonBatchPacket> {
|
||||
override val id = ID
|
||||
|
||||
data class PCPokemonMove(
|
||||
val pokemonID: UUID,
|
||||
val oldPosition: PCPosition,
|
||||
val newPosition: PCPosition
|
||||
)
|
||||
|
||||
override fun encode(buffer: RegistryFriendlyByteBuf) {
|
||||
buffer.writeVarInt(moves.size)
|
||||
moves.forEach { move ->
|
||||
buffer.writeUUID(move.pokemonID)
|
||||
buffer.writePCPosition(move.oldPosition)
|
||||
buffer.writePCPosition(move.newPosition)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val ID = cobblemonResource("move_pc_pokemon_batch")
|
||||
const val MAX_MOVES = 60
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf): MovePCPokemonBatchPacket {
|
||||
val size = buffer.readVarInt()
|
||||
require(size in 1..MAX_MOVES) { "Invalid batch PC move size: $size" }
|
||||
return MovePCPokemonBatchPacket(
|
||||
List(size) {
|
||||
PCPokemonMove(
|
||||
pokemonID = buffer.readUUID(),
|
||||
oldPosition = buffer.readPCPosition(),
|
||||
newPosition = buffer.readPCPosition()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
-23
@@ -1,23 +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://www.mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.net.serverhandling.storage.pc
|
||||
|
||||
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
|
||||
import com.cobblemon.mod.common.api.storage.pc.link.PCLinkManager
|
||||
import com.cobblemon.mod.common.net.messages.client.storage.pc.ClosePCPacket
|
||||
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePCPokemonBatchPacket
|
||||
import net.minecraft.server.MinecraftServer
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
|
||||
object MovePCPokemonBatchHandler : ServerNetworkPacketHandler<MovePCPokemonBatchPacket> {
|
||||
override fun handle(packet: MovePCPokemonBatchPacket, server: MinecraftServer, player: ServerPlayer) {
|
||||
val pc = PCLinkManager.getPC(player) ?: return run { ClosePCPacket(null).sendToPlayer(player) }
|
||||
pc.moveBatch(packet.moves.map { Triple(it.pokemonID, it.oldPosition, it.newPosition) })
|
||||
}
|
||||
}
|
||||
@@ -9,17 +9,25 @@
|
||||
package com.cobblemon.mod.common.pokeball
|
||||
|
||||
import com.bedrockk.molang.runtime.struct.QueryStruct
|
||||
import com.bedrockk.molang.runtime.value.DoubleValue
|
||||
import com.bedrockk.molang.runtime.value.StringValue
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addPokeBallFunctions
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
|
||||
import com.cobblemon.mod.common.api.molang.ObjectValue
|
||||
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.CaptureEffect
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.CatchRateModifier
|
||||
import com.cobblemon.mod.common.item.PokeBallItem
|
||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||
import com.cobblemon.mod.common.util.adapters.RegistryAccessResolver
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.codec.CodecUtils
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.mojang.serialization.Codec
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Rarity
|
||||
import java.awt.Color
|
||||
|
||||
/**
|
||||
* Base poke ball object
|
||||
@@ -31,37 +39,54 @@ import net.minecraft.resources.ResourceLocation
|
||||
* @property waterDragValue The value of the water drag modifier when the entity travels, default is 0.8.
|
||||
* @property model2d The identifier for the resource this Pokéball will use for the 2d model.
|
||||
* @property model3d The identifier for the resource this Pokéball will use for the 3d model.
|
||||
* @property ancient Marks this Pokéball as ancient, which makes it play different animations on catch hops
|
||||
* @property beamColor Defines the beam color of pokeball
|
||||
*/
|
||||
open class PokeBall(
|
||||
val name: ResourceLocation,
|
||||
class PokeBall @JvmOverloads constructor(
|
||||
@Transient // Assigns in PokeBalls.reload
|
||||
var name: ResourceLocation = cobblemonResource("strange_ball"),
|
||||
@SerializedName("modifier")
|
||||
val catchRateModifier: CatchRateModifier = CatchRateModifier.DUMMY,
|
||||
val effects: List<CaptureEffect> = listOf(),
|
||||
val effects: List<ExpressionLike> = listOf(),
|
||||
@SerializedName("item_properties")
|
||||
val itemProperties: PokeBallProperties = PokeBallProperties(),
|
||||
@SerializedName("water_drag")
|
||||
val waterDragValue: Float,
|
||||
@SerializedName("model_2d")
|
||||
val model2d: ResourceLocation,
|
||||
@SerializedName("model_3d")
|
||||
val model3d: ResourceLocation,
|
||||
@SerializedName("throw_power")
|
||||
val throwPower: Float,
|
||||
val ancient: Boolean
|
||||
val ancient: Boolean = false,
|
||||
@SerializedName("beam_color")
|
||||
val beamColor: Color = Color.RED,
|
||||
) {
|
||||
val struct = QueryStruct(hashMapOf())
|
||||
.addFunction("name") { StringValue(name.toString()) }
|
||||
.addFunction("water_drag_value") { DoubleValue(waterDragValue) }
|
||||
.addFunction("throw_power") { DoubleValue(throwPower) }
|
||||
.addFunction("is_ancient") { DoubleValue(ancient) }
|
||||
// .addFunction("item") { } // requires a registry which is hard
|
||||
@delegate:Transient
|
||||
val struct: QueryStruct by lazy {
|
||||
ObjectValue(this)
|
||||
.addPokeBallFunctions(this)
|
||||
.addFunction("stack") { this.stack().asMoLangValue(RegistryAccessResolver.getAccess()) }
|
||||
}
|
||||
|
||||
// This gets attached during item registry
|
||||
internal lateinit var item: PokeBallItem
|
||||
@Transient
|
||||
internal lateinit var stack: ItemStack
|
||||
|
||||
fun item(): PokeBallItem = this.item
|
||||
fun item(): PokeBallItem = this.stack.item as PokeBallItem
|
||||
|
||||
fun stack(count: Int = 1): ItemStack =
|
||||
ItemStack(this.item(), count)
|
||||
|
||||
fun itemProperties(): Item.Properties = Item.Properties()
|
||||
.rarity(this.itemProperties.rarity)
|
||||
.let { if (itemProperties.fireResistant) it.fireResistant() else it }
|
||||
|
||||
@Deprecated("This is a temporary solution for the safari ball dilemma", ReplaceWith("target.currentHealth"))
|
||||
internal fun hpForCalculation(target: Pokemon): Int = if (this.name == PokeBalls.SAFARI_BALL.name) target.maxHealth else target.currentHealth
|
||||
internal fun hpForCalculation(target: Pokemon): Int =
|
||||
if (this.name == PokeBalls.SAFARI_BALL.name) target.maxHealth else target.currentHealth
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
val BY_IDENTIFIER_CODEC: Codec<PokeBall> = CodecUtils.createByIdentifierCodec(
|
||||
PokeBalls::getPokeBall,
|
||||
@@ -70,4 +95,8 @@ open class PokeBall(
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
data class PokeBallProperties(
|
||||
val fireResistant: Boolean = false,
|
||||
val rarity: Rarity = Rarity.COMMON
|
||||
)
|
||||
}
|
||||
+2
-2
@@ -46,7 +46,7 @@ object Gen1CaptureCalculator : CaptureCalculator {
|
||||
}
|
||||
// This value can be reused when calculating the shakes in case of breakout.
|
||||
val nBound = when (pokeBall) {
|
||||
PokeBalls.POKE_BALL -> 255
|
||||
PokeBalls.POKE_BALL, PokeBalls.STRANGE_BALL -> 255
|
||||
PokeBalls.GREAT_BALL -> 200
|
||||
else -> 150
|
||||
}
|
||||
@@ -97,4 +97,4 @@ object Gen1CaptureCalculator : CaptureCalculator {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -642,7 +642,16 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
scaleModifier = 1F + (roundedPercent / 100F)
|
||||
}
|
||||
|
||||
var caughtBall: PokeBall = PokeBalls.POKE_BALL
|
||||
var caughtBall: PokeBall = PokeBalls.STRANGE_BALL
|
||||
get() {
|
||||
return try {
|
||||
field
|
||||
} catch (_: Exception) {
|
||||
// account for possibility of ball removal (datapack disable/removal)
|
||||
CaughtBallUpdatePacket({ this }, PokeBalls.STRANGE_BALL)
|
||||
PokeBalls.STRANGE_BALL
|
||||
}
|
||||
}
|
||||
set(value) {
|
||||
field = value
|
||||
onChange(CaughtBallUpdatePacket({ this }, field))
|
||||
|
||||
@@ -173,7 +173,6 @@ class Species : ShowdownIdentifiable {
|
||||
.addStandardFunctions()
|
||||
.addSpeciesFunctions(this)
|
||||
|
||||
var silenceStepSounds = false
|
||||
|
||||
fun initialize() {
|
||||
Cobblemon.statProvider.provide(this)
|
||||
@@ -257,7 +256,6 @@ class Species : ShowdownIdentifiable {
|
||||
}
|
||||
|
||||
this.riding.encode(buffer)
|
||||
buffer.writeBoolean(this.silenceStepSounds)
|
||||
}
|
||||
|
||||
fun decode(buffer: RegistryFriendlyByteBuf) {
|
||||
@@ -301,7 +299,6 @@ class Species : ShowdownIdentifiable {
|
||||
}
|
||||
}
|
||||
this.riding = RidingProperties.decode(buffer)
|
||||
this.silenceStepSounds = buffer.readBoolean()
|
||||
this.initialize()
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ import java.nio.file.SimpleFileVisitor
|
||||
import java.nio.file.attribute.BasicFileAttributes
|
||||
import kotlin.io.path.toPath
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import kotlin.io.path.name
|
||||
import kotlin.text.endsWith
|
||||
|
||||
/**
|
||||
* Basic functions for dealing with assets inside the mod, using the standard file visitor
|
||||
@@ -29,7 +31,9 @@ import net.minecraft.resources.ResourceLocation
|
||||
*/
|
||||
object AssetLoading {
|
||||
fun ResourceLocation.toPath() = toURL()?.toPath()
|
||||
fun ResourceLocation.toURL() = Cobblemon::class.java.getResource(String.format("/assets/%s/%s", namespace, path))?.toURI()
|
||||
fun ResourceLocation.toURL() =
|
||||
Cobblemon::class.java.getResource(String.format("/assets/%s/%s", namespace, path))?.toURI()
|
||||
|
||||
fun fileSearch(dir: Path, filter: (Path) -> Boolean, recursive: Boolean): List<Path> {
|
||||
val files = mutableListOf<Path>()
|
||||
Files.walkFileTree(dir, object : SimpleFileVisitor<Path>() {
|
||||
@@ -58,4 +62,14 @@ object AssetLoading {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* very "clever" way to get all files in asset folder in loaded minecraft client env
|
||||
*
|
||||
*/
|
||||
fun allAtPath(dir: Path, recursive: Boolean = false, suffix: String = ".json", take: Int = 2) = fileSearch(
|
||||
dir = dir,
|
||||
recursive = recursive,
|
||||
filter = { path -> path.name.endsWith(suffix) },
|
||||
).map { it.toString().removeSuffix(suffix).split("/").takeLast(take).joinToString("/") }
|
||||
}
|
||||
@@ -234,11 +234,11 @@ fun Entity.isDusk(): Boolean {
|
||||
}
|
||||
|
||||
fun Entity.isStandingOn(blocks: Set<String>, depth: Int = 2): Boolean {
|
||||
for (currentDepth in 0..depth) {
|
||||
val bellowBlockPos = blockPosBelowThatAffectsMyMovement.below(currentDepth)
|
||||
for (currentDepth in 1..depth) {
|
||||
val bellowBlockPos = blockPosition().below(currentDepth)
|
||||
val blockState = level().getBlockState(bellowBlockPos)
|
||||
|
||||
if (blockState.isAir) continue
|
||||
if (blockState.isAir || !blockState.isCollisionShapeFullBlock(level(), bellowBlockPos)) continue
|
||||
|
||||
val elementOrTags = ExtraCodecs.TAG_OR_ELEMENT_ID.listOf().decode(JavaOps.INSTANCE, blocks.toList()).result().get().first
|
||||
elementOrTags.forEach {
|
||||
|
||||
+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.util.adapters
|
||||
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.CaptureEffect
|
||||
import com.cobblemon.mod.common.util.readString
|
||||
import com.cobblemon.mod.common.util.writeString
|
||||
import com.google.common.collect.HashBiMap
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
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 net.minecraft.network.FriendlyByteBuf
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
object CobblemonCaptureEffectAdapter : JsonDeserializer<CaptureEffect>, JsonSerializer<CaptureEffect> {
|
||||
private const val VARIANT = "variant"
|
||||
|
||||
private val types = HashBiMap.create<String, KClass<out CaptureEffect>>()
|
||||
|
||||
val gson: Gson by lazy {
|
||||
GsonBuilder()
|
||||
.registerTypeAdapter(CaptureEffect::class.java, CobblemonCaptureEffectAdapter)
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
}
|
||||
|
||||
fun <T : CaptureEffect> registerType(id: String, type: KClass<T>) {
|
||||
this.types[id.lowercase()] = type
|
||||
}
|
||||
|
||||
override fun deserialize(
|
||||
json: JsonElement,
|
||||
typeOfT: Type,
|
||||
context: JsonDeserializationContext,
|
||||
): CaptureEffect {
|
||||
val variant =
|
||||
json.asJsonObject
|
||||
.get(VARIANT)
|
||||
.asString
|
||||
.lowercase()
|
||||
val type = getModifierType(variant)
|
||||
return context.deserialize(json, type.java)
|
||||
}
|
||||
|
||||
override fun serialize(
|
||||
effect: CaptureEffect,
|
||||
typeOfSrc: Type,
|
||||
context: JsonSerializationContext,
|
||||
): JsonElement {
|
||||
val json = context.serialize(effect, effect::class.java).asJsonObject
|
||||
val variant = getVariant(effect)
|
||||
json.addProperty(VARIANT, variant)
|
||||
return json
|
||||
}
|
||||
|
||||
fun encode(effect: CaptureEffect, buffer: FriendlyByteBuf) {
|
||||
buffer.writeString(gson.toJson(effect, CaptureEffect::class.java))
|
||||
}
|
||||
|
||||
fun decode(buffer: FriendlyByteBuf): CaptureEffect = gson.fromJson(buffer.readString(), CaptureEffect::class.java)
|
||||
|
||||
private fun getVariant(effect: CaptureEffect): String {
|
||||
val variant =
|
||||
this.types.inverse()[effect::class]
|
||||
?: throw IllegalArgumentException("Cannot resolve pokeball capture effect for type ${effect::class.qualifiedName}")
|
||||
|
||||
return variant
|
||||
}
|
||||
|
||||
private fun getModifierType(variant: String): KClass<out CaptureEffect> {
|
||||
val effectType =
|
||||
this.types[variant] ?: throw IllegalArgumentException("Cannot resolve pokeball capture effect type for variant $variant")
|
||||
|
||||
return effectType
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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.bedrockk.molang.Expression
|
||||
import com.cobblemon.mod.common.api.molang.ExpressionLike
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.CatchRateModifier
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.BaseStatModifier
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.CatchRateModifierAdapter
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.GuaranteedModifier
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.LabelModifier
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.ExpressionModifier
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.PropertyBasedModifier
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.ScriptModifier
|
||||
import com.cobblemon.mod.common.api.pokeball.catching.modifiers.SimpleModifier
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
|
||||
import com.cobblemon.mod.common.util.readString
|
||||
import com.cobblemon.mod.common.util.writeString
|
||||
import com.google.common.collect.HashBiMap
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
object CobblemonCatchRateModifierAdapter : CatchRateModifierAdapter {
|
||||
private const val VARIANT = "variant"
|
||||
|
||||
private val types = HashBiMap.create<String, KClass<out CatchRateModifier>>()
|
||||
|
||||
init {
|
||||
this.registerType(SimpleModifier.VARIANT, SimpleModifier::class)
|
||||
this.registerType(BaseStatModifier.VARIANT, BaseStatModifier::class)
|
||||
this.registerType(GuaranteedModifier.VARIANT, GuaranteedModifier::class)
|
||||
this.registerType(PropertyBasedModifier.VARIANT, PropertyBasedModifier::class)
|
||||
this.registerType(LabelModifier.VARIANT, LabelModifier::class)
|
||||
this.registerType(ExpressionModifier.VARIANT, ExpressionModifier::class)
|
||||
this.registerType(ScriptModifier.VARIANT, ScriptModifier::class)
|
||||
}
|
||||
|
||||
val gson: Gson by lazy {
|
||||
GsonBuilder()
|
||||
.registerTypeAdapter(ResourceLocation::class.java, IdentifierAdapter)
|
||||
.registerTypeAdapter(Expression::class.java, ExpressionAdapter)
|
||||
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
|
||||
.registerTypeAdapter(PokemonProperties::class.java, pokemonPropertiesShortAdapter)
|
||||
.registerTypeAdapter(CatchRateModifier::class.java, CobblemonCatchRateModifierAdapter)
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
}
|
||||
|
||||
override fun <T : CatchRateModifier> registerType(id: String, type: KClass<T>) {
|
||||
this.types[id.lowercase()] = type
|
||||
}
|
||||
|
||||
override fun deserialize(
|
||||
json: JsonElement,
|
||||
typeOfT: Type,
|
||||
context: JsonDeserializationContext,
|
||||
): CatchRateModifier {
|
||||
val variant =
|
||||
json.asJsonObject
|
||||
.get(VARIANT)
|
||||
.asString
|
||||
.lowercase()
|
||||
val type = getModifierType(variant)
|
||||
return context.deserialize(json, type.java)
|
||||
}
|
||||
|
||||
override fun serialize(
|
||||
modifier: CatchRateModifier,
|
||||
typeOfSrc: Type,
|
||||
context: JsonSerializationContext,
|
||||
): JsonElement {
|
||||
val json = context.serialize(modifier, modifier::class.java).asJsonObject
|
||||
val variant = getVariant(modifier)
|
||||
json.addProperty(VARIANT, variant)
|
||||
return json
|
||||
}
|
||||
|
||||
fun encode(modifier: CatchRateModifier, buffer: FriendlyByteBuf) {
|
||||
buffer.writeString(gson.toJson(modifier, CatchRateModifier::class.java))
|
||||
}
|
||||
|
||||
fun decode(buffer: FriendlyByteBuf): CatchRateModifier =
|
||||
gson.fromJson(buffer.readString(), CatchRateModifier::class.java)
|
||||
|
||||
private fun getVariant(modifier: CatchRateModifier): String {
|
||||
val variant =
|
||||
this.types.inverse()[modifier::class]
|
||||
?: throw IllegalArgumentException("Cannot resolve pokeball catchrate modifier for type ${modifier::class.qualifiedName}")
|
||||
|
||||
return variant
|
||||
}
|
||||
|
||||
private fun getModifierType(variant: String): KClass<out CatchRateModifier> {
|
||||
val requirementType =
|
||||
this.types[variant]
|
||||
?: throw IllegalArgumentException("Cannot resolve pokeball catchrate modifier type for variant $variant")
|
||||
|
||||
return requirementType
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2026. gitoido-mc
|
||||
* This Source Code Form is subject to the terms of the GNU General Public License v3.0.
|
||||
* If a copy of the GNU General Public License v3.0 was not distributed with this file,
|
||||
* you can obtain one at https://github.com/gitoido-mc/conditional-riding/blob/main/LICENSE.
|
||||
*/
|
||||
|
||||
package com.cobblemon.mod.common.util.adapters
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.TypeAdapter
|
||||
import com.google.gson.TypeAdapterFactory
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.google.gson.stream.JsonReader
|
||||
import com.google.gson.stream.JsonToken
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import java.io.IOException
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import java.util.*
|
||||
|
||||
class OptionalTypeAdapterFactory : TypeAdapterFactory {
|
||||
class OptionalTypeAdapter<T>(
|
||||
private val typeAdapter: TypeAdapter<T>,
|
||||
) : TypeAdapter<Optional<T>>() {
|
||||
@Throws(IOException::class)
|
||||
override fun write(
|
||||
out: JsonWriter,
|
||||
value: Optional<T>,
|
||||
) {
|
||||
when (value.isPresent) {
|
||||
true -> typeAdapter.write(out, value.get())
|
||||
false -> out.nullValue()
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun read(`in`: JsonReader): Optional<T> =
|
||||
when (`in`.peek() != JsonToken.NULL) {
|
||||
true -> {
|
||||
Optional.ofNullable(typeAdapter.read(`in`))
|
||||
}
|
||||
|
||||
false -> {
|
||||
`in`.nextNull()
|
||||
Optional.empty()
|
||||
}
|
||||
} as Optional<T>
|
||||
}
|
||||
|
||||
override fun <T> create(
|
||||
gson: Gson,
|
||||
typeToken: TypeToken<T>,
|
||||
): TypeAdapter<T>? {
|
||||
if (!Optional::class.java.isAssignableFrom(typeToken.rawType)) return null
|
||||
|
||||
val optionalType = typeToken.type
|
||||
val parametrizedType = optionalType as ParameterizedType
|
||||
val typeArgs = parametrizedType.actualTypeArguments
|
||||
val inner = TypeToken.get(typeArgs.first())
|
||||
val innerAdapter = gson.getAdapter(inner)
|
||||
|
||||
return OptionalTypeAdapter(innerAdapter) as TypeAdapter<T>?
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.api.pokeball.catching.CatchRateModifier
|
||||
import com.cobblemon.mod.common.api.spawning.detail.PossibleHeldItem
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonDeserializer
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.JsonOps
|
||||
import net.minecraft.client.renderer.item.ItemProperties
|
||||
import net.minecraft.core.component.DataComponentMap
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import java.awt.Color
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
/**
|
||||
* A JSON deserializer for [PokeBall].
|
||||
*
|
||||
* @author Gito
|
||||
* @since October 28th, 2026
|
||||
*/
|
||||
object PokeBallAdapter : JsonDeserializer<PokeBall> {
|
||||
override fun deserialize(json: JsonElement, tp: Type, ctx: JsonDeserializationContext): PokeBall {
|
||||
json as JsonObject
|
||||
|
||||
val beamColor: Color = when(json.has("beam_color")) {
|
||||
true -> Color.decode(json.get("beam_color").asString)
|
||||
false -> Color.RED
|
||||
}
|
||||
|
||||
val properties: PokeBall.PokeBallProperties = when(json.has("item_properties")) {
|
||||
true -> ctx.deserialize(json.get("item_properties"), PokeBall.PokeBallProperties::class.java)
|
||||
false -> PokeBall.PokeBallProperties()
|
||||
}
|
||||
|
||||
return PokeBall(
|
||||
catchRateModifier = ctx.deserialize(json.get("modifier"), CatchRateModifier::class.java),
|
||||
effects = listOf(),
|
||||
itemProperties = properties,
|
||||
waterDragValue = tryParse(json.get("water_drag"), Codec.FLOAT),
|
||||
model2d = tryParse(json.get("model_2d"), ResourceLocation.CODEC),
|
||||
model3d = tryParse(json.get("model_3d"), ResourceLocation.CODEC),
|
||||
throwPower = tryParse(json.get("throw_power"), Codec.FLOAT),
|
||||
ancient = if (json.has("ancient")) json.get("ancient").asBoolean else false,
|
||||
beamColor = beamColor,
|
||||
)
|
||||
}
|
||||
|
||||
private fun <T> tryParse(json: JsonElement, codec: Codec<T>): T {
|
||||
return runCatching { JsonOps.INSTANCE.withDecoder(codec).apply(json).result().getOrNull()!!.first }.getOrThrow()
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,5 @@ object CobblemonGameRules {
|
||||
@JvmField
|
||||
val HEALERS_HEAL_PC: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("healersHealPC", GameRules.Category.MISC, BooleanRuleInvoker.`cobblemon$create`(false))
|
||||
@JvmField
|
||||
val HEALER_SET_SPAWN: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("healersSetSpawn", GameRules.Category.MISC, BooleanRuleInvoker.`cobblemon$create`(false))
|
||||
@JvmField
|
||||
val DO_POKEMON_PREDATION: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("doPokemonPredation", GameRules.Category.MOBS, BooleanRuleInvoker.`cobblemon$create`(true))
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"portraitScale": 1,
|
||||
"portraitTranslation": [0, 0, 0],
|
||||
"profileScale": 1,
|
||||
"profileTranslation": [0, 0, 0],
|
||||
"rootBone": "ancient_ball",
|
||||
"poses": {
|
||||
"flying": {
|
||||
"poseTypes": ["NONE"],
|
||||
"condition": "q.capture_state() == 'NOT'",
|
||||
"animations": ["q.bedrock('ancient_ball', 'throw')"],
|
||||
"transitions": {
|
||||
"open": "q.bedrock_stateful('ancient_ball', 'open')"
|
||||
}
|
||||
},
|
||||
"open": {
|
||||
"poseTypes": ["NONE", "PORTRAIT"],
|
||||
"animations": ["q.bedrock('ancient_ball', 'open_idle')"],
|
||||
"transitions": {
|
||||
"shut": "q.bedrock_stateful('ancient_ball', 'shut')"
|
||||
}
|
||||
},
|
||||
"shut": {
|
||||
"poseTypes": ["NONE", "PORTRAIT"],
|
||||
"animations": [
|
||||
"q.bedrock('ancient_ball', 'shut_idle')"
|
||||
],
|
||||
"transitions": {
|
||||
"open": "q.bedrock_stateful('ancient_ball', 'open')"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"portraitScale": 1,
|
||||
"portraitTranslation": [0, 0, 0],
|
||||
"profileScale": 1,
|
||||
"profileTranslation": [0, 0, 0],
|
||||
"rootBone": "poke_ball",
|
||||
"poses": {
|
||||
"flying": {
|
||||
"poseTypes": ["NONE"],
|
||||
"condition": "q.capture_state() == 'NOT'",
|
||||
"animations": ["q.bedrock('poke_ball', 'throw')"],
|
||||
"transitions": {
|
||||
"open": "q.bedrock_stateful('poke_ball', 'open')"
|
||||
}
|
||||
},
|
||||
"open": {
|
||||
"poseTypes": ["NONE", "PORTRAIT"],
|
||||
"animations": ["q.bedrock('poke_ball', 'open_idle')"],
|
||||
"transitions": {
|
||||
"shut": "q.bedrock_stateful('poke_ball', 'shut')"
|
||||
}
|
||||
},
|
||||
"shut": {
|
||||
"poseTypes": ["NONE", "PORTRAIT"],
|
||||
"animations": [
|
||||
"q.bedrock('poke_ball', 'shut_idle')"
|
||||
],
|
||||
"transitions": {
|
||||
"open": "q.bedrock_stateful('poke_ball', 'open')"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-12
@@ -1815,12 +1815,6 @@
|
||||
"wings_open": {
|
||||
"scale": 0
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
|
||||
"0.5": "q.run_molang('cobblemon:stepsound_claw_medium');",
|
||||
"1.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
|
||||
"1.5": "q.run_molang('cobblemon:stepsound_claw_medium');"
|
||||
}
|
||||
},
|
||||
"animation.pidgeot.mount_ground_idle": {
|
||||
@@ -3637,12 +3631,6 @@
|
||||
"wings_open": {
|
||||
"scale": 0
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
|
||||
"0.5": "q.run_molang('cobblemon:stepsound_claw_medium');",
|
||||
"1.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
|
||||
"1.5": "q.run_molang('cobblemon:stepsound_claw_medium');"
|
||||
}
|
||||
},
|
||||
"animation.pidgeot.ride_ground_walk": {
|
||||
|
||||
+74
-308
@@ -1682,12 +1682,6 @@
|
||||
"1.3333": [10, 9, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.0": "q.run_molang('cobblemon:stepsound_standard_medium');",
|
||||
"0.4583": "q.run_molang('cobblemon:stepsound_standard_medium');",
|
||||
"0.6667": "q.run_molang('cobblemon:stepsound_standard_medium');",
|
||||
"1.125": "q.run_molang('cobblemon:stepsound_standard_medium');"
|
||||
}
|
||||
},
|
||||
"animation.arcanine.ride_ground_walk": {
|
||||
@@ -2645,12 +2639,6 @@
|
||||
"chest_fluff_right": {
|
||||
"rotation": [5, "-22.5+math.cos(q.anim_time*90*8-120)*15", "-math.sin(q.anim_time*90*8-120)*3"]
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.125": "q.run_molang('cobblemon:stepsound_standard_medium');",
|
||||
"0.2083": "q.run_molang('cobblemon:stepsound_standard_large');",
|
||||
"0.2917": "q.run_molang('cobblemon:stepsound_standard_medium');",
|
||||
"0.375": "q.run_molang('cobblemon:stepsound_standard_medium');"
|
||||
}
|
||||
},
|
||||
"animation.arcanine.ride_ground_run": {
|
||||
@@ -4173,101 +4161,41 @@
|
||||
"eye_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, 0.1]
|
||||
},
|
||||
"0.5": {
|
||||
"pre": [-0.1, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4167": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, 0.1]
|
||||
},
|
||||
"1.6667": {
|
||||
"pre": [-0.1, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.5": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
|
||||
"0.5": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
|
||||
"1.6667": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
|
||||
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eye_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, 0.1]
|
||||
},
|
||||
"0.5": {
|
||||
"pre": [0.1, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4167": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, 0.1]
|
||||
},
|
||||
"1.6667": {
|
||||
"pre": [0.1, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.5": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
|
||||
"0.5": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
|
||||
"1.6667": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
|
||||
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, -0.1]
|
||||
},
|
||||
"0.5": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4167": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, -0.1]
|
||||
},
|
||||
"1.6667": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.5": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
|
||||
"0.5": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
|
||||
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
|
||||
"1.6667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
|
||||
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, -0.1]
|
||||
},
|
||||
"0.5": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4167": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, -0.1]
|
||||
},
|
||||
"1.6667": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.5": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
|
||||
"0.5": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
|
||||
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
|
||||
"1.6667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
|
||||
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"jaw": {
|
||||
@@ -4895,101 +4823,41 @@
|
||||
"eye_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, 0.1]
|
||||
},
|
||||
"0.5": {
|
||||
"pre": [-0.1, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4167": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, 0.1]
|
||||
},
|
||||
"1.6667": {
|
||||
"pre": [-0.1, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.5": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
|
||||
"0.5": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
|
||||
"1.6667": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
|
||||
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eye_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, 0.1]
|
||||
},
|
||||
"0.5": {
|
||||
"pre": [0.1, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4167": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, 0.1]
|
||||
},
|
||||
"1.6667": {
|
||||
"pre": [0.1, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.5": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
|
||||
"0.5": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
|
||||
"1.6667": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
|
||||
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, -0.1]
|
||||
},
|
||||
"0.5": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4167": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, -0.1]
|
||||
},
|
||||
"1.6667": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.5": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
|
||||
"0.5": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
|
||||
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
|
||||
"1.6667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
|
||||
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.1667": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, -0.1]
|
||||
},
|
||||
"0.5": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.4167": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, -0.1]
|
||||
},
|
||||
"1.6667": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"2.5": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
|
||||
"0.5": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
|
||||
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
|
||||
"1.6667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
|
||||
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"jaw": {
|
||||
@@ -5419,20 +5287,14 @@
|
||||
"position": {
|
||||
"0.0": [-0.1, 0, 0.1],
|
||||
"0.125": [-0.1, 0, 0.1],
|
||||
"0.1667": {
|
||||
"pre": [-0.1, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.1667": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eye_right": {
|
||||
"position": {
|
||||
"0.0": [0.1, 0, 0.1],
|
||||
"0.125": [0.1, 0, 0.1],
|
||||
"0.1667": {
|
||||
"pre": [0.1, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.1667": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5629,95 +5491,47 @@
|
||||
"eye_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.2, 0, 0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [-0.2, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
|
||||
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eye_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.2, 0, 0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [0.2, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
|
||||
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.2, 0, 0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [-0.2, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
|
||||
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.2, 0, 0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [0.2, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
|
||||
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_left_hurt": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, -0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
|
||||
"0.3333": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_right_hurt": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, -0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
|
||||
"0.3333": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"jaw": {
|
||||
@@ -6424,95 +6238,47 @@
|
||||
"eye_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.2, 0, 0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [-0.2, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
|
||||
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eye_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.2, 0, 0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [0.2, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
|
||||
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.2, 0, 0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [-0.2, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
|
||||
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.2, 0, 0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [0.2, 0, 0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"1.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
|
||||
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
|
||||
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_left_hurt": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, -0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
|
||||
"0.3333": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_right_hurt": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.0417": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, -0.1]
|
||||
},
|
||||
"0.3333": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.0417": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
|
||||
"0.3333": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"jaw": {
|
||||
|
||||
-8
@@ -3150,10 +3150,6 @@
|
||||
"locator_seat_2": {
|
||||
"rotation": [45, 0, 0]
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.5": "q.run_molang('cobblemon:stepsound_claw_large');",
|
||||
"1.5": "q.run_molang('cobblemon:stepsound_claw_large');"
|
||||
}
|
||||
},
|
||||
"animation.corviknight.ground_run": {
|
||||
@@ -4477,10 +4473,6 @@
|
||||
"locator_seat_2": {
|
||||
"rotation": [25, 0, 0]
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.3333": "q.run_molang('cobblemon:stepsound_claw_large');",
|
||||
"0.8333": "q.run_molang('cobblemon:stepsound_claw_large');"
|
||||
}
|
||||
},
|
||||
"animation.corviknight.air_idle": {
|
||||
|
||||
+10
-56
@@ -566,12 +566,6 @@
|
||||
"1.5": [0, 0.2, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.5417": "q.run_molang('cobblemon:stepsound_hoof_medium');",
|
||||
"0.7083": "q.run_molang('cobblemon:stepsound_hoof_medium');",
|
||||
"1.2917": "q.run_molang('cobblemon:stepsound_hoof_medium');",
|
||||
"1.4583": "q.run_molang('cobblemon:stepsound_hoof_medium');"
|
||||
}
|
||||
},
|
||||
"animation.wyrdeer.sleep": {
|
||||
@@ -786,27 +780,15 @@
|
||||
"eyelid_right": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, -0.1]
|
||||
},
|
||||
"0.5": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.25": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
|
||||
"0.5": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.25": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, -0.1]
|
||||
},
|
||||
"0.5": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"0.25": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
|
||||
"0.5": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"ear_right": {
|
||||
@@ -1204,36 +1186,18 @@
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"1.5833": [-0.1, 0, -0.1],
|
||||
"1.6667": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"3.0": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [-0.1, 0, -0.1]
|
||||
},
|
||||
"3.125": {
|
||||
"pre": [-0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"1.6667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
|
||||
"3.0": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
|
||||
"3.125": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"eyelid_left": {
|
||||
"position": {
|
||||
"0.0": [0, 0, 0],
|
||||
"1.5833": [0.1, 0, -0.1],
|
||||
"1.6667": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
},
|
||||
"3.0": {
|
||||
"pre": [0, 0, 0],
|
||||
"post": [0.1, 0, -0.1]
|
||||
},
|
||||
"3.125": {
|
||||
"pre": [0.1, 0, -0.1],
|
||||
"post": [0, 0, 0]
|
||||
}
|
||||
"1.6667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
|
||||
"3.0": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
|
||||
"3.125": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
|
||||
}
|
||||
},
|
||||
"tail": {
|
||||
@@ -2240,16 +2204,6 @@
|
||||
"1.1667": [0, 0, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeline": {
|
||||
"0.2083": "q.run_molang('cobblemon:stepsound_hoof_medium');",
|
||||
"0.2917": "q.run_molang('cobblemon:stepsound_hoof_medium');",
|
||||
"0.375": "q.run_molang('cobblemon:stepsound_hoof_medium');",
|
||||
"0.4583": "q.run_molang('cobblemon:stepsound_hoof_large');",
|
||||
"0.7917": "q.run_molang('cobblemon:stepsound_hoof_medium');",
|
||||
"0.875": "q.run_molang('cobblemon:stepsound_hoof_medium');",
|
||||
"0.9583": "q.run_molang('cobblemon:stepsound_hoof_medium');",
|
||||
"1.0417": "q.run_molang('cobblemon:stepsound_hoof_large');"
|
||||
}
|
||||
},
|
||||
"animation.wyrdeer.ride_jump": {
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"item.cobblemon.park_ball": "Park Ball",
|
||||
"item.cobblemon.dream_ball": "Dream Ball",
|
||||
"item.cobblemon.beast_ball": "Beast Ball",
|
||||
"item.cobblemon.strange_ball": "Strange Ball",
|
||||
"item.cobblemon.ancient_poke_ball": "Ancient Poké Ball",
|
||||
"item.cobblemon.ancient_citrine_ball": "Ancient Citrine Ball",
|
||||
"item.cobblemon.ancient_verdant_ball": "Ancient Verdant Ball",
|
||||
@@ -1299,7 +1300,6 @@
|
||||
"cobblemon.ui.pc.filter.tooltip": "Format: pikachu shiny held_item lvl=1...",
|
||||
"cobblemon.ui.pc.options": "Options",
|
||||
"cobblemon.ui.pc.release": "Release",
|
||||
"cobblemon.ui.pc.release_all": "Release All",
|
||||
"cobblemon.ui.sort.name": "Sort by name",
|
||||
"cobblemon.ui.sort.level": "Sort by level",
|
||||
"cobblemon.ui.sort.pokedex_number": "Sort by Pokédex number",
|
||||
|
||||
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_azure_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_citrine_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_feather_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_gigaton_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_great_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_heavy_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_ivory_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_jet_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_leaden_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_origin_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_roseate_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"parent": "cobblemon:item/ancient_poke_ball_model",
|
||||
"parent": "cobblemon:item/poke_ball/ancient_poke_ball_model",
|
||||
"textures": {
|
||||
"layer0": "cobblemon:item/poke_balls/models/ancient_slate_ball"
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 683 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user