forked from mirrors/cobblemon
Compare commits
100
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94978bff20 | ||
|
|
cccc71a64b | ||
|
|
23ce272813 | ||
|
|
e271613257 | ||
|
|
948ca61ef3 | ||
|
|
e60aca30ba | ||
|
|
fb5055c39e | ||
|
|
dfb5650121 | ||
|
|
8a0cbf28fe | ||
|
|
a6b9060d57 | ||
|
|
8e57995e44 | ||
|
|
1d8257808c | ||
|
|
e3582ccfb4 | ||
|
|
4c6822b1c6 | ||
|
|
2e6a4c7341 | ||
|
|
8edb5e1013 | ||
|
|
6fb139cbb9 | ||
|
|
c81c95142b | ||
|
|
afde822860 | ||
|
|
474c386535 | ||
|
|
71b9ae8dee | ||
|
|
b87b47d62a | ||
|
|
2bb85718d7 | ||
|
|
ee187d7b89 | ||
|
|
3532cac278 | ||
|
|
1447ab25b4 | ||
|
|
9a06ca78c6 | ||
|
|
f6ba70634b | ||
|
|
148fd04a93 | ||
|
|
17f60623ee | ||
|
|
c5ece27c11 | ||
|
|
296ccd1a76 | ||
|
|
82a4f71f24 | ||
|
|
08b58e2f78 | ||
|
|
62d2b8db2d | ||
|
|
3869f7ed93 | ||
|
|
c9c44872d6 | ||
|
|
cae53efedc | ||
|
|
5fac24cee8 | ||
|
|
1954dfec80 | ||
|
|
2eea2b64c2 | ||
|
|
a127a93be8 | ||
|
|
9b32f85817 | ||
|
|
ec139d2677 | ||
|
|
4327be0cf9 | ||
|
|
c25c832b31 | ||
|
|
eabaabc535 | ||
|
|
9acf97f5a0 | ||
|
|
24fc212c76 | ||
|
|
04f88bdd63 | ||
|
|
a4eb58aa57 | ||
|
|
6704d4e5ee | ||
|
|
c88087de29 | ||
|
|
86bb802140 | ||
|
|
6b644b384d | ||
|
|
c370af8914 | ||
|
|
1cd6d2bfc7 | ||
|
|
1edeae2a60 | ||
|
|
409f1056b9 | ||
|
|
d8c470db3d | ||
|
|
c642c4b84b | ||
|
|
0b80f7e547 | ||
|
|
d543f45607 | ||
|
|
2b4fdfd219 | ||
|
|
1a3b655d3f | ||
|
|
1f5f278970 | ||
|
|
0b4eb5239a | ||
|
|
118e8f6205 | ||
|
|
cf126c5906 | ||
|
|
645cf61911 | ||
|
|
87d5ede3dd | ||
|
|
203e5d89cd | ||
|
|
ce611cc61c | ||
|
|
f6ad7ff865 | ||
|
|
d69627a9c8 | ||
|
|
54e8763470 | ||
|
|
db34687df0 | ||
|
|
7f008d85ff | ||
|
|
06ebf51078 | ||
|
|
39c5bcd73c | ||
|
|
8f5f158b60 | ||
|
|
3bc1e35125 | ||
|
|
460bedddae | ||
|
|
8b64c315f3 | ||
|
|
7c824a2b72 | ||
|
|
f197ac5077 | ||
|
|
e0be669482 | ||
|
|
08ea21fff4 | ||
|
|
9dac604a93 | ||
|
|
8540a73885 | ||
|
|
25ce784a60 | ||
|
|
5358cccb62 | ||
|
|
698fa9dff9 | ||
|
|
a8949cf1f9 | ||
|
|
61db6334f9 | ||
|
|
46d278ca55 | ||
|
|
339038956d | ||
|
|
116a93d8cc | ||
|
|
acebc35d3f | ||
|
|
aee89f1c92 |
+42
-2
@@ -6,17 +6,35 @@
|
||||
- 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
|
||||
@@ -24,15 +42,37 @@
|
||||
- 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.
|
||||
- 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,7 +11,9 @@ 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;
|
||||
@@ -42,7 +44,21 @@ public abstract class BeeOccupantMixin {
|
||||
if (cir.getReturnValue() == null) {
|
||||
final BeehiveBlockEntity.Occupant occupant = (BeehiveBlockEntity.Occupant) (Object) this;
|
||||
CompoundTag compoundTag = occupant.entityData().copyTag();
|
||||
Entity entity = EntityType.loadEntityRecursive(compoundTag, level, (entityx) -> entityx);
|
||||
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);
|
||||
}
|
||||
|
||||
if (entity instanceof PokemonEntity pokemonEntity) {
|
||||
var state = level.getBlockState(pos);
|
||||
var newPos = Vec3.ZERO;
|
||||
|
||||
@@ -33,7 +33,7 @@ public class SimpleBlockFeatureMixin {
|
||||
if (!(blockState.getBlock() instanceof HeartyGrainsBlock)) {
|
||||
return;
|
||||
}
|
||||
if (blockState.getValue(HeartyGrainsBlock.Companion.getAGE()) <= HeartyGrainsBlock.AGE_AFTER_HARVEST) {
|
||||
if (blockState.getValue(HeartyGrainsBlock.AGE) <= 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,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.tags.PokemonFlagProperty
|
||||
import com.cobblemon.mod.common.pokemon.properties.LabelProperty
|
||||
import com.cobblemon.mod.common.pokemon.stat.CobblemonStatProvider
|
||||
import com.cobblemon.mod.common.starter.CobblemonStarterHandler
|
||||
import com.cobblemon.mod.common.util.*
|
||||
@@ -164,7 +164,7 @@ object Cobblemon {
|
||||
|
||||
val statistics: CobblemonStats = CobblemonStats
|
||||
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
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),
|
||||
@@ -201,6 +201,7 @@ object Cobblemon {
|
||||
implementation.registerEntityDataSerializers()
|
||||
implementation.registerCriteria()
|
||||
implementation.registerEntitySubPredicates()
|
||||
implementation.registerMobEffects()
|
||||
DispenserBehaviorRegistry.registerDispenserBehaviors()
|
||||
|
||||
DropEntry.register("command", CommandDropEntry::class.java)
|
||||
@@ -314,7 +315,7 @@ object Cobblemon {
|
||||
|
||||
CustomPokemonProperty.register(UncatchableProperty)
|
||||
CustomPokemonProperty.register(BattleCloneProperty)
|
||||
CustomPokemonProperty.register(PokemonFlagProperty)
|
||||
CustomPokemonProperty.register(LabelProperty)
|
||||
CustomPokemonProperty.register(HiddenAbilityPropertyType)
|
||||
CustomPokemonProperty.register(AspectPropertyType)
|
||||
CustomPokemonProperty.register(UnaspectPropertyType)
|
||||
@@ -568,4 +569,4 @@ object Cobblemon {
|
||||
this.implementation.registerCommandArgument(cobblemonResource("model_part"), ModelPartArgumentType::class, SingletonArgumentInfo.contextFree(ModelPartArgumentType::modelPart))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -117,6 +117,11 @@ interface CobblemonImplementation {
|
||||
|
||||
fun registerEntitySubPredicates()
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
fun registerMobEffects()
|
||||
|
||||
|
||||
/**
|
||||
* Add a feature to the current platform implementation.
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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())
|
||||
}
|
||||
+2
-1
@@ -23,6 +23,7 @@ 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),
|
||||
@@ -35,4 +36,4 @@ class AspectCriterion(
|
||||
val caughtAspects = context.getOrDefault(species, mutableSetOf())
|
||||
return this.aspects.all { it in caughtAspects }
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -25,6 +25,7 @@ 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),
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@ 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)
|
||||
@@ -34,4 +35,4 @@ class CastPokeRodCriterionCondition(
|
||||
override fun matches(player: ServerPlayer, context: CastPokeRodContext): Boolean {
|
||||
return (context.baitId == this.baitId.asIdentifierDefaultingNamespace() || this.baitId == "empty_bait")
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -31,6 +31,7 @@ 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),
|
||||
@@ -42,4 +43,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")
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -23,6 +23,7 @@ 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)
|
||||
|
||||
+1
@@ -26,6 +26,7 @@ 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),
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@ 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),
|
||||
@@ -42,4 +43,4 @@ class LevelUpCriterion(
|
||||
return level == context.level && evolutionCheck == evolved
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -24,6 +24,7 @@ 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)
|
||||
@@ -47,4 +48,4 @@ class PartyCheckCriterion(
|
||||
}
|
||||
return matches.containsAll(party) && matches.size == party.size
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -23,6 +23,7 @@ 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) }
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@ 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),
|
||||
@@ -35,4 +36,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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -25,6 +25,7 @@ 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),
|
||||
@@ -35,4 +36,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")
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -26,6 +26,7 @@ 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 },
|
||||
@@ -37,4 +38,4 @@ class ReelInPokemonCriterionCondition(
|
||||
return (context.species == this.species.asIdentifierDefaultingNamespace() || this.species == "any")
|
||||
&& (context.baitId == this.baitId.asIdentifierDefaultingNamespace() || this.baitId == "any" || this.baitId == "empty_bait")
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -28,6 +28,7 @@ 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),
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ import net.minecraft.resources.ResourceKey
|
||||
|
||||
object CobblemonEntitySubPredicates : PlatformRegistry<Registry<MapCodec<out EntitySubPredicate>>, ResourceKey<Registry<MapCodec<out EntitySubPredicate>>>, MapCodec<out EntitySubPredicate>>() {
|
||||
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val POKE_POBBER = this.create("poke_bobber", FishingBobberPredicate.CODEC)
|
||||
|
||||
override val registry: Registry<MapCodec<out EntitySubPredicate>> = BuiltInRegistries.ENTITY_SUB_PREDICATE_TYPE
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ class FishingBobberPredicate(val inOpenWater: Boolean) : EntitySubPredicate {
|
||||
return (entity as? PokeRodFishingBobberEntity)?.inOpenWater == this.inOpenWater
|
||||
}
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
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 {
|
||||
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val CODEC: Codec<Priority> = StringRepresentable.fromEnum(Priority::values)
|
||||
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ open class Ability internal constructor(var template: AbilityTemplate, forced: B
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
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 {
|
||||
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val CODEC: Codec<AbilityTemplate> = CodecUtils.createByStringCodec(
|
||||
Abilities::getOrDummy,
|
||||
AbilityTemplate::name
|
||||
|
||||
@@ -29,6 +29,7 @@ interface PotentialAbility {
|
||||
val type: PotentialAbilityType<*>
|
||||
fun isSatisfiedBy(aspects: Set<String>): Boolean
|
||||
companion object {
|
||||
@JvmField
|
||||
val types = mutableListOf<PotentialAbilityType<*>>()
|
||||
}
|
||||
}
|
||||
@@ -51,5 +52,4 @@ open class CommonAbility(override val template: AbilityTemplate) : PotentialAbil
|
||||
override val priority = Priority.LOWEST
|
||||
override val type = CommonAbilityType
|
||||
override fun isSatisfiedBy(aspects: Set<String>) = true
|
||||
}
|
||||
|
||||
}
|
||||
+2
-1
@@ -26,8 +26,9 @@ class AttackHostileMobsTaskConfig : SingleTaskConfig {
|
||||
): BehaviorControl<in LivingEntity>? {
|
||||
return AttackHostileMobsTask.create()
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC: Codec<AttackHostileMobsTaskConfig> = Codec.unit(AttackHostileMobsTaskConfig())
|
||||
}
|
||||
}
|
||||
@@ -99,6 +99,7 @@ enum class Apricorn : StringRepresentable {
|
||||
override fun getSerializedName() = this.name.lowercase()
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC: Codec<Apricorn> = StringRepresentable.fromValues(::values)
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -24,6 +24,7 @@ class AllBiomeCondition(val minGroveSize: Int, val maxGroveSize: Int) : BerrySpa
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val ID = cobblemonResource("all_biome")
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -26,6 +26,7 @@ class PreferredBiomeCondition(val minGroveSize: Int, val maxGroveSize: Int) : Be
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val ID = cobblemonResource("preferred_biome")
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -24,6 +24,7 @@ class SpecificBiomeCondition : BerrySpawnCondition {
|
||||
override fun getGroveSize(random: RandomSource) = random.nextIntBetweenInclusive(minGroveSize, maxGroveSize)
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val ID = cobblemonResource("specific_biome")
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ enum class Flavour(val colour: Int): StringRepresentable {
|
||||
|
||||
override fun getSerializedName() = name
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC = StringRepresentable.fromEnum<Flavour> { Flavour.entries.toTypedArray() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ 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,6 +38,7 @@ 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 },
|
||||
@@ -58,6 +59,7 @@ data class Seasoning(
|
||||
}
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val STREAM_CODEC: StreamCodec<ByteBuf, Seasoning> = ByteBufCodecs.fromCodec(CODEC)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -31,6 +31,7 @@ data class SerializableMobEffectInstance(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC: Codec<SerializableMobEffectInstance> = RecordCodecBuilder.create { builder ->
|
||||
builder.group(
|
||||
ResourceLocation.CODEC.fieldOf("effect").forGetter { it.effect },
|
||||
@@ -42,4 +43,4 @@ data class SerializableMobEffectInstance(
|
||||
).apply(builder, ::SerializableMobEffectInstance)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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,9 +26,11 @@ 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,
|
||||
@@ -44,6 +46,7 @@ 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 {
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val types = mutableMapOf<String, Class<out DialogueAction>>()
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ sealed interface DialogueFaceProvider {
|
||||
val isLeftSide: Boolean
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val types = mutableMapOf(
|
||||
"artificial" to ArtificialDialogueFaceProvider::class.java,
|
||||
"player" to PlayerDialogueFaceProvider::class.java,
|
||||
|
||||
@@ -58,4 +58,9 @@ object DialogueManager {
|
||||
DialogueClosedPacket(activeDialogue.dialogueId).sendToPlayer(playerEntity)
|
||||
activeDialogues.remove(playerEntity.uuid)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getDialogue(playerEntity: ServerPlayer): ActiveDialogue? {
|
||||
return activeDialogues[playerEntity.uuid]
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@ 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 = "",
|
||||
@@ -78,4 +79,4 @@ class DialoguePage(
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import com.cobblemon.mod.common.util.resolveBoolean
|
||||
*/
|
||||
interface DialoguePredicate {
|
||||
companion object {
|
||||
@JvmField
|
||||
val types = mutableMapOf<String, Class<out DialoguePredicate>>()
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import net.minecraft.network.chat.MutableComponent
|
||||
*/
|
||||
interface DialogueText {
|
||||
companion object {
|
||||
@JvmField
|
||||
val types = mutableMapOf<String, Class<out DialogueText>>(
|
||||
"expression" to ExpressionLikeDialogueText::class.java,
|
||||
)
|
||||
|
||||
@@ -26,7 +26,10 @@ 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,13 +63,16 @@ 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)
|
||||
@@ -100,4 +103,4 @@ interface MocKEffect : PhysicalEffect {
|
||||
|
||||
val exposedBall: PokeBall?
|
||||
get() = this.mock.pokeball?.let { PokeBalls.getPokeBall(it.asIdentifierDefaultingNamespace()) }
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -8,12 +8,10 @@
|
||||
|
||||
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
|
||||
|
||||
@@ -25,7 +23,8 @@ import com.cobblemon.mod.common.util.asArrayValue
|
||||
data class FormeChangeEvent(
|
||||
override val battle: PokemonBattle,
|
||||
val pokemon: BattlePokemon,
|
||||
val formeName: String
|
||||
val formeName: String,
|
||||
val pnx: String
|
||||
) : BattleEvent {
|
||||
val context = mutableMapOf(
|
||||
"battle" to battle.struct,
|
||||
@@ -33,6 +32,7 @@ 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)
|
||||
"forme" to StringValue(formeName),
|
||||
"pnx" to StringValue(pnx)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ 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 },
|
||||
@@ -47,6 +48,7 @@ class SpawnBait(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC = RecordCodecBuilder.create<SpawnBait> { instance ->
|
||||
instance.group(
|
||||
ITEM_REGISTRY_LIKE_CODEC.fieldOf("item").forGetter { it.item },
|
||||
@@ -54,6 +56,7 @@ class SpawnBait(
|
||||
).apply(instance, ::SpawnBait)
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val STREAM_CODEC = ByteBufCodecs.fromCodec(CODEC)
|
||||
}
|
||||
|
||||
@@ -96,6 +99,4 @@ class SpawnBait(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+11
@@ -9,6 +9,7 @@
|
||||
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
|
||||
@@ -29,6 +30,11 @@ 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")
|
||||
@@ -43,6 +49,11 @@ 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()
|
||||
|
||||
+19
-4
@@ -17,6 +17,7 @@ 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 net.minecraft.core.registries.Registries
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
@@ -143,11 +144,12 @@ class GiveItemEffect(val item: ResourceLocation, val amount: IntRange?) : Intera
|
||||
class PlaySoundEffect(
|
||||
val sound: ResourceLocation,
|
||||
val soundSource: SoundSource?,
|
||||
val playAround: Boolean = true,
|
||||
val distance: Double = 64.0,
|
||||
val volume: Float = 1.0F,
|
||||
val pitch: Float = 1.0F
|
||||
@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 {
|
||||
|
||||
override fun applyEffect(
|
||||
pokemon: PokemonEntity,
|
||||
player: ServerPlayer
|
||||
@@ -161,6 +163,7 @@ class PlaySoundEffect(
|
||||
volume,
|
||||
pitch
|
||||
)
|
||||
|
||||
if (playAround) {
|
||||
packet.sendToPlayersAround(pokemon.x, pokemon.y, pokemon.z, distance, pokemon.level().dimension())
|
||||
} else {
|
||||
@@ -168,6 +171,18 @@ class PlaySoundEffect(
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -223,6 +223,7 @@ 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.
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
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.
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val HIDDEN_ABILITY: AbilityChanger<HiddenAbility> = AbilityTypeChanger(HiddenAbilityType) { other -> other == CommonAbilityType || other == HiddenAbilityType }
|
||||
|
||||
}
|
||||
|
||||
@@ -35,10 +35,11 @@ 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 + args.mapIndexed { index, value -> "arg_${index + 1}" to value }.toMap()
|
||||
(params.environment.context?.map ?: emptyMap()) + args.mapIndexed { index, value -> "arg_${index + 1}" to value }.toMap()
|
||||
)
|
||||
val script = params.getString(0).asIdentifierDefaultingNamespace()
|
||||
// store the args in the
|
||||
@@ -324,13 +324,24 @@ 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) {
|
||||
runtime.resolve(expression)
|
||||
evaluate()
|
||||
}
|
||||
DoubleValue.ONE
|
||||
} else {
|
||||
runtime.resolve(expression)
|
||||
evaluate()
|
||||
}
|
||||
},
|
||||
"system_time_millis" to java.util.function.Function { _ ->
|
||||
@@ -340,19 +351,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))
|
||||
|
||||
@@ -112,7 +112,7 @@ class BenchedMoves : Iterable<BenchedMove> {
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val CODEC: Codec<BenchedMoves> = Codec.list(BenchedMove.CODEC)
|
||||
.xmap(
|
||||
{ moveList ->
|
||||
@@ -144,6 +144,7 @@ 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(
|
||||
@@ -152,6 +153,7 @@ 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(
|
||||
@@ -160,6 +162,7 @@ data class BenchedMove(val moveTemplate: MoveTemplate, val ppRaisedStages: Int)
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun loadFromBuffer(buffer: RegistryFriendlyByteBuf): BenchedMove {
|
||||
val name = buffer.readString()
|
||||
return BenchedMove(
|
||||
@@ -168,7 +171,7 @@ data class BenchedMove(val moveTemplate: MoveTemplate, val ppRaisedStages: Int)
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
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,12 +149,14 @@ 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)
|
||||
@@ -163,6 +165,7 @@ 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)
|
||||
@@ -171,7 +174,7 @@ open class Move(
|
||||
return template.create(currentPp, raisedPpStages)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
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
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val CODEC: Codec<MoveSet> = Codec.list(Move.CODEC, 0, MOVE_COUNT)
|
||||
.xmap(
|
||||
{ moveList ->
|
||||
|
||||
@@ -90,9 +90,10 @@ open class MoveTemplate(
|
||||
)
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun dummy(name: String) = Dummy(name)
|
||||
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val BY_STRING_CODEC: Codec<MoveTemplate> = CodecUtils.createByStringCodec(
|
||||
Moves::getByNameOrDummy,
|
||||
MoveTemplate::name
|
||||
@@ -157,4 +158,4 @@ open class MoveTemplate(
|
||||
}
|
||||
return this.elementalType
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -32,6 +32,7 @@ class ActionEffectTimeline(
|
||||
val condition: ExpressionLike = "true".asExpressionLike()
|
||||
) {
|
||||
companion object {
|
||||
@JvmField
|
||||
val NONE = ActionEffectTimeline()
|
||||
}
|
||||
|
||||
@@ -98,4 +99,4 @@ interface EntityProvider {
|
||||
// val sound: ResourceLocation? = null,
|
||||
// val animation: List<AnimationWithMoments> = listOf(),
|
||||
// val effects: List<ActionEffect> = listOf()
|
||||
//)
|
||||
//)
|
||||
+3
-1
@@ -21,8 +21,10 @@ 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
|
||||
}
|
||||
@@ -31,4 +33,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,6 +109,7 @@ 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,6 +25,7 @@ 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() },
|
||||
|
||||
+1
@@ -34,6 +34,7 @@ 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)
|
||||
}
|
||||
|
||||
+1
@@ -34,6 +34,7 @@ interface NPCVariationProvider {
|
||||
"random" to RandomNPCVariationProvider::class.java
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
fun register(type: String, clazz: Class<out NPCVariationProvider>) {
|
||||
types[type] = clazz
|
||||
}
|
||||
|
||||
+4
-1
@@ -23,8 +23,11 @@ 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)
|
||||
}
|
||||
|
||||
@@ -129,4 +132,4 @@ open class OrientationController(val entity: LivingEntity) {
|
||||
return@updateOrientation Matrix3f().set(resultQuat)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ enum class PermissionLevel(val numericalValue: Int) {
|
||||
ALL_COMMANDS(4);
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun byNumericValue(value: Int): PermissionLevel {
|
||||
return entries.first { it.numericalValue == value }
|
||||
}
|
||||
|
||||
+2
@@ -23,6 +23,8 @@ 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,6 +37,7 @@ 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,10 +26,11 @@ 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,6 +70,7 @@ class PokedexManager(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC = RecordCodecBuilder.create<PokedexManager> { instance ->
|
||||
instance.group(
|
||||
PrimitiveCodec.STRING.fieldOf("uuid").forGetter { it.uuid.toString() },
|
||||
|
||||
@@ -33,6 +33,7 @@ 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,7 +76,9 @@ 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,9 +34,12 @@ 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
|
||||
@@ -45,6 +48,7 @@ abstract class PokedexDef: ClientDataSynchronizer<PokedexDef> {
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getCodecById(id: ResourceLocation): MapCodec<out PokedexDef> {
|
||||
return when (id) {
|
||||
SimplePokedexDef.ID -> SimplePokedexDef.CODEC
|
||||
|
||||
@@ -64,7 +64,9 @@ 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 },
|
||||
@@ -78,6 +80,7 @@ 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 {
|
||||
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val CODEC: Codec<PokemonProperties> = Codec.STRING.xmap(
|
||||
{ parse(it) },
|
||||
{ it.asString() }
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val CUSTOM_PROPERTIES_CODEC: Codec<MutableList<CustomPokemonProperty>> = Codec.list(Codec.STRING)
|
||||
.xmap(
|
||||
{ string -> parse(string.joinToString(" ")).customProperties },
|
||||
@@ -96,6 +96,7 @@ open class PokemonProperties {
|
||||
)
|
||||
|
||||
@JvmOverloads
|
||||
@JvmStatic
|
||||
fun parse(string: String, delimiter: String = " ", assigner: String = "="): PokemonProperties {
|
||||
val props = PokemonProperties()
|
||||
props.originalString = string
|
||||
|
||||
@@ -22,10 +22,14 @@ 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)
|
||||
}
|
||||
|
||||
+1
@@ -21,6 +21,7 @@ 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,6 +38,7 @@ 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]
|
||||
|
||||
+2
-2
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+5
-5
@@ -25,15 +25,15 @@ object EvolutionProgressTypes {
|
||||
ResourceKey.createRegistryKey(cobblemonResource("evolution_progress")), Lifecycle.stable()
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val DAMAGE_TAKEN = this.registerType(DamageTakenEvolutionProgress.ID, EvolutionProgressType(DamageTakenEvolutionProgress.CODEC))
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val DEFEAT = this.registerType(DefeatEvolutionProgress.ID, EvolutionProgressType(DefeatEvolutionProgress.CODEC))
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val LAST_BATTLE_CRITICAL_HITS = this.registerType(LastBattleCriticalHitsEvolutionProgress.ID, EvolutionProgressType(LastBattleCriticalHitsEvolutionProgress.CODEC))
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val RECOIL = this.registerType(RecoilEvolutionProgress.ID, EvolutionProgressType(RecoilEvolutionProgress.CODEC))
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val USE_MOVE = this.registerType(UseMoveEvolutionProgress.ID, EvolutionProgressType(UseMoveEvolutionProgress.CODEC))
|
||||
|
||||
/**
|
||||
|
||||
+10
-8
@@ -80,7 +80,9 @@ open class ChoiceSpeciesFeatureProvider(
|
||||
|
||||
internal constructor(): this(emptyList())
|
||||
|
||||
override fun get(pokemon: Pokemon) = pokemon.getFeature<StringSpeciesFeature>(keys.first())
|
||||
override fun get(pokemon: Pokemon): StringSpeciesFeature? {
|
||||
return pokemon.features.filterIsInstance<StringSpeciesFeature>().find { it.name in keys }
|
||||
}
|
||||
|
||||
override fun invoke(pokemon: Pokemon): StringSpeciesFeature? {
|
||||
val existing = get(pokemon)
|
||||
@@ -101,15 +103,15 @@ open class ChoiceSpeciesFeatureProvider(
|
||||
}
|
||||
|
||||
override fun invoke(nbt: CompoundTag): StringSpeciesFeature? {
|
||||
return if (nbt.contains(keys.first())) {
|
||||
StringSpeciesFeature(keys.first(), "").also { it.loadFromNBT(nbt) }
|
||||
} else null
|
||||
val key = keys.find { nbt.contains(it) }
|
||||
if (key == null) return null
|
||||
return StringSpeciesFeature(key, "").also { it.loadFromNBT(nbt) }
|
||||
}
|
||||
|
||||
override fun invoke(json: JsonObject): StringSpeciesFeature? {
|
||||
return if (json.has(keys.first())) {
|
||||
StringSpeciesFeature(keys.first(), "").also { it.loadFromJSON(json) }
|
||||
} else null
|
||||
val key = keys.find { json.has(it) }
|
||||
if (key == null) return null
|
||||
return StringSpeciesFeature(key, "").also { it.loadFromJSON(json) }
|
||||
}
|
||||
|
||||
override fun fromString(value: String?): StringSpeciesFeature? {
|
||||
@@ -131,7 +133,7 @@ open class ChoiceSpeciesFeatureProvider(
|
||||
|
||||
override fun provide(properties: PokemonProperties): Set<String> {
|
||||
return if (isAspect) {
|
||||
val feature = properties.customProperties.filterIsInstance<StringSpeciesFeature>().find { it.name == keys.first() }
|
||||
val feature = properties.customProperties.filterIsInstance<StringSpeciesFeature>().find { it.name in keys }
|
||||
if (feature != null) {
|
||||
setOf(getAspect(feature))
|
||||
} else {
|
||||
|
||||
+23
-11
@@ -132,7 +132,9 @@ class FlagSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<FlagSpecie
|
||||
|
||||
constructor(vararg keys: String) : this(keys.toList())
|
||||
|
||||
override fun get(pokemon: Pokemon) = pokemon.getFeature<FlagSpeciesFeature>(keys.first())
|
||||
override fun get(pokemon: Pokemon): FlagSpeciesFeature? {
|
||||
return pokemon.features.filterIsInstance<FlagSpeciesFeature>().find { it.name in keys }
|
||||
}
|
||||
|
||||
override fun invoke(pokemon: Pokemon): FlagSpeciesFeature? {
|
||||
return get(pokemon)
|
||||
@@ -144,15 +146,15 @@ class FlagSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<FlagSpecie
|
||||
}
|
||||
|
||||
override fun invoke(nbt: CompoundTag): FlagSpeciesFeature? {
|
||||
return if (nbt.contains(keys.first())) {
|
||||
FlagSpeciesFeature(keys.first(), false).also { it.loadFromNBT(nbt) }
|
||||
} else null
|
||||
val key = keys.find { nbt.contains(it) }
|
||||
if (key == null) return null
|
||||
return FlagSpeciesFeature(key, false).also { it.loadFromNBT(nbt) }
|
||||
}
|
||||
|
||||
override fun invoke(json: JsonObject): FlagSpeciesFeature? {
|
||||
return if (json.has(keys.first())) {
|
||||
FlagSpeciesFeature(keys.first(), false).also { it.loadFromJSON(json) }
|
||||
} else null
|
||||
val key = keys.find { json.has(it) }
|
||||
if (key == null) return null
|
||||
return FlagSpeciesFeature(key, false).also { it.loadFromJSON(json) }
|
||||
}
|
||||
|
||||
override fun fromString(value: String?): FlagSpeciesFeature? {
|
||||
@@ -170,16 +172,26 @@ class FlagSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<FlagSpecie
|
||||
}
|
||||
|
||||
override fun provide(pokemon: Pokemon): Set<String> {
|
||||
return if (isAspect && pokemon.getFeature<FlagSpeciesFeature>(keys.first())?.enabled == true) {
|
||||
setOf(keys.first())
|
||||
return if (isAspect) {
|
||||
val feature = pokemon.features.filterIsInstance<FlagSpeciesFeature>().find { it.name in keys }
|
||||
if (feature != null && feature.enabled) {
|
||||
setOf(keys.first())
|
||||
} else {
|
||||
emptySet()
|
||||
}
|
||||
} else {
|
||||
emptySet()
|
||||
}
|
||||
}
|
||||
|
||||
override fun provide(properties: PokemonProperties): Set<String> {
|
||||
return if (isAspect && properties.customProperties.filterIsInstance<FlagSpeciesFeature>().find { it.name == keys.first() }?.enabled == true) {
|
||||
setOf(keys.first())
|
||||
return if (isAspect) {
|
||||
val feature = properties.customProperties.filterIsInstance<FlagSpeciesFeature>().find { it.name in keys }
|
||||
if (feature != null && feature.enabled) {
|
||||
setOf(keys.first())
|
||||
} else {
|
||||
emptySet()
|
||||
}
|
||||
} else {
|
||||
emptySet()
|
||||
}
|
||||
|
||||
+6
-10
@@ -142,19 +142,15 @@ class IntSpeciesFeatureProvider : SynchronizedSpeciesFeatureProvider<IntSpeciesF
|
||||
}
|
||||
|
||||
override fun invoke(nbt: CompoundTag): IntSpeciesFeature? {
|
||||
return if (nbt.contains(keys.first())) {
|
||||
IntSpeciesFeature(keys.first(), nbt.getInt(keys.first()))
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val key = keys.find { nbt.contains(it) }
|
||||
if (key == null) return null
|
||||
return IntSpeciesFeature(keys.first(), nbt.getInt(key));
|
||||
}
|
||||
|
||||
override fun invoke(json: JsonObject): IntSpeciesFeature? {
|
||||
return if (json.has(keys.first())) {
|
||||
IntSpeciesFeature(keys.first(), json.get(keys.first()).asInt)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val key = keys.find { json.has(it) }
|
||||
if (key == null) return null
|
||||
return IntSpeciesFeature(keys.first(), json.get(key).asInt)
|
||||
}
|
||||
|
||||
override fun get(pokemon: Pokemon) = pokemon.features.filterIsInstance<IntSpeciesFeature>().find { it.name in keys }
|
||||
|
||||
@@ -102,6 +102,12 @@ 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
|
||||
|
||||
+1
@@ -34,6 +34,7 @@ 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,6 +23,7 @@ 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
|
||||
@@ -40,12 +41,19 @@ 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(":")
|
||||
@@ -68,6 +76,7 @@ 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,6 +34,7 @@ fun interface LearnsetQuery {
|
||||
|| learnset.specialMoves.contains(move)
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val LEGAL = LearnsetQuery { move, learnset ->
|
||||
learnset.levelUpMoves.values.any { it.contains(move) }
|
||||
|| learnset.eggMoves.contains(move)
|
||||
@@ -43,22 +44,31 @@ 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) }
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ interface Stat {
|
||||
/**
|
||||
* A [Codec] for [Stat] without filtering the [Stat.Type].
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
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].
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
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].
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
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,21 +35,25 @@ 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"
|
||||
@@ -62,6 +66,7 @@ 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].
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmField
|
||||
val CODEC: Codec<Status> = CodecUtils.createByIdentifierCodec(
|
||||
Statuses::getStatus,
|
||||
Status::name
|
||||
|
||||
+7
@@ -25,17 +25,23 @@ 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> {
|
||||
@@ -48,6 +54,7 @@ interface CustomPokemonProperty {
|
||||
this.triggerSyncAttempt()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun unregister(property: CustomPokemonPropertyType<*>) {
|
||||
properties.remove(property)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ 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,10 +59,12 @@ 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) }
|
||||
@@ -70,20 +72,28 @@ 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 }
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,9 @@ enum class RidingStat(
|
||||
JUMP(Flavour.BITTER);
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getByName(name: String) = RidingStat.entries.firstOrNull { it.name.equals(name, ignoreCase = true) }
|
||||
@JvmStatic
|
||||
fun getByFlavour(flavour: Flavour) = RidingStat.entries.firstOrNull { it.flavour == flavour }
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ class BedrockParticle(
|
||||
|
||||
// kill plane maybe
|
||||
companion object {
|
||||
@JvmField
|
||||
val EXPRESSION_SET_CODEC = RecordCodecBuilder.create<ExpressionSet> { instance ->
|
||||
instance.group(
|
||||
EXPRESSION_CODEC.fieldOf("sizeX").forGetter { it.sizeX },
|
||||
@@ -83,6 +84,7 @@ class BedrockParticle(
|
||||
).apply(instance, ::ExpressionSet)
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val EVENT_SET_CODEC = RecordCodecBuilder.create<EventSet> { instance ->
|
||||
instance.group(
|
||||
SimpleEventTrigger.CODEC.listOf().fieldOf("creationEvents").forGetter { it.creationEvents },
|
||||
@@ -91,6 +93,7 @@ class BedrockParticle(
|
||||
).apply(instance, ::EventSet)
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val CODEC: Codec<BedrockParticle> = RecordCodecBuilder.create { instance ->
|
||||
instance.group(
|
||||
ResourceLocation.CODEC.fieldOf("texture").forGetter { it.texture },
|
||||
|
||||
@@ -36,6 +36,7 @@ class BedrockParticleOptions(
|
||||
var events: MutableMap<String, ParticleEvent> = mutableMapOf()
|
||||
) {
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC: Codec<BedrockParticleOptions> = RecordCodecBuilder.create { instance ->
|
||||
instance.group(
|
||||
ResourceLocation.CODEC.fieldOf("id").forGetter { it.id },
|
||||
|
||||
+1
@@ -39,6 +39,7 @@ class BedrockParticleEmitter(
|
||||
var loopingTravelDistanceEvents: MutableList<LoopingTravelDistanceEventTrigger> = mutableListOf()
|
||||
) {
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC: Codec<BedrockParticleEmitter> = RecordCodecBuilder.create { instance ->
|
||||
instance.group(
|
||||
EXPRESSION_CODEC.listOf().fieldOf("startExpressions").forGetter { it.startExpressions },
|
||||
|
||||
@@ -20,6 +20,7 @@ class EmitterSpace(
|
||||
var scaling: ScalingMode = ScalingMode.WORLD
|
||||
) {
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC: Codec<EmitterSpace> = RecordCodecBuilder.create { instance ->
|
||||
instance.group(
|
||||
Codec.STRING.optionalFieldOfWithDefault("scaling", "world").forGetter { it.scaling.toString() }
|
||||
|
||||
@@ -66,6 +66,7 @@ class LinearMoLangCurve(
|
||||
var nodes: List<Double> = emptyList()
|
||||
) : MoLangCurve {
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC: Codec<LinearMoLangCurve> = RecordCodecBuilder.create { instance ->
|
||||
instance.group(
|
||||
PrimitiveCodec.STRING.fieldOf("type").forGetter { it.type.name },
|
||||
@@ -127,6 +128,7 @@ class CatmullRomMoLangCurve(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC: Codec<CatmullRomMoLangCurve> = RecordCodecBuilder.create { instance ->
|
||||
instance.group(
|
||||
PrimitiveCodec.STRING.fieldOf("type").forGetter { it.type.name },
|
||||
@@ -202,6 +204,7 @@ class BezierChainMoLangCurve(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC = RecordCodecBuilder.create<BezierChainNode> { instance ->
|
||||
instance.group(
|
||||
PrimitiveCodec.DOUBLE.fieldOf("value").forGetter { it.value },
|
||||
@@ -230,6 +233,7 @@ class BezierChainMoLangCurve(
|
||||
class BezierChainPointData(val time: Double, val value: Double, val slope: Double)
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC: Codec<BezierChainMoLangCurve> = RecordCodecBuilder.create { instance ->
|
||||
instance.group(
|
||||
PrimitiveCodec.STRING.fieldOf("type").forGetter { it.type.name },
|
||||
@@ -280,6 +284,7 @@ class BezierMoLangCurve(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val CODEC: Codec<BezierMoLangCurve> = RecordCodecBuilder.create { instance ->
|
||||
instance.group(
|
||||
PrimitiveCodec.STRING.fieldOf("type").forGetter { it.type.name },
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user