Compare commits

..
Author SHA1 Message Date
Guilherme Pereira 96079065b6 more armors 2025-12-05 11:38:38 -03:00
Guilherme Pereira 86f91ed77a add malicious armor armor material 2025-12-03 20:41:32 -03:00
453 changed files with 1242 additions and 3302 deletions
+1 -57
View File
@@ -2,77 +2,21 @@
## [1.7.2 (MONTH Xth, YEAR)](#1-7-2)
### Additions
- Added riding statistics: `Distance by Pokémon on Land`, `Distance by Pokémon in Air` and `Distance by Pokémon in Liquid`.
- Added the Partner Mark, which party Pokémon have a very small chance to earn as the player walks, provided they have enough friendship.
- Added trades for Saccharine Saplings, Hearty Grains, Chipped Pot, and Masterpiece Teacup to the Wandering Trader.
- Added brewing recipe for Throat Spray.
- Added new effects
- Mental Restoration: Reduces "Time Since Last Rest" statistic, which controls Insomnia, by half a minute per second per effect level
- Negative Effect Cleanse: Removes all negative effects
- Effect Cleanse: Removes all effects
- Added more seasonings for sinister tea
- Mental Herb - Mental Restoration I for 10 seconds
- White Herb - Negative Effect Cleanse
- Milk - Effect Cleanse
- Moomoo Milk - Effect Cleanse
- Added `label` as an alternate key to the `tag` property.
- Added Saccharine wood furniture for Adorn.
### Changes
- Ride sounds have been separated into stereo for passengers and mono for other players. Riding will now sound more spacious.
- Added a new config option, `Enable In-Flight Dismounting` (default: off), which lets you dismount while riding a Pokémon in the air.
- Battle AI now uses a smarter threshold for switching, reducing unnecessary switches.
- AI will always use the most damaging move when at low HP and when it is not switching, improving endgame decision-making.
- Added support for optional message variants in battle activate instructions for more context-specific battle text.
- Example: `this.add('-activate', pokemon, 'ability: example', '[msg]message1');` will parse to lang key `cobblemon.battle.activate.example.message1`
### Fixes
- Fixed an issue in the OmniPathNodeMaker/Navigation that prevented Combees from pathing into and out of Saccharine leaves.
- Fixed orientation not getting reset after crashing while flying and getting back on the Pokémon.
- Fixed Furfrou not being trimmable on NeoForge.
- Fixed shiny Pokémon not respecting the silent flag on spawn.
- Fixed honey from Saccharine Leaves being harvestable at less than the max age.
- Items given from interacting with Saccharine Leaves are placed in the active hotbar slot if possible.
- Fix all Pokémon being saved to chunks and never despawning.
- Fixed possible error on world generation when Combees are placed in naturally generated bee nests.
- Fixed PokeSnacks crashing if there was no available spawn.
- Fixed Pokémon spawn influences not being specific to regional forms
- Fixed crashing when viewing another player in spectator mode
- Fixed missing apricorn textures for Adorn blocks
- Fixed crashing when riding due to malformed json file, instead resetting it
- Fixed mochi items consuming two items at a time
- Fix item interaction sometimes not working properly when playing on servers.
- Fixed Soothe Bell not being properly tagged as a held item.
- Fixed Mint Leaves not being usable for filling the Resurrection Machine.
- Added Saccharine Boats and Saccharine Boat with Chests to relevant boat tags.
- Fixed the `run_script` Molang function to not fail if the environment's context is null.
- Fixed issue #1917
- Fixed the movesets of certain Pokémon being incorrectly sanitized upon reload.
- Fixed the ordering of Aprijuice's riding stat boosts to always have the same order.
- Fixed the Molang functions `date_local_time`, `date_of`, `date_is_after` to use the correct date format.
- Fixed the bottom half of pasture blocks having an incorrect hit-box when facing north or south.
- Fixed Galarian Mr. Mime incorrectly being rideable.
- Fixed gimmicks not being usable in double / triple battles
- Fixed gimmick buttons showing when already used in the same turn in double / triple battles
- Fixed Apricorn block model rotation for counters/sinks/cupboards/drawers to match that of most recent version of Adorn.
- Fixed Fresh Start Mochi EV reset not syncing health changes properly.
- Fixed requirements such as `biomeCondition` crashing the game when used to define Pokémon interactions.
- Fixed Pokémon interactions not playing sound effects when the volume was not specified.
- Fixed Pokémon interaction cooldowns taking longer than intended when the Pokémon was in the player’s party.
- Fixed Pokémon interactions occasionally crashing the game when spamming an interaction with a 0 cooldown.
- Fixed Pokémon fullness decreasing more than intended when the Pokémon was pastured.
- Fixed crashing when sending a Pokémon out after editing its form
- Fixed Super Potion recipes incorrectly using Hondew Berry instead of Aguav Berry.
### Developer
- Changed the `owner` parameter in the `OwnerQueryRequirement` interface from `ServerPlayer` to `Player`. This method is now also called on the client to verify whether a Pokémon interaction succeeded, so make sure to update your implementations to handle both server and client contexts.
### Molang & Datapacks
- Ride sounds can now be set as exclusive to passengers
- Ride sounds no longer play when submerged unless specified with a new setting
- Exception handling has been added to `run_molang`, resolving some crashes caused by malformed MoLang expressions.
### Particles
### Localization
- Updated translations for:
- Updated translations for:
@@ -11,9 +11,7 @@ package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.CobblemonMemories;
import com.cobblemon.mod.common.api.ai.config.task.PathToBeeHiveTaskConfig;
import com.cobblemon.mod.common.api.pokemon.PokemonProperties;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.world.feature.SaccharineTreeFeature;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.tags.BlockTags;
@@ -44,21 +42,7 @@ public abstract class BeeOccupantMixin {
if (cir.getReturnValue() == null) {
final BeehiveBlockEntity.Occupant occupant = (BeehiveBlockEntity.Occupant) (Object) this;
CompoundTag compoundTag = occupant.entityData().copyTag();
String id = compoundTag.getString("id");
Entity entity = null;
if (id.equals(SaccharineTreeFeature.Companion.getPOKEMON_PLACEHOLD_ID())) {
// Special case for Pokemon stuffed into a beenest upon world gen.
// For technical reasons we cannot create them as full entities during world gen.
// So we look for this special id tag and complete the entity when it attempts to exit a hive.
if (compoundTag.contains("pokemonProperties")) {
String properties = compoundTag.getString("pokemonProperties");
PokemonProperties pokemon = PokemonProperties.Companion.parse(properties);
entity = pokemon.createEntity(level);
}
} else {
entity = EntityType.loadEntityRecursive(compoundTag, level, (entityx) -> entityx);
}
Entity entity = EntityType.loadEntityRecursive(compoundTag, level, (entityx) -> entityx);
if (entity instanceof PokemonEntity pokemonEntity) {
var state = level.getBlockState(pos);
var newPos = Vec3.ZERO;
@@ -11,15 +11,11 @@ package com.cobblemon.mod.common.mixin;
import com.cobblemon.mod.common.Cobblemon;
import com.cobblemon.mod.common.OrientationControllable;
import com.cobblemon.mod.common.PlayerSpawnerAccessor;
import com.cobblemon.mod.common.api.riding.RidingStyle;
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawner;
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawnerFactory;
import com.cobblemon.mod.common.api.stats.CobblemonStats;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
@@ -93,32 +89,4 @@ public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
private boolean cobblemon$cancelSavingPokemonMounts(boolean original, @Local(ordinal=0) Entity entity) {
return original && !(entity instanceof PokemonEntity);
}
@WrapOperation(method = "checkRidingStatistics", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;getVehicle()Lnet/minecraft/world/entity/Entity;"))
public Entity cobblemon$checkRidingStatistics(ServerPlayer player, Operation<Entity> original, @Local int distance) {
var entity = original.call(player);
if (!(entity instanceof PokemonEntity pokemonEntity)) {
return entity;
}
var ridingController = pokemonEntity.getRidingController();
if (ridingController == null) return entity;
var activeContext = ridingController.getContext();
if (activeContext == null) return entity;
var ridingStyle = activeContext.getStyle();
CobblemonStats.CobblemonStat stat = switch (ridingStyle) {
case RidingStyle.LAND -> CobblemonStats.RIDING_LAND;
case RidingStyle.AIR -> CobblemonStats.RIDING_AIR;
case RidingStyle.LIQUID -> CobblemonStats.RIDING_LIQUID;
default -> null;
};
if (stat != null) {
player.awardStat(CobblemonStats.getStat(stat), distance);
}
return entity;
}
}
@@ -33,7 +33,7 @@ public class SimpleBlockFeatureMixin {
if (!(blockState.getBlock() instanceof HeartyGrainsBlock)) {
return;
}
if (blockState.getValue(HeartyGrainsBlock.AGE) <= HeartyGrainsBlock.AGE_AFTER_HARVEST) {
if (blockState.getValue(HeartyGrainsBlock.Companion.getAGE()) <= HeartyGrainsBlock.AGE_AFTER_HARVEST) {
return; //block is too young to be double
}
if (!worldGenLevel.isEmptyBlock(blockPos.above())) {
@@ -43,4 +43,4 @@ public class SimpleBlockFeatureMixin {
DoublePlantBlock.placeAt(worldGenLevel, blockState, blockPos, Block.UPDATE_CLIENTS);
cir.setReturnValue(true);
}
}
}
@@ -33,7 +33,7 @@ public class AbstractClientPlayerMixin {
cir.setReturnValue(usageContext.getFovMultiplier());
} else {
// Only modify fov through riding if the pokedex is not open
AbstractClientPlayer player = (AbstractClientPlayer) (Object) this;
LocalPlayer player = (LocalPlayer) (Object) this;
// Only modify fov for the driver and not the passengers
if (player != null && player.isPassenger() && player.getVehicle() instanceof PokemonEntity && player.getVehicle().getControllingPassenger() == player) {
PokemonEntity ride = (PokemonEntity) player.getVehicle();
@@ -42,8 +42,8 @@ import com.cobblemon.mod.common.api.scheduling.ServerRealTimeTaskTracker
import com.cobblemon.mod.common.api.scheduling.ServerTaskTracker
import com.cobblemon.mod.common.api.spawning.BestSpawner
import com.cobblemon.mod.common.api.spawning.CobblemonSpawningZoneGenerator
import com.cobblemon.mod.common.api.spawning.SpawningZoneGenerator
import com.cobblemon.mod.common.api.spawning.position.AreaSpawnablePositionResolver
import com.cobblemon.mod.common.api.spawning.SpawningZoneGenerator
import com.cobblemon.mod.common.api.starter.StarterHandler
import com.cobblemon.mod.common.api.stats.CobblemonStats
import com.cobblemon.mod.common.api.storage.PokemonStoreManager
@@ -76,7 +76,12 @@ import com.cobblemon.mod.common.config.LastChangedVersion
import com.cobblemon.mod.common.config.constraint.IntConstraint
import com.cobblemon.mod.common.config.starter.StarterConfig
import com.cobblemon.mod.common.data.CobblemonDataProvider
import com.cobblemon.mod.common.events.*
import com.cobblemon.mod.common.events.AdvancementHandler
import com.cobblemon.mod.common.events.EntityCallbackHandler
import com.cobblemon.mod.common.events.CallbackHandler
import com.cobblemon.mod.common.events.PokedexHandler
import com.cobblemon.mod.common.events.ServerTickHandler
import com.cobblemon.mod.common.events.StatHandler
import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacket
import com.cobblemon.mod.common.permission.LaxPermissionValidator
import com.cobblemon.mod.common.platform.events.PlatformEvents
@@ -91,7 +96,7 @@ import com.cobblemon.mod.common.pokemon.feature.SlowpokeTailRegrowthSpeciesFeatu
import com.cobblemon.mod.common.pokemon.feature.TagSeasonResolver
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
import com.cobblemon.mod.common.pokemon.properties.*
import com.cobblemon.mod.common.pokemon.properties.LabelProperty
import com.cobblemon.mod.common.pokemon.properties.tags.PokemonFlagProperty
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
import com.cobblemon.mod.common.util.*
@@ -164,7 +169,7 @@ object Cobblemon {
val statistics: CobblemonStats = CobblemonStats
@JvmField
@JvmStatic
val builtinPacks = listOf<CobblemonPack>(
CobblemonPack(id = "adorncompatibility", name = "Adorn Compatibility", packType = PackType.CLIENT_RESOURCES, activationBehaviour = ResourcePackActivationBehaviour.ALWAYS_ENABLED, neededMods = setOf("adorn")),
CobblemonPack(id = "gyaradosjump", name = "Gyarados Jump Patterns", packType = PackType.CLIENT_RESOURCES, activationBehaviour = ResourcePackActivationBehaviour.DEFAULT_ENABLED),
@@ -189,6 +194,7 @@ object Cobblemon {
implementation.registerSoundEvents()
implementation.registerDataComponents()
implementation.registerBlocks()
implementation.registerArmorMaterials()
implementation.registerItems()
implementation.registerEntityTypes()
implementation.registerEntityAttributes()
@@ -201,7 +207,6 @@ object Cobblemon {
implementation.registerEntityDataSerializers()
implementation.registerCriteria()
implementation.registerEntitySubPredicates()
implementation.registerMobEffects()
DispenserBehaviorRegistry.registerDispenserBehaviors()
DropEntry.register("command", CommandDropEntry::class.java)
@@ -315,7 +320,7 @@ object Cobblemon {
CustomPokemonProperty.register(UncatchableProperty)
CustomPokemonProperty.register(BattleCloneProperty)
CustomPokemonProperty.register(LabelProperty)
CustomPokemonProperty.register(PokemonFlagProperty)
CustomPokemonProperty.register(HiddenAbilityPropertyType)
CustomPokemonProperty.register(AspectPropertyType)
CustomPokemonProperty.register(UnaspectPropertyType)
@@ -569,4 +574,4 @@ object Cobblemon {
this.implementation.registerCommandArgument(cobblemonResource("model_part"), ModelPartArgumentType::class, SingletonArgumentInfo.contextFree(ModelPartArgumentType::modelPart))
}
}
}
@@ -0,0 +1,53 @@
package com.cobblemon.mod.common
import com.cobblemon.mod.common.platform.PlatformRegistry
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.sounds.SoundEvents
import net.minecraft.world.item.ArmorItem
import net.minecraft.world.item.ArmorMaterial
import net.minecraft.world.item.Items
import net.minecraft.world.item.crafting.Ingredient
@Suppress("unused")
object CobblemonArmorMaterials :
PlatformRegistry<Registry<ArmorMaterial>, ResourceKey<Registry<ArmorMaterial>>, ArmorMaterial>() {
override val registry: Registry<ArmorMaterial> = BuiltInRegistries.ARMOR_MATERIAL
override val resourceKey: ResourceKey<Registry<ArmorMaterial>> = Registries.ARMOR_MATERIAL
@JvmField
val MALICIOUS_ARMOR = cosmeticMaterial("malicious_armor")
@JvmField
val HEAVY_DUTY_BOOTS = cosmeticMaterial("heavy_duty_boots")
@JvmField
val PROTECTIVE_PADS = cosmeticMaterial("protective_pads")
@JvmField
val ASSAULT_VEST = cosmeticMaterial("assault_vest")
@JvmField
val MYSTIC_WATER = cosmeticMaterial("mystic_water")
@JvmField
val BLACK_BELT = cosmeticMaterial("black_belt")
private fun cosmeticMaterial(name: String): ArmorMaterial {
val armorMaterial = ArmorMaterial(
mapOf(
ArmorItem.Type.HELMET to 0,
ArmorItem.Type.CHESTPLATE to 0,
ArmorItem.Type.LEGGINGS to 0,
ArmorItem.Type.BOOTS to 0,
),
0,
SoundEvents.ARMOR_EQUIP_GENERIC,
{ Ingredient.EMPTY },
listOf(ArmorMaterial.Layer(cobblemonResource(name), "", true)),
0.0f,
0.0f,
)
return create(name, armorMaterial)
}
}
@@ -64,6 +64,8 @@ interface CobblemonImplementation {
fun registerEntityDataSerializers()
fun registerArmorMaterials()
/**
* TODO
*
@@ -117,11 +119,6 @@ interface CobblemonImplementation {
fun registerEntitySubPredicates()
/**
* TODO
*/
fun registerMobEffects()
/**
* Add a feature to the current platform implementation.
@@ -44,16 +44,21 @@ import com.cobblemon.mod.common.pokeball.PokeBall
import com.cobblemon.mod.common.pokemon.IVs
import com.cobblemon.mod.common.pokemon.helditem.CobblemonHeldItemManager
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.core.Holder
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.sounds.SoundEvents
import net.minecraft.world.effect.MobEffectInstance
import net.minecraft.world.effect.MobEffects
import net.minecraft.world.entity.EquipmentSlot
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.food.FoodProperties
import net.minecraft.world.item.ArmorItem
import net.minecraft.world.item.ArmorMaterial
import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.HangingSignItem
import net.minecraft.world.item.Item
@@ -501,8 +506,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField val RAZOR_CLAW = noSettingsItem("razor_claw")
@JvmField val RAZOR_FANG = noSettingsItem("razor_fang")
@JvmField val AUSPICIOUS_ARMOR = heldItem("auspicious_armor")
@JvmField val MALICIOUS_ARMOR = heldItem("malicious_armor")
@JvmField val SHELL_HELMET = heldItem("shell_helmet")
@JvmField val METAL_ALLOY = noSettingsItem("metal_alloy")
@JvmField val SCROLL_OF_DARKNESS = noSettingsItem("scroll_of_darkness")
@JvmField val SCROLL_OF_WATERS = noSettingsItem("scroll_of_waters")
@@ -892,7 +895,8 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
val WATER_STONE = noSettingsItem("water_stone")
val wearables = mutableListOf<WearableItem>()
//Wearable items (these items should have a corresponding 3D model)
// Wearable items (these items should have a corresponding 3D model)
@JvmField val BLACK_GLASSES = wearableItem("black_glasses")
@JvmField val CHOICE_BAND = wearableItem("choice_band")
@JvmField val CHOICE_SPECS = wearableItem("choice_specs")
@@ -903,6 +907,20 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField val ROCKY_HELMET = wearableItem("rocky_helmet")
@JvmField val SAFETY_GOGGLES = wearableItem("safety_goggles")
@JvmField val WISE_GLASSES = wearableItem("wise_glasses")
@JvmField val SHELL_HELMET = wearableItem("shell_helmet")
@JvmField
val MALICIOUS_ARMOR = armorItem("malicious_armor", CobblemonArmorMaterials.MALICIOUS_ARMOR, ArmorItem.Type.CHESTPLATE)
@JvmField
val HEAVY_DUTY_BOOTS = armorItem("heavy_duty_boots", CobblemonArmorMaterials.HEAVY_DUTY_BOOTS, ArmorItem.Type.BOOTS)
@JvmField
val PROTECTIVE_PADS = armorItem("protective_pads", CobblemonArmorMaterials.PROTECTIVE_PADS, ArmorItem.Type.CHESTPLATE)
@JvmField
val ASSAULT_VEST = armorItem("assault_vest", CobblemonArmorMaterials.ASSAULT_VEST, ArmorItem.Type.CHESTPLATE)
@JvmField
val MYSTIC_WATER = armorItem("mystic_water", CobblemonArmorMaterials.MYSTIC_WATER, ArmorItem.Type.CHESTPLATE)
@JvmField
val BLACK_BELT = armorItem("black_belt", CobblemonArmorMaterials.BLACK_BELT, ArmorItem.Type.CHESTPLATE)
// Held Items
@JvmField
@@ -912,14 +930,10 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val AIR_BALLOON = heldItem("air_balloon")
@JvmField
val ASSAULT_VEST = heldItem("assault_vest")
@JvmField
val BIG_ROOT = compostableBlockItem("big_root", CobblemonBlocks.BIG_ROOT, 0.30f)
@JvmField
val BINDING_BAND = heldItem("binding_band")
@JvmField
val BLACK_BELT = heldItem("black_belt")
@JvmField
val BLACK_SLUDGE = heldItem("black_sludge")
@JvmField
val BLUNDER_POLICY = heldItem("blunder_policy")
@@ -966,8 +980,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val HARD_STONE = heldItem("hard_stone")
@JvmField
val HEAVY_DUTY_BOOTS = heldItem("heavy_duty_boots")
@JvmField
val IRON_BALL = heldItem("iron_ball")
@JvmField
val LAGGING_TAIL = heldItem("lagging_tail")
@@ -992,8 +1004,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val MIRACLE_SEED = heldItem("miracle_seed")
@JvmField
val MYSTIC_WATER = heldItem("mystic_water")
@JvmField
val NEVER_MELT_ICE = heldItem("never_melt_ice")
@JvmField
val POISON_BARB = heldItem("poison_barb")
@@ -1012,8 +1022,6 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
@JvmField
val PSYCHIC_SEED = heldItem("psychic_seed")
@JvmField
val PROTECTIVE_PADS = heldItem("protective_pads")
@JvmField
val PUNCHING_GLOVE = heldItem("punching_glove")
@JvmField
val QUICK_CLAW = heldItem("quick_claw")
@@ -1491,9 +1499,13 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
return item
}
private fun wearableItem(name: String, heldItemRemappedName: String? = null): CobblemonItem = create(
private fun wearableItem(
name: String,
heldItemRemappedName: String? = null,
equipmentSlot: EquipmentSlot = EquipmentSlot.HEAD,
): CobblemonItem = create(
name,
WearableItem(name).also {
WearableItem(name, equipmentSlot).also {
wearables.add(it)
if (heldItemRemappedName != null) {
CobblemonHeldItemManager.registerRemap(it, heldItemRemappedName)
@@ -1501,6 +1513,21 @@ object CobblemonItems : PlatformRegistry<Registry<Item>, ResourceKey<Registry<It
}
)
private fun armorItem(
name: String,
armorMaterial: ArmorMaterial,
armorType: ArmorItem.Type,
durability: Int? = null,
): ArmorItem {
var properties = Properties()
if (durability != null) properties = properties.durability(durability)
val armorMaterialHolder = BuiltInRegistries.ARMOR_MATERIAL.wrapAsHolder(armorMaterial)
val armorItem = ArmorItem(armorMaterialHolder, armorType, properties)
return create(name, armorItem)
}
private fun campfirePotItem(block: Block, color: CampfirePotColor): CampfirePotItem {
val item = create("campfire_pot_${color.suffix}", CampfirePotItem(block, color))
campfire_pots.add(item)
@@ -1,33 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common
import com.cobblemon.mod.common.api.cooking.effects.CleanseAllEffect
import com.cobblemon.mod.common.api.cooking.effects.CleanseNegativeEffect
import com.cobblemon.mod.common.api.cooking.effects.MentalRestorationEffect
import com.cobblemon.mod.common.platform.PlatformRegistry
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.world.effect.MobEffect
object CobblemonMobEffects : PlatformRegistry<Registry<MobEffect>, ResourceKey<Registry<MobEffect>>, MobEffect>() {
override val registry: Registry<MobEffect> = BuiltInRegistries.MOB_EFFECT
override val resourceKey: ResourceKey<Registry<MobEffect>> = Registries.MOB_EFFECT
@JvmField
val CLEANSE_NEGATIVE = create("cleanse_negative", CleanseNegativeEffect())
@JvmField
val MENTAL_RESTORATION = create("mental_restoration", MentalRestorationEffect())
@JvmField
val CLEANSE_ALL = create("cleanse_all", CleanseAllEffect())
}
@@ -21,12 +21,15 @@ import com.cobblemon.mod.common.client.net.callback.partymove.OpenPartyMoveCallb
import com.cobblemon.mod.common.client.net.cooking.ToggleCookingPotLidHandler
import com.cobblemon.mod.common.client.net.data.CobblemonMechanicsSyncHandler
import com.cobblemon.mod.common.client.net.data.DataRegistrySyncPacketHandler
import com.cobblemon.mod.common.client.net.data.PokemonInteractionsSyncHandler
import com.cobblemon.mod.common.client.net.data.RideSettingsSyncHandler
import com.cobblemon.mod.common.client.net.debug.OpenRidingStatsDebugGUIHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueClosedHandler
import com.cobblemon.mod.common.client.net.dialogue.DialogueOpenedHandler
import com.cobblemon.mod.common.client.net.effect.*
import com.cobblemon.mod.common.client.net.effect.PokeSnackBlockParticlesHandler
import com.cobblemon.mod.common.client.net.effect.RunPosableMoLangHandler
import com.cobblemon.mod.common.client.net.effect.SaccharineLogBlockParticlesHandler
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormEntityParticleHandler
import com.cobblemon.mod.common.client.net.effect.SpawnSnowstormParticleHandler
import com.cobblemon.mod.common.client.net.gui.ExpGainedDataPacketHandler
import com.cobblemon.mod.common.client.net.gui.InteractPokemonUIPacketHandler
import com.cobblemon.mod.common.client.net.gui.PokedexUIPacketHandler
@@ -34,7 +37,11 @@ import com.cobblemon.mod.common.client.net.gui.SummaryUIPacketHandler
import com.cobblemon.mod.common.client.net.npc.CloseNPCEditorHandler
import com.cobblemon.mod.common.client.net.npc.OpenNPCEditorHandler
import com.cobblemon.mod.common.client.net.orientation.ClientboundUpdateOrientationHandler
import com.cobblemon.mod.common.client.net.pasture.*
import com.cobblemon.mod.common.client.net.pasture.ClosePastureHandler
import com.cobblemon.mod.common.client.net.pasture.OpenPastureHandler
import com.cobblemon.mod.common.client.net.pasture.PokemonPasturedHandler
import com.cobblemon.mod.common.client.net.pasture.PokemonUnpasturedHandler
import com.cobblemon.mod.common.client.net.pasture.UpdatePastureConflictFlagHandler
import com.cobblemon.mod.common.client.net.pokedex.ServerConfirmedRegisterHandler
import com.cobblemon.mod.common.client.net.pokemon.update.ClientboundUpdateRidingStateHandler
import com.cobblemon.mod.common.client.net.pokemon.update.PokemonUpdatePacketHandler
@@ -52,7 +59,14 @@ import com.cobblemon.mod.common.client.net.storage.party.SetPartyPokemonHandler
import com.cobblemon.mod.common.client.net.storage.party.SetPartyReferenceHandler
import com.cobblemon.mod.common.client.net.storage.pc.*
import com.cobblemon.mod.common.client.net.toast.ToastPacketHandler
import com.cobblemon.mod.common.client.net.trade.*
import com.cobblemon.mod.common.client.net.trade.TradeAcceptanceChangedHandler
import com.cobblemon.mod.common.client.net.trade.TradeCancelledHandler
import com.cobblemon.mod.common.client.net.trade.TradeCompletedHandler
import com.cobblemon.mod.common.client.net.trade.TradeOfferExpiredHandler
import com.cobblemon.mod.common.client.net.trade.TradeOfferNotificationHandler
import com.cobblemon.mod.common.client.net.trade.TradeProcessStartedHandler
import com.cobblemon.mod.common.client.net.trade.TradeStartedHandler
import com.cobblemon.mod.common.client.net.trade.TradeUpdatedHandler
import com.cobblemon.mod.common.net.PacketRegisterInfo
import com.cobblemon.mod.common.net.messages.client.CalculateSeatPositionsPacket
import com.cobblemon.mod.common.net.messages.client.OpenBehaviourEditorPacket
@@ -69,12 +83,20 @@ import com.cobblemon.mod.common.net.messages.client.data.*
import com.cobblemon.mod.common.net.messages.client.debug.RequestOpenRidingStatsDebugGUIPacket
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueClosedPacket
import com.cobblemon.mod.common.net.messages.client.dialogue.DialogueOpenedPacket
import com.cobblemon.mod.common.net.messages.client.effect.*
import com.cobblemon.mod.common.net.messages.client.effect.PokeSnackBlockParticlesPacket
import com.cobblemon.mod.common.net.messages.client.effect.RunPosableMoLangPacket
import com.cobblemon.mod.common.net.messages.client.effect.SaccharineLogBlockParticlesPacket
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
import com.cobblemon.mod.common.net.messages.client.npc.CloseNPCEditorPacket
import com.cobblemon.mod.common.net.messages.client.npc.OpenNPCEditorPacket
import com.cobblemon.mod.common.net.messages.client.orientation.ClientboundUpdateDriverInputPacket
import com.cobblemon.mod.common.net.messages.client.orientation.ClientboundUpdateOrientationPacket
import com.cobblemon.mod.common.net.messages.client.pasture.*
import com.cobblemon.mod.common.net.messages.client.pasture.ClosePasturePacket
import com.cobblemon.mod.common.net.messages.client.pasture.OpenPasturePacket
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonPasturedPacket
import com.cobblemon.mod.common.net.messages.client.pasture.PokemonUnpasturedPacket
import com.cobblemon.mod.common.net.messages.client.pasture.UpdatePastureConflictFlagPacket
import com.cobblemon.mod.common.net.messages.client.pokedex.ServerConfirmedRegisterPacket
import com.cobblemon.mod.common.net.messages.client.pokemon.update.*
import com.cobblemon.mod.common.net.messages.client.pokemon.update.evolution.AddEvolutionPacket
@@ -94,19 +116,43 @@ import com.cobblemon.mod.common.net.messages.client.storage.party.InitializePart
import com.cobblemon.mod.common.net.messages.client.storage.party.MoveClientPartyPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.party.SetPartyReferencePacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.*
import com.cobblemon.mod.common.net.messages.client.storage.pc.ClosePCPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.InitializePCPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.MoveClientPCPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.OpenPCPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.RenamePCBoxPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCBoxPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.ChangePCBoxWallpaperPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.RequestPCBoxWallpapersPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.SetPCBoxWallpapersPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.UnlockPCBoxWallpaperPacket
import com.cobblemon.mod.common.net.messages.client.toast.ToastPacket
import com.cobblemon.mod.common.net.messages.client.trade.*
import com.cobblemon.mod.common.net.messages.client.trade.TradeAcceptanceChangedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeCancelledPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeCompletedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferExpiredPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeOfferNotificationPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeProcessStartedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeStartedPacket
import com.cobblemon.mod.common.net.messages.client.trade.TradeUpdatedPacket
import com.cobblemon.mod.common.net.messages.client.ui.ExpGainedDataPacket
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
import com.cobblemon.mod.common.net.messages.client.ui.PokedexUIPacket
import com.cobblemon.mod.common.net.messages.client.ui.SummaryUIPacket
import com.cobblemon.mod.common.net.messages.server.*
import com.cobblemon.mod.common.net.messages.server.battle.*
import com.cobblemon.mod.common.net.messages.server.BattleChallengePacket
import com.cobblemon.mod.common.net.messages.server.BattleChallengeResponsePacket
import com.cobblemon.mod.common.net.messages.server.BenchMovePacket
import com.cobblemon.mod.common.net.messages.server.RequestMoveSwapPacket
import com.cobblemon.mod.common.net.messages.server.RequestPlayerInteractionsPacket
import com.cobblemon.mod.common.net.messages.server.SelectStarterPacket
import com.cobblemon.mod.common.net.messages.server.SendOutPokemonPacket
import com.cobblemon.mod.common.net.messages.server.battle.BattleSelectActionsPacket
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamLeavePacket
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamRequestPacket
import com.cobblemon.mod.common.net.messages.server.battle.BattleTeamResponsePacket
import com.cobblemon.mod.common.net.messages.server.battle.RemoveSpectatorPacket
import com.cobblemon.mod.common.net.messages.server.battle.SpectateBattlePacket
import com.cobblemon.mod.common.net.messages.server.behaviour.DamageOnCollisionPacket
import com.cobblemon.mod.common.net.messages.server.behaviour.SetEntityBehaviourPacket
import com.cobblemon.mod.common.net.messages.server.block.AdjustBlockEntityViewerCountPacket
@@ -131,7 +177,11 @@ import com.cobblemon.mod.common.net.messages.server.pasture.UnpasturePokemonPack
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.FinishScanningPacket
import com.cobblemon.mod.common.net.messages.server.pokedex.scanner.StartScanningPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.interact.InteractPokemonPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.*
import com.cobblemon.mod.common.net.messages.server.pokemon.update.ServerboundUpdateRidingStatePacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetActiveMarkPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetItemHiddenPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetMarkingsPacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.SetNicknamePacket
import com.cobblemon.mod.common.net.messages.server.pokemon.update.evolution.AcceptEvolutionPacket
import com.cobblemon.mod.common.net.messages.server.riding.DismountPokemonPacket
import com.cobblemon.mod.common.net.messages.server.riding.ServerboundUpdateDriverInputPacket
@@ -142,11 +192,21 @@ import com.cobblemon.mod.common.net.messages.server.storage.party.MovePartyPokem
import com.cobblemon.mod.common.net.messages.server.storage.party.ReleasePartyPokemonPacket
import com.cobblemon.mod.common.net.messages.server.storage.party.SwapPartyPokemonPacket
import com.cobblemon.mod.common.net.messages.server.storage.pc.*
import com.cobblemon.mod.common.net.messages.server.trade.*
import com.cobblemon.mod.common.net.messages.server.trade.AcceptTradeRequestPacket
import com.cobblemon.mod.common.net.messages.server.trade.CancelTradePacket
import com.cobblemon.mod.common.net.messages.server.trade.ChangeTradeAcceptancePacket
import com.cobblemon.mod.common.net.messages.server.trade.OfferTradePacket
import com.cobblemon.mod.common.net.messages.server.trade.PerformTradePacket
import com.cobblemon.mod.common.net.messages.server.trade.UpdateTradeOfferPacket
import com.cobblemon.mod.common.net.serverhandling.ChallengeHandler
import com.cobblemon.mod.common.net.serverhandling.ChallengeResponseHandler
import com.cobblemon.mod.common.net.serverhandling.RequestInteractionsHandler
import com.cobblemon.mod.common.net.serverhandling.battle.*
import com.cobblemon.mod.common.net.serverhandling.battle.BattleSelectActionsHandler
import com.cobblemon.mod.common.net.serverhandling.battle.RemoveSpectatorHandler
import com.cobblemon.mod.common.net.serverhandling.battle.SpectateBattleHandler
import com.cobblemon.mod.common.net.serverhandling.battle.TeamLeaveHandler
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestHandler
import com.cobblemon.mod.common.net.serverhandling.battle.TeamRequestResponseHandler
import com.cobblemon.mod.common.net.serverhandling.behaviour.DamageOnCollisionPacketHandler
import com.cobblemon.mod.common.net.serverhandling.behaviour.SetEntityBehaviourHandler
import com.cobblemon.mod.common.net.serverhandling.block.AdjustBlockEntityViewerCountHandler
@@ -172,7 +232,11 @@ import com.cobblemon.mod.common.net.serverhandling.pasture.UnpasturePokemonHandl
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.FinishScanningHandler
import com.cobblemon.mod.common.net.serverhandling.pokedex.scanner.StartScanningHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.interact.InteractPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.*
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.ServerboundUpdateRidingStateHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetActiveMarkHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetItemHiddenHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetMarkingsHandler
import com.cobblemon.mod.common.net.serverhandling.pokemon.update.SetNicknameHandler
import com.cobblemon.mod.common.net.serverhandling.riding.DismountPokemonPacketHandler
import com.cobblemon.mod.common.net.serverhandling.riding.DriverInputPacketHandler
import com.cobblemon.mod.common.net.serverhandling.riding.ServerboundUpdateRiderRotationHandler
@@ -186,7 +250,12 @@ import com.cobblemon.mod.common.net.serverhandling.storage.party.MovePartyPokemo
import com.cobblemon.mod.common.net.serverhandling.storage.party.ReleasePCPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.storage.party.SwapPartyPokemonHandler
import com.cobblemon.mod.common.net.serverhandling.storage.pc.*
import com.cobblemon.mod.common.net.serverhandling.trade.*
import com.cobblemon.mod.common.net.serverhandling.trade.AcceptTradeRequestHandler
import com.cobblemon.mod.common.net.serverhandling.trade.CancelTradeHandler
import com.cobblemon.mod.common.net.serverhandling.trade.ChangeTradeAcceptanceHandler
import com.cobblemon.mod.common.net.serverhandling.trade.OfferTradeHandler
import com.cobblemon.mod.common.net.serverhandling.trade.PerformTradeHandler
import com.cobblemon.mod.common.net.serverhandling.trade.UpdateTradeOfferHandler
import com.cobblemon.mod.common.util.server
import net.minecraft.server.level.ServerPlayer
@@ -332,7 +401,6 @@ object CobblemonNetwork {
// Data registries
list.add(PacketRegisterInfo(AbilityRegistrySyncPacket.ID, AbilityRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(CobblemonMechanicsSyncPacket.ID, CobblemonMechanicsSyncPacket::decode, CobblemonMechanicsSyncHandler))
list.add(PacketRegisterInfo(PokemonInteractionsSyncPacket.ID, PokemonInteractionsSyncPacket::decode, PokemonInteractionsSyncHandler))
list.add(PacketRegisterInfo(MovesRegistrySyncPacket.ID, MovesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(BerryRegistrySyncPacket.ID, BerryRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
list.add(PacketRegisterInfo(SpeciesRegistrySyncPacket.ID, SpeciesRegistrySyncPacket::decode, DataRegistrySyncPacketHandler()))
@@ -23,7 +23,6 @@ class AspectCriterion(
): SimpleCriterionCondition<MutableMap<ResourceLocation, MutableSet<String>>>(playerCtx) {
companion object {
@JvmField
val CODEC: Codec<AspectCriterion> = RecordCodecBuilder.create { it.group(
//All three of these codecs used to use Codecs.createStrictOptionalFieldCodec, that no longer exists
ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(AspectCriterion::playerCtx),
@@ -36,4 +35,4 @@ class AspectCriterion(
val caughtAspects = context.getOrDefault(species, mutableSetOf())
return this.aspects.all { it in caughtAspects }
}
}
}
@@ -25,7 +25,6 @@ class BattleCountableCriterion(
): CountableCriterion<BattleCountableContext>(playerCtx, count) {
companion object {
@JvmField
val CODEC: Codec<BattleCountableCriterion> = RecordCodecBuilder.create { it.group(
ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(BattleCountableCriterion::playerCtx),
Codec.STRING.listOf().optionalFieldOf("battle_types", listOf("any")).forGetter(BattleCountableCriterion::battleTypes),
@@ -25,7 +25,6 @@ class CastPokeRodCriterionCondition(
): SimpleCriterionCondition<CastPokeRodContext>(playerCtx) {
companion object {
@JvmField
val CODEC: Codec<CastPokeRodCriterionCondition> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(CastPokeRodCriterionCondition::playerCtx),
Codec.STRING.optionalFieldOf("baitId", "empty_bait").forGetter(CastPokeRodCriterionCondition::baitId)
@@ -35,4 +34,4 @@ class CastPokeRodCriterionCondition(
override fun matches(player: ServerPlayer, context: CastPokeRodContext): Boolean {
return (context.baitId == this.baitId.asIdentifierDefaultingNamespace() || this.baitId == "empty_bait")
}
}
}
@@ -31,7 +31,6 @@ class CaughtPokemonCriterion(
): CountableCriterion<CountablePokemonTypeContext>(playerCtx, count) {
companion object {
@JvmField
val CODEC: Codec<CaughtPokemonCriterion> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(CaughtPokemonCriterion::playerCtx),
Codec.STRING.optionalFieldOf("type", "any").forGetter(CaughtPokemonCriterion::type),
@@ -43,4 +42,4 @@ class CaughtPokemonCriterion(
override fun matches(player: ServerPlayer, context: CountablePokemonTypeContext): Boolean {
return super.matches(player, context) && (context.type == type || type == "any")// && (context.species == species || species == "any")
}
}
}
@@ -23,7 +23,6 @@ open class CountableCriterion<T : CountableContext>(
): SimpleCriterionCondition<T>(playerCtx) {
companion object {
@JvmField
val CODEC: Codec<CountableCriterion<CountableContext>> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(CountableCriterion<CountableContext>::playerCtx),
Codec.INT.optionalFieldOf("count", 0).forGetter(CountableCriterion<CountableContext>::count)
@@ -26,7 +26,6 @@ class EvolvePokemonCriterion(
): CountableCriterion<EvolvePokemonContext>(playerCtx, count) {
companion object {
@JvmField
val CODEC: Codec<EvolvePokemonCriterion> = RecordCodecBuilder.create { it.group(
ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(EvolvePokemonCriterion::playerCtx),
Codec.STRING.optionalFieldOf("species", "any").forGetter(EvolvePokemonCriterion::species),
@@ -25,7 +25,6 @@ class LevelUpCriterion(
): SimpleCriterionCondition<LevelUpContext>(playerCtx) {
companion object {
@JvmField
val CODEC: Codec<LevelUpCriterion> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(LevelUpCriterion::playerCtx),
Codec.INT.optionalFieldOf("level", 0).forGetter(LevelUpCriterion::level),
@@ -43,4 +42,4 @@ class LevelUpCriterion(
return level == context.level && evolutionCheck == evolved
}
}
}
@@ -24,7 +24,6 @@ class PartyCheckCriterion(
): SimpleCriterionCondition<PlayerPartyStore>(playerCtx) {
companion object {
@JvmField
val CODEC: Codec<PartyCheckCriterion> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(PartyCheckCriterion::playerCtx),
ResourceLocation.CODEC.listOf().optionalFieldOf("party", listOf()).forGetter(PartyCheckCriterion::party)
@@ -48,4 +47,4 @@ class PartyCheckCriterion(
}
return matches.containsAll(party) && matches.size == party.size
}
}
}
@@ -23,7 +23,6 @@ class PlantTumblestoneCriterion(
): SimpleCriterionCondition<PlantTumblestoneContext>(playerCtx) {
companion object {
@JvmField
val CODEC: Codec<PlantTumblestoneCriterion> = RecordCodecBuilder.create { it.group(
ContextAwarePredicate.CODEC.optionalFieldOf("player").forGetter(PlantTumblestoneCriterion::playerCtx)
).apply(it, ::PlantTumblestoneCriterion) }
@@ -24,7 +24,6 @@ class PokemonCriterion(
): SimpleCriterionCondition<Pokemon>(playerCtx) {
companion object {
@JvmField
val CODEC: Codec<PokemonCriterion> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(PokemonCriterion::playerCtx),
Codec.STRING.optionalFieldOf("species", "any").forGetter(PokemonCriterion::species),
@@ -36,4 +35,4 @@ class PokemonCriterion(
var speciesCheck = (species.equals(context.species.resourceIdentifier.path) || species.equals(context.species.resourceIdentifier.toString())) || species.equals("any")
return speciesCheck && properties.matches(context)
}
}
}
@@ -25,7 +25,6 @@ class PokemonInteractCriterion(
val item: String
): SimpleCriterionCondition<PokemonInteractContext>(playerCtx) {
companion object {
@JvmField
val CODEC: Codec<PokemonInteractCriterion> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(PokemonInteractCriterion::playerCtx),
Codec.STRING.optionalFieldOf("species", "any").forGetter(PokemonInteractCriterion::species),
@@ -36,4 +35,4 @@ class PokemonInteractCriterion(
override fun matches(player: ServerPlayer, context: PokemonInteractContext): Boolean {
return (context.species == this.species.asIdentifierDefaultingNamespace() || this.species == "any") && (context.item == this.item.asIdentifierDefaultingNamespace() || this.item == "any")
}
}
}
@@ -26,7 +26,6 @@ class ReelInPokemonCriterionCondition(
) : SimpleCriterionCondition<ReelInPokemonContext>(playerCtx) {
companion object {
@JvmField
val CODEC: Codec<ReelInPokemonCriterionCondition> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter { it.playerCtx },
Codec.STRING.optionalFieldOf("species", "any").forGetter { it.species },
@@ -38,4 +37,4 @@ class ReelInPokemonCriterionCondition(
return (context.species == this.species.asIdentifierDefaultingNamespace() || this.species == "any")
&& (context.baitId == this.baitId.asIdentifierDefaultingNamespace() || this.baitId == "any" || this.baitId == "empty_bait")
}
}
}
@@ -28,7 +28,6 @@ class TradePokemonCriterion(
): SimpleCriterionCondition<TradePokemonContext>(playerCtx) {
companion object {
@JvmField
val CODEC: Codec<TradePokemonCriterion> = RecordCodecBuilder.create { it.group(
EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(TradePokemonCriterion::playerCtx),
Codec.STRING.optionalFieldOf("traded", "any").forGetter(TradePokemonCriterion::traded),
@@ -18,7 +18,7 @@ import net.minecraft.resources.ResourceKey
object CobblemonEntitySubPredicates : PlatformRegistry<Registry<MapCodec<out EntitySubPredicate>>, ResourceKey<Registry<MapCodec<out EntitySubPredicate>>>, MapCodec<out EntitySubPredicate>>() {
@JvmField
@JvmStatic
val POKE_POBBER = this.create("poke_bobber", FishingBobberPredicate.CODEC)
override val registry: Registry<MapCodec<out EntitySubPredicate>> = BuiltInRegistries.ENTITY_SUB_PREDICATE_TYPE
@@ -24,7 +24,7 @@ class FishingBobberPredicate(val inOpenWater: Boolean) : EntitySubPredicate {
return (entity as? PokeRodFishingBobberEntity)?.inOpenWater == this.inOpenWater
}
companion object {
@JvmField
@JvmStatic
val CODEC: MapCodec<FishingBobberPredicate> = RecordCodecBuilder.mapCodec { instance ->
instance.group(
Codec.BOOL.fieldOf("in_open_water").forGetter(FishingBobberPredicate::inOpenWater)
@@ -22,7 +22,7 @@ enum class Priority : StringRepresentable {
companion object {
@JvmField
@JvmStatic
val CODEC: Codec<Priority> = StringRepresentable.fromEnum(Priority::values)
}
@@ -104,7 +104,7 @@ open class Ability internal constructor(var template: AbilityTemplate, forced: B
companion object {
@JvmField
@JvmStatic
val CODEC: Codec<Ability> = RecordCodecBuilder.create {
it.group(
AbilityTemplate.CODEC.fieldOf(DataKeys.POKEMON_ABILITY_NAME).forGetter(Ability::template),
@@ -47,7 +47,7 @@ class AbilityTemplate(
companion object {
@JvmField
@JvmStatic
val CODEC: Codec<AbilityTemplate> = CodecUtils.createByStringCodec(
Abilities::getOrDummy,
AbilityTemplate::name
@@ -29,7 +29,6 @@ interface PotentialAbility {
val type: PotentialAbilityType<*>
fun isSatisfiedBy(aspects: Set<String>): Boolean
companion object {
@JvmField
val types = mutableListOf<PotentialAbilityType<*>>()
}
}
@@ -52,4 +51,5 @@ open class CommonAbility(override val template: AbilityTemplate) : PotentialAbil
override val priority = Priority.LOWEST
override val type = CommonAbilityType
override fun isSatisfiedBy(aspects: Set<String>) = true
}
}
@@ -26,9 +26,8 @@ class AttackHostileMobsTaskConfig : SingleTaskConfig {
): BehaviorControl<in LivingEntity>? {
return AttackHostileMobsTask.create()
}
companion object {
@JvmField
val CODEC: Codec<AttackHostileMobsTaskConfig> = Codec.unit(AttackHostileMobsTaskConfig())
}
}
@@ -99,7 +99,6 @@ enum class Apricorn : StringRepresentable {
override fun getSerializedName() = this.name.lowercase()
companion object {
@JvmField
val CODEC: Codec<Apricorn> = StringRepresentable.fromValues(::values)
}
}
@@ -24,7 +24,6 @@ class AllBiomeCondition(val minGroveSize: Int, val maxGroveSize: Int) : BerrySpa
}
companion object {
@JvmField
val ID = cobblemonResource("all_biome")
}
}
}
@@ -26,7 +26,6 @@ class PreferredBiomeCondition(val minGroveSize: Int, val maxGroveSize: Int) : Be
}
companion object {
@JvmField
val ID = cobblemonResource("preferred_biome")
}
}
}
@@ -24,7 +24,6 @@ class SpecificBiomeCondition : BerrySpawnCondition {
override fun getGroveSize(random: RandomSource) = random.nextIntBetweenInclusive(minGroveSize, maxGroveSize)
companion object {
@JvmField
val ID = cobblemonResource("specific_biome")
}
}
@@ -27,7 +27,6 @@ enum class Flavour(val colour: Int): StringRepresentable {
override fun getSerializedName() = name
companion object {
@JvmField
val CODEC = StringRepresentable.fromEnum<Flavour> { Flavour.entries.toTypedArray() }
}
}
}
@@ -17,7 +17,6 @@ data class Food(
val saturation: Float = 0f,
) {
companion object {
@JvmField
val CODEC: Codec<Food> = RecordCodecBuilder.create { builder ->
builder.group(
Codec.INT.optionalFieldOf("hunger", 0).forGetter { it.hunger },
@@ -38,7 +38,6 @@ data class Seasoning(
val mobEffects: List<SerializableMobEffectInstance>? = null
) {
companion object {
@JvmField
val CODEC: Codec<Seasoning> = RecordCodecBuilder.create { builder ->
builder.group(
ITEM_REGISTRY_LIKE_CODEC.fieldOf("ingredient").forGetter { it.ingredient },
@@ -59,7 +58,6 @@ data class Seasoning(
}
}
@JvmField
val STREAM_CODEC: StreamCodec<ByteBuf, Seasoning> = ByteBufCodecs.fromCodec(CODEC)
}
}
}
@@ -31,7 +31,6 @@ data class SerializableMobEffectInstance(
}
companion object {
@JvmField
val CODEC: Codec<SerializableMobEffectInstance> = RecordCodecBuilder.create { builder ->
builder.group(
ResourceLocation.CODEC.fieldOf("effect").forGetter { it.effect },
@@ -43,4 +42,4 @@ data class SerializableMobEffectInstance(
).apply(builder, ::SerializableMobEffectInstance)
}
}
}
}
@@ -1,22 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.cooking.effects
import net.minecraft.world.effect.MobEffect
import net.minecraft.world.effect.MobEffectCategory
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.LivingEntity
class CleanseAllEffect : MobEffect(MobEffectCategory.BENEFICIAL, 0xFFFFFF) {
override fun isInstantenous() = true
override fun applyInstantenousEffect(source: Entity?, indirect: Entity?, target: LivingEntity, amplifier: Int, proximity: Double) {
target.removeAllEffects()
}
override fun shouldApplyEffectTickThisTick(duration: Int, amplifier: Int) = false
}
@@ -1,27 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.cooking.effects
import net.minecraft.world.effect.MobEffect
import net.minecraft.world.effect.MobEffectCategory
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.LivingEntity
class CleanseNegativeEffect : MobEffect(MobEffectCategory.BENEFICIAL, 0xFFFFFF) {
override fun isInstantenous() = true
override fun applyInstantenousEffect(source: Entity?, indirect: Entity?, target: LivingEntity, amplifier: Int, proximity: Double) {
val snapshot = target.activeEffects.toList()
for (ei in snapshot) {
if (ei.effect.value().category == MobEffectCategory.HARMFUL) {
target.removeEffect(ei.effect)
}
}
}
override fun shouldApplyEffectTickThisTick(duration: Int, amplifier: Int) = false
}
@@ -1,33 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.api.cooking.effects
import net.minecraft.server.level.ServerPlayer
import net.minecraft.stats.Stats
import net.minecraft.world.effect.MobEffect
import net.minecraft.world.effect.MobEffectCategory
import net.minecraft.world.entity.LivingEntity
class MentalRestorationEffect : MobEffect(MobEffectCategory.BENEFICIAL, 0xAA66FF) {
override fun applyEffectTick(entity: LivingEntity, amplifier: Int): Boolean {
if (entity is ServerPlayer) {
val stats = entity.stats
val statType = Stats.CUSTOM.get(Stats.TIME_SINCE_REST)
val current = stats.getValue(statType)
val reduction = 31 * (amplifier + 1)// reduce by half a minute every second per level (30 ticks removed per tick + 1 to account for the tick passing)
val newValue = Math.max(current - reduction, 0)
stats.setValue(entity, statType, newValue)
}
return true
}
override fun shouldApplyEffectTickThisTick(duration: Int, amplifier: Int): Boolean {
return true
}
}
@@ -26,11 +26,9 @@ class Dialogue(
val initializationAction: DialogueAction = FunctionDialogueAction { _, _ -> }
) {
companion object {
@JvmField
val DEFAULT_BACKGROUND = cobblemonResource("textures/gui/dialogue/dialogue_box.png")
@JvmOverloads
@JvmStatic
fun of(
pages: Iterable<DialoguePage>,
background: ResourceLocation = DEFAULT_BACKGROUND,
@@ -46,7 +44,6 @@ class Dialogue(
}
@JvmOverloads
@JvmStatic
fun of(
pages: Iterable<DialoguePage>,
background: ResourceLocation = DEFAULT_BACKGROUND,
@@ -23,7 +23,7 @@ import com.cobblemon.mod.common.util.resolve
*/
interface DialogueAction {
companion object {
@JvmField
@JvmStatic
val types = mutableMapOf<String, Class<out DialogueAction>>()
}
@@ -23,7 +23,6 @@ sealed interface DialogueFaceProvider {
val isLeftSide: Boolean
companion object {
@JvmField
val types = mutableMapOf(
"artificial" to ArtificialDialogueFaceProvider::class.java,
"player" to PlayerDialogueFaceProvider::class.java,
@@ -58,9 +58,4 @@ object DialogueManager {
DialogueClosedPacket(activeDialogue.dialogueId).sendToPlayer(playerEntity)
activeDialogues.remove(playerEntity.uuid)
}
@JvmStatic
fun getDialogue(playerEntity: ServerPlayer): ActiveDialogue? {
return activeDialogues[playerEntity.uuid]
}
}
@@ -38,7 +38,6 @@ class DialoguePage(
) {
companion object {
@JvmOverloads
@JvmStatic
fun of(
/** The ID is optional, but if you want to be able to jump to this page from other pages then you probably want to set this. */
id: String = "",
@@ -79,4 +78,4 @@ class DialoguePage(
)
)
}
}
}
@@ -20,7 +20,6 @@ import com.cobblemon.mod.common.util.resolveBoolean
*/
interface DialoguePredicate {
companion object {
@JvmField
val types = mutableMapOf<String, Class<out DialoguePredicate>>()
}
@@ -24,7 +24,6 @@ import net.minecraft.network.chat.MutableComponent
*/
interface DialogueText {
companion object {
@JvmField
val types = mutableMapOf<String, Class<out DialogueText>>(
"expression" to ExpressionLikeDialogueText::class.java,
)
@@ -26,10 +26,7 @@ interface DropEntry {
companion object {
val entryTypes = mutableMapOf<String, Class<out DropEntry>>()
var defaultType: Class<out DropEntry>? = null
@JvmStatic
fun getByName(name: String) = entryTypes[name]
@JvmOverloads
@JvmStatic
fun <T : DropEntry> register(name: String, clazz: Class<T>, isDefault: Boolean = false) {
entryTypes[name] = clazz
if (isDefault) {
@@ -63,16 +63,13 @@ interface EntityEffect {
register(TransformEffect.ID, TransformEffect::class, ::TransformEffect)
}
@JvmStatic
fun <T : EntityEffect> register(id: String, type: KClass<T>, default: () -> T) {
effects[id] = type
defaults[id] = default
}
@JvmStatic
fun createDefault(id: String): EntityEffect? = defaults[id]?.invoke()
@JvmStatic
fun loadFromNbt(nbt: CompoundTag, registryLookup: HolderLookup.Provider): EntityEffect? {
if (nbt.contains(DataKeys.ENTITY_EFFECT_ID)) {
val id = nbt.getString(DataKeys.ENTITY_EFFECT_ID)
@@ -103,4 +100,4 @@ interface MocKEffect : PhysicalEffect {
val exposedBall: PokeBall?
get() = this.mock.pokeball?.let { PokeBalls.getPokeBall(it.asIdentifierDefaultingNamespace()) }
}
}
@@ -8,10 +8,12 @@
package com.cobblemon.mod.common.api.events.battles.instruction
import com.bedrockk.molang.runtime.value.MoValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
import com.cobblemon.mod.common.api.battles.model.actor.ActorType
import com.cobblemon.mod.common.api.events.battles.BattleEvent
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
import com.cobblemon.mod.common.util.asArrayValue
@@ -23,8 +25,7 @@ import com.cobblemon.mod.common.util.asArrayValue
data class FormeChangeEvent(
override val battle: PokemonBattle,
val pokemon: BattlePokemon,
val formeName: String,
val pnx: String
val formeName: String
) : BattleEvent {
val context = mutableMapOf(
"battle" to battle.struct,
@@ -32,7 +33,6 @@ data class FormeChangeEvent(
"npcs" to battle.actors.filter { it.type == ActorType.NPC }.asArrayValue { it.struct },
"wild_pokemon" to battle.actors.filter { it.type == ActorType.WILD }.asArrayValue { it.struct },
"pokemon" to pokemon.struct,
"forme" to StringValue(formeName),
"pnx" to StringValue(pnx)
"forme" to StringValue(formeName)
)
}
}
@@ -35,7 +35,6 @@ class SpawnBait(
constructor(type: ResourceLocation, subcategory: Optional<ResourceLocation>, chance: Double, value: Double) : this(type, subcategory.orElse(null), chance, value)
companion object {
@JvmField
val CODEC = RecordCodecBuilder.create<Effect> { instance ->
instance.group(
ResourceLocation.CODEC.fieldOf("type").forGetter { it.type },
@@ -48,7 +47,6 @@ class SpawnBait(
}
companion object {
@JvmField
val CODEC = RecordCodecBuilder.create<SpawnBait> { instance ->
instance.group(
ITEM_REGISTRY_LIKE_CODEC.fieldOf("item").forGetter { it.item },
@@ -56,7 +54,6 @@ class SpawnBait(
).apply(instance, ::SpawnBait)
}
@JvmField
val STREAM_CODEC = ByteBufCodecs.fromCodec(CODEC)
}
@@ -99,4 +96,6 @@ class SpawnBait(
}
}
}
}
}
@@ -9,14 +9,13 @@
package com.cobblemon.mod.common.api.interaction
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.conditional.RegistryLikeCondition
import com.cobblemon.mod.common.api.data.JsonDataRegistry
import com.cobblemon.mod.common.api.molang.ExpressionLike
import com.cobblemon.mod.common.api.pokemon.PokemonProperties
import com.cobblemon.mod.common.api.pokemon.requirement.OwnerQueryRequirement
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
import com.cobblemon.mod.common.api.reactive.SimpleObservable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.net.messages.client.data.PokemonInteractionsSyncPacket
import com.cobblemon.mod.common.pokemon.adapters.CobblemonRequirementAdapter
import com.cobblemon.mod.common.pokemon.evolution.adapters.LegacyItemConditionWrapperAdapter
import com.cobblemon.mod.common.pokemon.requirements.PokemonPropertiesRequirement
@@ -30,11 +29,6 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.packs.PackType
import net.minecraft.util.LowerCaseEnumTypeAdapterFactory
import net.minecraft.world.item.Item
import net.minecraft.world.level.biome.Biome
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.levelgen.structure.Structure
import net.minecraft.world.level.material.Fluid
object PokemonInteractions : JsonDataRegistry<PokemonInteractionSet> {
override val id = cobblemonResource("pokemon_interactions")
@@ -49,11 +43,6 @@ object PokemonInteractions : JsonDataRegistry<PokemonInteractionSet> {
.registerTypeAdapter(Requirement::class.java, CobblemonRequirementAdapter)
.registerTypeAdapter(InteractionEffect::class.java, InteractionEffectAdapter)
.registerTypeAdapter(ExpressionLike::class.java, ExpressionLikeAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Biome::class.java).type, BiomeLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Block::class.java).type, BlockLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Item::class.java).type, ItemLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Structure::class.java).type, StructureLikeConditionAdapter)
.registerTypeAdapter(TypeToken.getParameterized(RegistryLikeCondition::class.java, Fluid::class.java).type, FluidLikeConditionAdapter)
.registerTypeAdapter(IntRange::class.java, IntRangeAdapter)
.registerTypeAdapterFactory(LowerCaseEnumTypeAdapterFactory())
.setPrettyPrinting()
@@ -62,12 +51,7 @@ object PokemonInteractions : JsonDataRegistry<PokemonInteractionSet> {
val speciesInteractions = mutableListOf<PokemonInteractionSet>()
val generalInteractions = mutableListOf<PokemonInteractionSet>()
override fun sync(player: ServerPlayer) {
PokemonInteractionsSyncPacket(
speciesInteractions,
generalInteractions,
).sendToPlayer(player)
}
override fun sync(player: ServerPlayer) {}
override fun reload(data: Map<ResourceLocation, PokemonInteractionSet>) {
speciesInteractions.clear()
@@ -15,11 +15,11 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
import com.cobblemon.mod.common.pokemon.adapters.CobblemonRequirementAdapter
import com.cobblemon.mod.common.util.*
import com.google.gson.annotations.SerializedName
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.giveOrDropItemStack
import com.cobblemon.mod.common.util.withPlayerValue
import com.cobblemon.mod.common.util.withQueryValue
import net.minecraft.core.registries.Registries
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.sounds.SoundSource
@@ -28,83 +28,30 @@ import net.minecraft.world.entity.EquipmentSlot
import net.minecraft.world.entity.item.ItemEntity
import net.minecraft.world.item.ItemStack
/**
* A
*/
data class PokemonInteractionSet(
val requirements: List<Requirement> = listOf(),
val interactions: List<PokemonInteraction> = listOf(),
) {
fun encode(buffer: FriendlyByteBuf) {
buffer.writeCollection(requirements) { it, requirement ->
CobblemonRequirementAdapter.encode(requirement, it)
}
buffer.writeCollection(interactions) { it, interaction ->
interaction.encode(it)
}
}
companion object {
fun decode(buffer: FriendlyByteBuf): PokemonInteractionSet {
val requirements = buffer.readList { it ->
CobblemonRequirementAdapter.decode(it)
}
val interactions = buffer.readList { it ->
PokemonInteraction.decode(it)
}
return PokemonInteractionSet(
requirements,
interactions,
)
}
}
}
val interactions: List<PokemonInteraction> = listOf()
)
data class PokemonInteraction(
val grouping: ResourceLocation,
val requirements: List<Requirement> = listOf(),
val effects: List<InteractionEffect> = listOf(),
val cooldown: ExpressionLike = "0".asExpressionLike()
) {
fun encode(buffer: FriendlyByteBuf) {
buffer.writeResourceLocation(grouping)
buffer.writeCollection(requirements) { it, requirement ->
CobblemonRequirementAdapter.encode(requirement, it)
}
buffer.writeExpressionLike(cooldown)
}
companion object {
fun decode(buffer: FriendlyByteBuf): PokemonInteraction {
val grouping = buffer.readResourceLocation()
val requirements = buffer.readList { it ->
CobblemonRequirementAdapter.decode(it)
}
// No need to sync these for now
val effects = emptyList<InteractionEffect>()
val cooldown = buffer.readExpressionLike()
return PokemonInteraction(
grouping,
requirements,
effects,
cooldown,
)
}
}
}
)
interface InteractionEffect {
fun applyEffect(pokemon: PokemonEntity, player: ServerPlayer)
}
class DropItemEffect(val item: ResourceLocation, val amount: IntRange?) : InteractionEffect {
class DropItemEffect(val item: ResourceLocation, val amount: IntRange?): InteractionEffect {
override fun applyEffect(
pokemon: PokemonEntity,
player: ServerPlayer
) {
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException(
"Cannot load item with id: $item"
)
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException("Cannot load item with id: $item")
val stack = ItemStack(item)
stack.count = amount?.randomOrNull() ?: 1
if (stack.isEmpty)
@@ -121,14 +68,12 @@ class DropItemEffect(val item: ResourceLocation, val amount: IntRange?) : Intera
}
}
class GiveItemEffect(val item: ResourceLocation, val amount: IntRange?) : InteractionEffect {
class GiveItemEffect(val item: ResourceLocation, val amount: IntRange?): InteractionEffect {
override fun applyEffect(
pokemon: PokemonEntity,
player: ServerPlayer
) {
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException(
"Cannot load item with id: $item"
)
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(item) ?: throw IllegalArgumentException("Cannot load item with id: $item")
val stack = ItemStack(item)
stack.count = amount?.randomOrNull() ?: 1
if (stack.isEmpty)
@@ -141,54 +86,25 @@ class GiveItemEffect(val item: ResourceLocation, val amount: IntRange?) : Intera
}
}
class PlaySoundEffect(
val sound: ResourceLocation,
val soundSource: SoundSource?,
@SerializedName("playAround") private val _playAround: Boolean?,
@SerializedName("distance") private val _distance: Double?,
@SerializedName("volume") private val _volume: Float?,
@SerializedName("pitch") private val _pitch: Float?,
) : InteractionEffect {
class PlaySoundEffect(val sound: ResourceLocation, val soundSource: SoundSource?, val playAround: Boolean = true, val distance: Double = 64.0, val volume: Float = 1.0F, val pitch: Float = 1.0F): InteractionEffect {
override fun applyEffect(
pokemon: PokemonEntity,
player: ServerPlayer
) {
val packet = UnvalidatedPlaySoundS2CPacket(
sound,
soundSource ?: SoundSource.NEUTRAL,
pokemon.x,
pokemon.y,
pokemon.z,
volume,
pitch
)
val packet = UnvalidatedPlaySoundS2CPacket(sound, soundSource ?: SoundSource.NEUTRAL, pokemon.x, pokemon.y, pokemon.z, volume, pitch)
if (playAround) {
packet.sendToPlayersAround(pokemon.x, pokemon.y, pokemon.z, distance, pokemon.level().dimension())
packet.sendToPlayersAround( pokemon.x, pokemon.y, pokemon.z, distance, pokemon.level().dimension())
} else {
packet.sendToPlayer(player)
}
}
val playAround: Boolean
get() = _playAround != false
val distance: Double
get() = _distance ?: 64.0
val volume: Float
get() = _volume ?: 1.0F
val pitch: Float
get() = _pitch ?: 1.0F
companion object {
val ID = "play_sound"
}
}
class ShrinkItemEffect(val amount: Int = 1) : InteractionEffect {
class ShrinkItemEffect(val amount: Int = 1): InteractionEffect {
override fun applyEffect(
pokemon: PokemonEntity,
player: ServerPlayer
@@ -204,7 +120,7 @@ class ShrinkItemEffect(val amount: Int = 1) : InteractionEffect {
}
}
class ScriptEffect(val script: ExpressionLike) : InteractionEffect {
class ScriptEffect(val script: ExpressionLike): InteractionEffect {
override fun applyEffect(
pokemon: PokemonEntity,
player: ServerPlayer
@@ -223,7 +223,6 @@ abstract class RequestManager<T : ServerPlayerActionRequest> {
companion object {
private val managers = mutableListOf<RequestManager<*>>()
@JvmStatic
fun register(manager: RequestManager<*>) = managers.add(manager)
fun onLogoff(player: ServerPlayer) = managers.forEach { it.onLogoff(player) }
@@ -59,7 +59,7 @@ interface AbilityChanger<T : PotentialAbility> {
*
* While this can be used in custom data scenarios this functions most "game-like" if the Pokémon only has 2 common abilities.
*/
@JvmField
@JvmStatic
val COMMON_ABILITY: AbilityChanger<CommonAbility> = AbilityTypeChanger(CommonAbilityType) { other -> other == CommonAbilityType }
/**
@@ -67,7 +67,7 @@ interface AbilityChanger<T : PotentialAbility> {
*
* While this can be used in custom data scenarios this functions most "game-like" if the Pokémon only has 1 hidden ability.
*/
@JvmField
@JvmStatic
val HIDDEN_ABILITY: AbilityChanger<HiddenAbility> = AbilityTypeChanger(HiddenAbilityType) { other -> other == CommonAbilityType || other == HiddenAbilityType }
}
@@ -35,11 +35,10 @@ interface ExpressionLike {
fun resolveObject(runtime: MoLangRuntime) = resolve(runtime) as ObjectValue<*>
companion object {
@JvmField
val CODEC: Codec<ExpressionLike> = Codec.STRING.xmap({
it.asExpressionLike()
}) {
it.getString()
}
}
}
}
@@ -311,7 +311,7 @@ object MoLangFunctions {
runtime.environment.variable = params.environment.variable
val args = params.params.subList(1, params.params.size)
runtime.environment.context = ContextStruct(
(params.environment.context?.map ?: emptyMap()) + args.mapIndexed { index, value -> "arg_${index + 1}" to value }.toMap()
params.environment.context.map + args.mapIndexed { index, value -> "arg_${index + 1}" to value }.toMap()
)
val script = params.getString(0).asIdentifierDefaultingNamespace()
// store the args in the
@@ -324,24 +324,13 @@ object MoLangFunctions {
runtime.environment.context = params.environment.context
val expression = params.getString(0).asExpressionLike()
val delayInSeconds = params.getDoubleOrNull(1)?.toFloat() ?: 0.0f
fun evaluate(): MoValue {
return try {
runtime.resolve(expression)
} catch (ex: Exception) {
Cobblemon.LOGGER.warn("Failed to evaluate MoLang expression${if (delayInSeconds > 0.0f) " (delayed)" else ""}: $expression", ex)
DoubleValue.ZERO
}
}
if (delayInSeconds > 0.0f) {
val tracker = if (Cobblemon.implementation.environment() == Environment.SERVER) ServerTaskTracker else ClientTaskTracker
tracker.after(delayInSeconds) {
evaluate()
runtime.resolve(expression)
}
DoubleValue.ONE
} else {
evaluate()
runtime.resolve(expression)
}
},
"system_time_millis" to java.util.function.Function { _ ->
@@ -351,19 +340,19 @@ object MoLangFunctions {
"date_local_time" to java.util.function.Function { _ ->
val time = System.currentTimeMillis()
val date = java.util.Date(time)
val formatted = java.text.SimpleDateFormat("dd/MM/yyyy").format(date)
val formatted = java.text.SimpleDateFormat("DD/MM/YYYY").format(date)
StringValue(formatted)
},
"date_of" to java.util.function.Function { params ->
val time = params.getDouble(0).toLong()
val date = java.util.Date(time)
val formatted = java.text.SimpleDateFormat("dd/MM/yyyy").format(date)
val formatted = java.text.SimpleDateFormat("DD/MM/YYYY").format(date)
StringValue(formatted)
},
"date_is_after" to java.util.function.Function { params ->
val dateA = params.getString(0)
val dateB = params.getString(1)
val format = java.text.SimpleDateFormat("dd/MM/yyyy")
val format = java.text.SimpleDateFormat("DD/MM/YYYY")
val a = format.parse(dateA)
val b = format.parse(dateB)
DoubleValue(a.after(b))
@@ -790,20 +779,6 @@ object MoLangFunctions {
battleStartResult.ifSuccessful { returnValue = it.struct }
return@put returnValue
}
map.put("get_custom_stat") { params ->
val statName = params.getString(0)
val resourceLocation = ResourceLocation.tryParse(statName) ?: return@put DoubleValue.ZERO
val statResourceLocation = BuiltInRegistries.CUSTOM_STAT.get(resourceLocation) ?: return@put DoubleValue.ZERO
val exists = net.minecraft.stats.Stats.CUSTOM.contains(statResourceLocation)
if (!exists) return@put DoubleValue.ZERO
val stat = net.minecraft.stats.Stats.CUSTOM.get(statResourceLocation)
val value = player.stats.getValue(stat)
DoubleValue(value)
}
}
map
}
@@ -1764,35 +1739,22 @@ object MoLangFunctions {
pokemon.removeCosmeticItem()
}
map.put("add_marks") { params ->
var appliedMark = false
for (param in params.params) {
val identifier = param.asString().asIdentifierDefaultingNamespace()
val mark = Marks.getByIdentifier(identifier)
if (mark != null) {
pokemon.exchangeMark(mark, true)
appliedMark = true
}
if (mark != null) pokemon.exchangeMark(mark, true)
}
DoubleValue(appliedMark)
}
map.put("add_marks_with_chance") { params ->
var appliedMark = false
for (param in params.params) {
val identifier = param.asString().asIdentifierDefaultingNamespace()
val mark = Marks.getByIdentifier(identifier)
mark?.let {
val probability = it.chance.coerceIn(0F, 1F) * 100
val randomValue = Random.nextDouble(0.0, 100.0)
if (randomValue < probability) {
pokemon.exchangeMark(it, true)
appliedMark = true
}
if (randomValue < probability) pokemon.exchangeMark(it, true)
}
}
DoubleValue(appliedMark)
}
map.put("add_potential_marks") { params ->
for (param in params.params) {
@@ -112,7 +112,7 @@ class BenchedMoves : Iterable<BenchedMove> {
}
companion object {
@JvmField
@JvmStatic
val CODEC: Codec<BenchedMoves> = Codec.list(BenchedMove.CODEC)
.xmap(
{ moveList ->
@@ -144,7 +144,6 @@ data class BenchedMove(val moveTemplate: MoveTemplate, val ppRaisedStages: Int)
}
companion object {
@JvmStatic
fun loadFromNBT(nbt: CompoundTag): BenchedMove {
val name = nbt.getString(DataKeys.POKEMON_MOVESET_MOVENAME)
return BenchedMove(
@@ -153,7 +152,6 @@ data class BenchedMove(val moveTemplate: MoveTemplate, val ppRaisedStages: Int)
)
}
@JvmStatic
fun loadFromJSON(json: JsonObject): BenchedMove {
val name = json.get(DataKeys.POKEMON_MOVESET_MOVENAME).asString
return BenchedMove(
@@ -162,7 +160,6 @@ data class BenchedMove(val moveTemplate: MoveTemplate, val ppRaisedStages: Int)
)
}
@JvmStatic
fun loadFromBuffer(buffer: RegistryFriendlyByteBuf): BenchedMove {
val name = buffer.readString()
return BenchedMove(
@@ -171,7 +168,7 @@ data class BenchedMove(val moveTemplate: MoveTemplate, val ppRaisedStages: Int)
)
}
@JvmField
@JvmStatic
val CODEC: Codec<BenchedMove> = RecordCodecBuilder.create { it.group(
MoveTemplate.BY_STRING_CODEC.fieldOf(DataKeys.POKEMON_MOVESET_MOVENAME).forGetter(BenchedMove::moveTemplate),
Codec.intRange(0, 3).fieldOf(DataKeys.POKEMON_MOVESET_RAISED_PP_STAGES).forGetter(BenchedMove::ppRaisedStages)
@@ -149,14 +149,12 @@ open class Move(
}
companion object {
@JvmStatic
fun loadFromNBT(nbt: CompoundTag): Move {
val moveName = nbt.getString(DataKeys.POKEMON_MOVESET_MOVENAME)
val template = Moves.getByNameOrDummy(moveName)
return template.create(nbt.getInt(DataKeys.POKEMON_MOVESET_MOVEPP), nbt.getInt(DataKeys.POKEMON_MOVESET_RAISED_PP_STAGES))
}
@JvmStatic
fun loadFromJSON(json: JsonObject): Move {
val moveName = json.get(DataKeys.POKEMON_MOVESET_MOVENAME).asString
val template = Moves.getByNameOrDummy(moveName)
@@ -165,7 +163,6 @@ open class Move(
return Move(template, currentPp, raisedPpStages)
}
@JvmStatic
fun loadFromBuffer(buffer: RegistryFriendlyByteBuf): Move {
val moveName = buffer.readString()
val currentPp = buffer.readSizedInt(IntSize.U_BYTE)
@@ -174,7 +171,7 @@ open class Move(
return template.create(currentPp, raisedPpStages)
}
@JvmField
@JvmStatic
val CODEC: Codec<Move> = RecordCodecBuilder.create { it.group(
MoveTemplate.BY_STRING_CODEC.fieldOf(DataKeys.POKEMON_MOVESET_MOVENAME).forGetter(Move::template),
Codec.intRange(0, Int.MAX_VALUE).fieldOf(DataKeys.POKEMON_MOVESET_MOVEPP).forGetter(Move::currentPp),
@@ -208,7 +208,7 @@ class MoveSet : Iterable<Move> {
companion object {
const val MOVE_COUNT = 4
@JvmField
@JvmStatic
val CODEC: Codec<MoveSet> = Codec.list(Move.CODEC, 0, MOVE_COUNT)
.xmap(
{ moveList ->
@@ -90,10 +90,9 @@ open class MoveTemplate(
)
companion object {
@JvmStatic
fun dummy(name: String) = Dummy(name)
@JvmField
@JvmStatic
val BY_STRING_CODEC: Codec<MoveTemplate> = CodecUtils.createByStringCodec(
Moves::getByNameOrDummy,
MoveTemplate::name
@@ -158,4 +157,4 @@ open class MoveTemplate(
}
return this.elementalType
}
}
}
@@ -32,7 +32,6 @@ class ActionEffectTimeline(
val condition: ExpressionLike = "true".asExpressionLike()
) {
companion object {
@JvmField
val NONE = ActionEffectTimeline()
}
@@ -99,4 +98,4 @@ interface EntityProvider {
// val sound: ResourceLocation? = null,
// val animation: List<AnimationWithMoments> = listOf(),
// val effects: List<ActionEffect> = listOf()
//)
//)
@@ -21,10 +21,8 @@ import java.util.concurrent.CompletableFuture
*/
interface ActionEffectKeyframe {
companion object {
@JvmField
val types = mutableMapOf<String, Class<out ActionEffectKeyframe>>()
@JvmStatic
inline fun <reified T : ActionEffectKeyframe> register(type: String) {
types[type] = T::class.java
}
@@ -33,4 +31,4 @@ interface ActionEffectKeyframe {
fun play(context: ActionEffectContext): CompletableFuture<Unit>
fun interrupt(context: ActionEffectContext) {}
fun skip(): CompletableFuture<Unit> = CompletableFuture.completedFuture(Unit)
}
}
@@ -32,4 +32,4 @@ enum class MulchVariant(val duration: Int = -1) : StringRepresentable {
companion object {
const val GROWTH_TIME_MULTIPLIER = 0.5
}
}
}
@@ -109,7 +109,6 @@ object NPCClasses : JsonDataRegistry<NPCClass> {
* @param name The path of the NPC class asset.
* @return The [NPCClass] if existing.
*/
@JvmStatic
fun getByName(name: String) = this.getByIdentifier(cobblemonResource(name))
/**
@@ -25,7 +25,6 @@ import net.minecraft.server.level.ServerPlayer
*/
interface NPCPartyProvider {
companion object {
@JvmField
val types = mutableMapOf<String, (String) -> NPCPartyProvider>(
SimplePartyProvider.TYPE to { SimplePartyProvider() },
PoolPartyProvider.TYPE to { PoolPartyProvider() },
@@ -34,7 +34,6 @@ interface NPCInteractConfiguration {
companion object {
val types = mutableMapOf<String, NPCInteractConfigurationType<out NPCInteractConfiguration>>()
@JvmStatic
fun register(type: String, displayName: MutableComponent, clazz: Class<out NPCInteractConfiguration>) {
types[type] = NPCInteractConfigurationType(displayName, clazz)
}
@@ -34,7 +34,6 @@ interface NPCVariationProvider {
"random" to RandomNPCVariationProvider::class.java
)
@JvmStatic
fun register(type: String, clazz: Class<out NPCVariationProvider>) {
types[type] = clazz
}
@@ -23,11 +23,8 @@ import kotlin.math.sign
open class OrientationController(val entity: LivingEntity) {
companion object {
@JvmField
val FORWARDS: Vector3f = Vector3f(0.0f, 0.0f, -1.0f)
@JvmField
val UP: Vector3f = Vector3f(0.0f, 1.0f, 0.0f)
@JvmField
val LEFT: Vector3f = Vector3f(-1.0f, 0.0f, 0.0f)
}
@@ -132,4 +129,4 @@ open class OrientationController(val entity: LivingEntity) {
return@updateOrientation Matrix3f().set(resultQuat)
}
}
}
@@ -25,7 +25,6 @@ enum class PermissionLevel(val numericalValue: Int) {
ALL_COMMANDS(4);
companion object {
@JvmStatic
fun byNumericValue(value: Int): PermissionLevel {
return entries.first { it.numericalValue == value }
}
@@ -23,8 +23,6 @@ data class CaptureContext(
* @param critical If the capture is a critical capture, defaults to false.
* @return The generated [CaptureContext].
*/
@JvmOverloads
@JvmStatic
fun successful(critical: Boolean = false): CaptureContext {
if (critical) {
return CaptureContext(numberOfShakes = 1, isSuccessfulCapture = true, isCriticalCapture = true)
@@ -37,7 +37,6 @@ import net.minecraft.network.RegistryFriendlyByteBuf
*/
class FormDexRecord {
companion object {
@JvmField
val CODEC: Codec<FormDexRecord> = RecordCodecBuilder.create { instance ->
instance.group(
ListCodec(Codec.STRING, 0, 3).fieldOf("genders").forGetter { it.genders.map { it.name } },
@@ -26,11 +26,10 @@ enum class PokedexEntryProgress : StringRepresentable, Comparable<PokedexEntryPr
override fun getSerializedName() = this.name
companion object {
@JvmField
val CODEC: Codec<PokedexEntryProgress> = RecordCodecBuilder.create { instance ->
instance.map ({
PokedexEntryProgress.valueOf(it)
}, PrimitiveCodec.STRING.fieldOf("name").forGetter { it.name })
}
}
}
}
@@ -70,7 +70,6 @@ class PokedexManager(
}
companion object {
@JvmField
val CODEC = RecordCodecBuilder.create<PokedexManager> { instance ->
instance.group(
PrimitiveCodec.STRING.fieldOf("uuid").forGetter { it.uuid.toString() },
@@ -33,7 +33,6 @@ import net.minecraft.resources.ResourceLocation
*/
class SpeciesDexRecord {
companion object {
@JvmField
val CODEC: Codec<SpeciesDexRecord> = RecordCodecBuilder.create { instance ->
instance.group(
ListCodec(PrimitiveCodec.STRING, 0, 512).fieldOf("aspects").forGetter { it.aspects.toList() },
@@ -76,9 +76,7 @@ class AggregatePokedexDef(
}
companion object {
@JvmField
val ID = cobblemonResource("aggregate_pokedex_def")
@JvmField
val CODEC: MapCodec<AggregatePokedexDef> = RecordCodecBuilder.mapCodec { instance ->
instance.group(
ResourceLocation.CODEC.fieldOf("id").forGetter { it.id },
@@ -34,12 +34,9 @@ abstract class PokedexDef: ClientDataSynchronizer<PokedexDef> {
abstract fun getEntries(): List<PokedexEntry>
companion object {
@JvmField
val CODEC: Codec<PokedexDef> = ResourceLocation.CODEC.dispatch("type", PokedexDef::typeId, PokedexDef::getCodecById)
@JvmField
val PACKET_CODEC: StreamCodec<ByteBuf, PokedexDef> = ResourceLocation.STREAM_CODEC.dispatch({ it.typeId }, ::getPacketCodecById)
@JvmStatic
fun getPacketCodecById(id: ResourceLocation): StreamCodec<ByteBuf, out PokedexDef> {
return when (id) {
SimplePokedexDef.ID -> SimplePokedexDef.PACKET_CODEC
@@ -48,7 +45,6 @@ abstract class PokedexDef: ClientDataSynchronizer<PokedexDef> {
}
}
@JvmStatic
fun getCodecById(id: ResourceLocation): MapCodec<out PokedexDef> {
return when (id) {
SimplePokedexDef.ID -> SimplePokedexDef.CODEC
@@ -64,9 +64,7 @@ class SimplePokedexDef(
}
companion object {
@JvmField
val ID = cobblemonResource("simple_pokedex_def")
@JvmField
val CODEC: MapCodec<SimplePokedexDef> = RecordCodecBuilder.mapCodec { instance ->
instance.group(
ResourceLocation.CODEC.fieldOf("id").forGetter { it.id },
@@ -80,7 +78,6 @@ class SimplePokedexDef(
}
}
@JvmField
val PACKET_CODEC: StreamCodec<ByteBuf, SimplePokedexDef> = StreamCodec.composite(
ResourceLocation.STREAM_CODEC, SimplePokedexDef::id,
ByteBufCodecs.INT, SimplePokedexDef::sortOrder,
@@ -82,13 +82,13 @@ import kotlin.jvm.optionals.getOrNull
open class PokemonProperties {
companion object {
@JvmField
@JvmStatic
val CODEC: Codec<PokemonProperties> = Codec.STRING.xmap(
{ parse(it) },
{ it.asString() }
)
@JvmField
@JvmStatic
val CUSTOM_PROPERTIES_CODEC: Codec<MutableList<CustomPokemonProperty>> = Codec.list(Codec.STRING)
.xmap(
{ string -> parse(string.joinToString(" ")).customProperties },
@@ -96,7 +96,6 @@ open class PokemonProperties {
)
@JvmOverloads
@JvmStatic
fun parse(string: String, delimiter: String = " ", assigner: String = "="): PokemonProperties {
val props = PokemonProperties()
props.originalString = string
@@ -22,14 +22,10 @@ import com.cobblemon.mod.common.pokemon.Pokemon
interface AspectProvider {
companion object {
val providers = mutableListOf<AspectProvider>()
@JvmStatic
fun register(provider: AspectProvider): AspectProvider {
providers.add(provider)
return provider
}
@JvmStatic
fun unregister(provider: AspectProvider) {
providers.remove(provider)
}
@@ -21,7 +21,6 @@ import com.cobblemon.mod.common.pokemon.Pokemon
*/
interface SingleConditionalAspectProvider : AspectProvider {
companion object {
@JvmStatic
fun getForFeature(name: String): SingleConditionalAspectProvider {
return object : SingleConditionalAspectProvider {
override val aspect: String = name
@@ -38,7 +38,6 @@ enum class EggGroup(val showdownID: String) {
it.showdownID.lowercase().replace(" ", "_").replace("-", "_")
}
@JvmStatic
fun fromIdentifier(identifier: String): EggGroup? {
val key = identifier.lowercase().replace(" ", "_").replace("-", "_")
return identifierMap[key]
@@ -26,9 +26,9 @@ interface PreEvolution {
val form: FormData
companion object {
@JvmOverloads
@JvmStatic
fun of(species: Species, form: FormData = species.standardForm): PreEvolution = StandardPreEvolution(species, form)
}
}
@@ -25,15 +25,15 @@ object EvolutionProgressTypes {
ResourceKey.createRegistryKey(cobblemonResource("evolution_progress")), Lifecycle.stable()
)
@JvmField
@JvmStatic
val DAMAGE_TAKEN = this.registerType(DamageTakenEvolutionProgress.ID, EvolutionProgressType(DamageTakenEvolutionProgress.CODEC))
@JvmField
@JvmStatic
val DEFEAT = this.registerType(DefeatEvolutionProgress.ID, EvolutionProgressType(DefeatEvolutionProgress.CODEC))
@JvmField
@JvmStatic
val LAST_BATTLE_CRITICAL_HITS = this.registerType(LastBattleCriticalHitsEvolutionProgress.ID, EvolutionProgressType(LastBattleCriticalHitsEvolutionProgress.CODEC))
@JvmField
@JvmStatic
val RECOIL = this.registerType(RecoilEvolutionProgress.ID, EvolutionProgressType(RecoilEvolutionProgress.CODEC))
@JvmField
@JvmStatic
val USE_MOVE = this.registerType(UseMoveEvolutionProgress.ID, EvolutionProgressType(UseMoveEvolutionProgress.CODEC))
/**
@@ -80,9 +80,7 @@ open class ChoiceSpeciesFeatureProvider(
internal constructor(): this(emptyList())
override fun get(pokemon: Pokemon): StringSpeciesFeature? {
return pokemon.features.filterIsInstance<StringSpeciesFeature>().find { it.name in keys }
}
override fun get(pokemon: Pokemon) = pokemon.getFeature<StringSpeciesFeature>(keys.first())
override fun invoke(pokemon: Pokemon): StringSpeciesFeature? {
val existing = get(pokemon)
@@ -103,15 +101,15 @@ open class ChoiceSpeciesFeatureProvider(
}
override fun invoke(nbt: CompoundTag): StringSpeciesFeature? {
val key = keys.find { nbt.contains(it) }
if (key == null) return null
return StringSpeciesFeature(key, "").also { it.loadFromNBT(nbt) }
return if (nbt.contains(keys.first())) {
StringSpeciesFeature(keys.first(), "").also { it.loadFromNBT(nbt) }
} else null
}
override fun invoke(json: JsonObject): StringSpeciesFeature? {
val key = keys.find { json.has(it) }
if (key == null) return null
return StringSpeciesFeature(key, "").also { it.loadFromJSON(json) }
return if (json.has(keys.first())) {
StringSpeciesFeature(keys.first(), "").also { it.loadFromJSON(json) }
} else null
}
override fun fromString(value: String?): StringSpeciesFeature? {
@@ -133,7 +131,7 @@ open class ChoiceSpeciesFeatureProvider(
override fun provide(properties: PokemonProperties): Set<String> {
return if (isAspect) {
val feature = properties.customProperties.filterIsInstance<StringSpeciesFeature>().find { it.name in keys }
val feature = properties.customProperties.filterIsInstance<StringSpeciesFeature>().find { it.name == keys.first() }
if (feature != null) {
setOf(getAspect(feature))
} else {
@@ -132,9 +132,7 @@ class FlagSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<FlagSpecie
constructor(vararg keys: String) : this(keys.toList())
override fun get(pokemon: Pokemon): FlagSpeciesFeature? {
return pokemon.features.filterIsInstance<FlagSpeciesFeature>().find { it.name in keys }
}
override fun get(pokemon: Pokemon) = pokemon.getFeature<FlagSpeciesFeature>(keys.first())
override fun invoke(pokemon: Pokemon): FlagSpeciesFeature? {
return get(pokemon)
@@ -146,15 +144,15 @@ class FlagSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<FlagSpecie
}
override fun invoke(nbt: CompoundTag): FlagSpeciesFeature? {
val key = keys.find { nbt.contains(it) }
if (key == null) return null
return FlagSpeciesFeature(key, false).also { it.loadFromNBT(nbt) }
return if (nbt.contains(keys.first())) {
FlagSpeciesFeature(keys.first(), false).also { it.loadFromNBT(nbt) }
} else null
}
override fun invoke(json: JsonObject): FlagSpeciesFeature? {
val key = keys.find { json.has(it) }
if (key == null) return null
return FlagSpeciesFeature(key, false).also { it.loadFromJSON(json) }
return if (json.has(keys.first())) {
FlagSpeciesFeature(keys.first(), false).also { it.loadFromJSON(json) }
} else null
}
override fun fromString(value: String?): FlagSpeciesFeature? {
@@ -172,26 +170,16 @@ class FlagSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<FlagSpecie
}
override fun provide(pokemon: Pokemon): Set<String> {
return if (isAspect) {
val feature = pokemon.features.filterIsInstance<FlagSpeciesFeature>().find { it.name in keys }
if (feature != null && feature.enabled) {
setOf(keys.first())
} else {
emptySet()
}
return if (isAspect && pokemon.getFeature<FlagSpeciesFeature>(keys.first())?.enabled == true) {
setOf(keys.first())
} else {
emptySet()
}
}
override fun provide(properties: PokemonProperties): Set<String> {
return if (isAspect) {
val feature = properties.customProperties.filterIsInstance<FlagSpeciesFeature>().find { it.name in keys }
if (feature != null && feature.enabled) {
setOf(keys.first())
} else {
emptySet()
}
return if (isAspect && properties.customProperties.filterIsInstance<FlagSpeciesFeature>().find { it.name == keys.first() }?.enabled == true) {
setOf(keys.first())
} else {
emptySet()
}
@@ -142,15 +142,19 @@ class IntSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<IntSpeciesF
}
override fun invoke(nbt: CompoundTag): IntSpeciesFeature? {
val key = keys.find { nbt.contains(it) }
if (key == null) return null
return IntSpeciesFeature(keys.first(), nbt.getInt(key));
return if (nbt.contains(keys.first())) {
IntSpeciesFeature(keys.first(), nbt.getInt(keys.first()))
} else {
null
}
}
override fun invoke(json: JsonObject): IntSpeciesFeature? {
val key = keys.find { json.has(it) }
if (key == null) return null
return IntSpeciesFeature(keys.first(), json.get(key).asInt)
return if (json.has(keys.first())) {
IntSpeciesFeature(keys.first(), json.get(keys.first()).asInt)
} else {
null
}
}
override fun get(pokemon: Pokemon) = pokemon.features.filterIsInstance<IntSpeciesFeature>().find { it.name in keys }
@@ -102,12 +102,6 @@ object SpeciesFeatures : JsonDataRegistry<SpeciesFeatureProvider<*>> {
@JvmStatic
fun register(name: String, provider: SpeciesFeatureProvider<*>) = register(name, provider, isCoded = true)
@JvmStatic
fun registerType(key: String, clazz: Class<out SpeciesFeatureProvider<*>>) {
types[key] = clazz
}
private fun registerFromAssets(identifier: ResourceLocation, provider: SpeciesFeatureProvider<*>) = register(identifier.path, provider, isCoded = false)
@JvmStatic
@@ -34,7 +34,6 @@ fun interface FriendshipMutationCalculator {
* For more information see this [Bulbapedia](https://bulbapedia.bulbagarden.net/wiki/Friendship#Generation_VIII) entry.
* It will yield 3 between 0 and 99 friendship, 2 between 100 and 199 otherwise 0.
*/
@JvmField
val SWORD_AND_SHIELD_LEVEL_UP = FriendshipMutationCalculator { pokemon ->
when {
pokemon.friendship <= 99 -> 3
@@ -23,7 +23,6 @@ open class Learnset : ClientDataSynchronizer<Learnset> {
val loadMove: (JsonElement, Learnset) -> Boolean
) {
companion object {
@JvmStatic
fun parseFromPrefixIntoList(prefix: String, list: (Learnset) -> MutableList<MoveTemplate>): Interpreter {
return Interpreter { element, learnset ->
val str = element.takeIf { it.isJsonPrimitive }?.asString ?: return@Interpreter false
@@ -41,19 +40,12 @@ open class Learnset : ClientDataSynchronizer<Learnset> {
}
companion object {
@JvmField
val tmInterpreter = Interpreter.parseFromPrefixIntoList("tm") { it.tmMoves }
@JvmField
val eggInterpreter = Interpreter.parseFromPrefixIntoList("egg") { it.eggMoves }
@JvmField
val tutorInterpreter = Interpreter.parseFromPrefixIntoList("tutor") { it.tutorMoves }
@JvmField
val legacyInterpreter = Interpreter.parseFromPrefixIntoList("legacy") { it.legacyMoves }
@JvmField
val specialInterpreter = Interpreter.parseFromPrefixIntoList("special") { it.specialMoves }
@JvmField
val formChangeInterpreter = Interpreter.parseFromPrefixIntoList("form_change") { it.formChangeMoves }
@JvmField
val levelUpInterpreter = Interpreter { element, learnset ->
val str = element.takeIf { it.isJsonPrimitive }?.asString ?: return@Interpreter false
val splits = str.split(":")
@@ -76,7 +68,6 @@ open class Learnset : ClientDataSynchronizer<Learnset> {
}
@JvmField
val interpreters = mutableListOf(
tmInterpreter,
eggInterpreter,
@@ -22,7 +22,7 @@ fun interface LearnsetQuery {
fun canLearn(move: MoveTemplate, learnset: Learnset): Boolean
companion object {
@JvmField
val ANY = LearnsetQuery { move, learnset ->
learnset.levelUpMoves.values.any { it.contains(move) }
|| learnset.eggMoves.contains(move)
@@ -34,7 +34,6 @@ fun interface LearnsetQuery {
|| learnset.specialMoves.contains(move)
}
@JvmField
val LEGAL = LearnsetQuery { move, learnset ->
learnset.levelUpMoves.values.any { it.contains(move) }
|| learnset.eggMoves.contains(move)
@@ -44,31 +43,22 @@ fun interface LearnsetQuery {
|| learnset.evolutionMoves.contains(move)
}
@JvmStatic
fun level(level: Int) = LearnsetQuery { move, learnset -> learnset.getLevelUpMovesUpTo(level).contains(move) }
@JvmField
val ANY_LEVEL = LearnsetQuery { move, learnset -> learnset.levelUpMoves.values.any { it.contains(move) } }
@JvmField
val EGG_MOVE = LearnsetQuery { move, learnset -> learnset.eggMoves.contains(move) }
@JvmField
val TUTOR_MOVES = LearnsetQuery { move, learnset -> learnset.tutorMoves.contains(move) }
@JvmField
val TM_MOVE = LearnsetQuery { move, learnset -> learnset.tmMoves.contains(move) }
@JvmField
val FORM_CHANGE = LearnsetQuery { move, learnset -> learnset.formChangeMoves.contains(move) }
@JvmField
val EVOLUTION = LearnsetQuery { move, learnset -> learnset.evolutionMoves.contains(move) }
@JvmField
val LEGACY_MOVES = LearnsetQuery { move, learnset -> learnset.legacyMoves.contains(move) }
@JvmField
val SPECIAL_MOVES = LearnsetQuery { move, learnset -> learnset.specialMoves.contains(move) }
}
@@ -12,7 +12,6 @@ import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.pokemon.Pokemon
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
/**
* A [Requirement] that expects a [LivingEntity] to be attached to the [Pokemon].
@@ -27,7 +26,7 @@ interface OwnerQueryRequirement : Requirement {
override fun check(pokemon: Pokemon): Boolean {
val owner = pokemon.getOwnerEntity() ?: return false
return when (owner) {
is Player -> {
is ServerPlayer -> {
this.checkPlayer(pokemon, owner)
}
is NPCEntity -> {
@@ -38,13 +37,13 @@ interface OwnerQueryRequirement : Requirement {
}
/**
* Checks if the given [Pokemon] & [Player] satisfies the requirement.
* Checks if the given [Pokemon] & [ServerPlayer] satisfies the requirement.
*
* @param pokemon The [Pokemon] being queried.
* @param owner The [Player] that owns this [Pokemon].
* @param owner The [ServerPlayer] that owns this [Pokemon].
* @return If the requirement was satisfied.
*/
fun checkPlayer(pokemon: Pokemon, owner: Player): Boolean
fun checkPlayer(pokemon: Pokemon, owner: ServerPlayer): Boolean
/**
* Checks if the given [Pokemon] & [NPCEntity] satisfies the requirement.
@@ -70,7 +70,7 @@ interface Stat {
/**
* A [Codec] for [Stat] without filtering the [Stat.Type].
*/
@JvmField
@JvmStatic
val ALL_CODEC: Codec<Stat> = CodecUtils.createByIdentifierCodec(
Cobblemon.statProvider::fromIdentifier,
Stat::identifier
@@ -79,7 +79,7 @@ interface Stat {
/**
* A [Codec] for [Stat] with the [Stat.Type.PERMANENT].
*/
@JvmField
@JvmStatic
val PERMANENT_ONLY_CODEC: Codec<Stat> = ALL_CODEC.comapFlatMap(
{ stat -> if (stat.type == Type.PERMANENT) DataResult.success(stat) else DataResult.error { "${stat.identifier} is not of type ${Type.PERMANENT}" } },
{ stat -> stat }
@@ -88,7 +88,7 @@ interface Stat {
/**
* A [Codec] for [Stat] with the [Stat.Type.BATTLE_ONLY].
*/
@JvmField
@JvmStatic
val BATTLE_ONLY_CODEC: Codec<Stat> = ALL_CODEC.comapFlatMap(
{ stat -> if (stat.type == Type.BATTLE_ONLY) DataResult.success(stat) else DataResult.error { "${stat.identifier} is not of type ${Type.BATTLE_ONLY}" } },
{ stat -> stat }
@@ -35,25 +35,21 @@ enum class Stats(override val identifier: ResourceLocation, override val display
* All the stats, an alternative to [values].
* Using [StatProvider.all] is recommended instead for maximum addon compatibility.
*/
@JvmField
val ALL: Set<Stat> = EnumSet.allOf(Stats::class.java)
/**
* All the stats with type of [Stat.Type.PERMANENT].
* Using [StatProvider.ofType] with type [Stat.Type.PERMANENT] is recommended instead for maximum addon compatibility.
*/
@JvmField
val PERMANENT: Set<Stat> = EnumSet.of(HP, ATTACK, DEFENCE, SPECIAL_ATTACK, SPECIAL_DEFENCE, SPEED)
/**
* All the stats with type of [Stat.Type.BATTLE_ONLY].
* Using [StatProvider.ofType] with type [Stat.Type.BATTLE_ONLY] is recommended instead for maximum addon compatibility.
*/
@JvmField
val BATTLE_ONLY: Set<Stat> = EnumSet.of(EVASION, ACCURACY)
/** Gets the [Stat] from the respective Showdown id. */
@JvmStatic
fun getStat(statKey: String) = when(statKey.lowercase()) {
"hp" -> HP
"atk", "attack" -> ATTACK // Hyper Cutter states the full stat name "Attack"
@@ -66,7 +62,6 @@ enum class Stats(override val identifier: ResourceLocation, override val display
}
/** Gets the severity lang key from the respective boost/unboost stage. */
@JvmStatic
fun getSeverity(stages: Int) = when(stages) {
0 -> "cap.single"
1 -> "slight"
@@ -30,7 +30,7 @@ open class Status(
/**
* A [Codec] for [Status].
*/
@JvmField
@JvmStatic
val CODEC: Codec<Status> = CodecUtils.createByIdentifierCodec(
Statuses::getStatus,
Status::name
@@ -25,23 +25,17 @@ import com.cobblemon.mod.common.util.server
interface CustomPokemonProperty {
companion object {
/** A list of all the registered [CustomPokemonPropertyType]s. */
@JvmField
val properties = mutableListOf<CustomPokemonPropertyType<*>>()
@JvmStatic
fun <T: CustomPokemonProperty> register(propertyType: CustomPokemonPropertyType<T>) {
properties.add(propertyType)
this.triggerSyncAttempt()
}
@JvmStatic
@JvmOverloads
fun <T : CustomPokemonProperty> register(name: String, needsLabel: Boolean = true, fromString: (String?) -> T?, examples: () -> Collection<String>) {
register(listOf(name), needsLabel, fromString, examples)
}
@JvmStatic
@JvmOverloads
fun <T : CustomPokemonProperty> register(aliases: Iterable<String>, needsLabel: Boolean = true, fromString: (String?) -> T?, examples: () -> Collection<String>) {
properties.add(
object : CustomPokemonPropertyType<T> {
@@ -54,7 +48,6 @@ interface CustomPokemonProperty {
this.triggerSyncAttempt()
}
@JvmStatic
fun unregister(property: CustomPokemonPropertyType<*>) {
properties.remove(property)
}
@@ -11,7 +11,6 @@ package com.cobblemon.mod.common.api.reactive
import com.cobblemon.mod.common.api.events.Cancelable
open class EventObservable<T> : SimpleObservable<T>() {
@JvmOverloads
inline fun post(vararg events: T, then: (T) -> Unit = {}) {
// Issuing generic-typed pass-throughs to varargs doesn't work
// properly unless the source is a vararg as well, complicated story.
@@ -59,12 +59,10 @@ interface Observable<T> {
companion object {
/** Creates a completed [Observable] with the given values. This [Observable] cannot receive new values. */
@JvmStatic
fun <T> just(vararg values: T): Observable<T> {
return SingularObservable<T>().also { it.emit(*values) }
}
@JvmStatic
fun <T> of(future: CompletableFuture<T>): Observable<T> {
val observable = SingularObservable<T>()
future.thenAccept { observable.emit(it) }
@@ -72,28 +70,20 @@ interface Observable<T> {
}
/** Gets a [TakeFirstTransform] */
@JvmStatic
fun <T> takeFirst(amount: Int = 1) = TakeFirstTransform<T>(amount)
/** Gets a [IgnoreFirstTransform] */
@JvmStatic
fun <T> ignoreFirst(amount: Int = 1) = IgnoreFirstTransform<T>(amount)
/** Gets a [FilterTransform] */
@JvmStatic
fun <T> filter(predicate: (T) -> Boolean) = FilterTransform(predicate)
/** Gets a [MapTransform] */
@JvmStatic
fun <T, O> map(mapping: (T) -> O) = MapTransform(mapping)
/** Gets a [EmitWhileTransform] */
@JvmStatic
fun <T> emitWhile(predicate: (T) -> Boolean) = EmitWhileTransform(predicate)
/** Gets a [StopAfterTransform] */
@JvmStatic
fun <T> stopAfter(predicate: (T) -> Boolean) = StopAfterTransform(predicate)
/** Gets a transform which will take values until the given predicate is met. */
@JvmStatic
fun <T> emitUntil(predicate: (T) -> Boolean) = EmitWhileTransform<T> { !predicate(it) }
/** Gets a transform which does not change the value but lets you access the value at this stage of the pipe. */
@JvmStatic
fun <T> tap(handler: (T) -> Unit) = map<T, T> { handler(it); return@map it }
}
}

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