Compare commits

..
1 Commits
Author SHA1 Message Date
Paul 396ab13164 1.9 in gradle properties 2026-09-06 20:01:10 +10:00
157 changed files with 3764 additions and 11150 deletions
+18 -34
View File
@@ -1,41 +1,25 @@
# Changelog
## [1.8.1 (September 13th, 2026)](#1-8-1)
## [1.x.x (MONTH Xth, 2026)](#1-x-x)
### Additions
### New rideable Pokémon
### Pokémon Added
### Model updates for the following Pokémon
### Animation updates for the following Pokémon
- Flapple, Appletun, Dipplin, Hydrapple (placeholder animations only).
### Changes
### Fixes
- Fixed a potential world generation stall caused by Type Gem clusters.
- Fixed Pokémon on shoulders not animating if they are visibly holding a held item.
- Fixed NPCs getting their own TM progress file.
- Fixed odd NeoForge crash due to a dependency being outdated. It will now correctly flag the dependency for being outdated.
- Fixed the TM Machine refusing move selections that the `unlockAllMoveDexMovesByDefault` config had made visible, leaving the move slot blank and the craft button unresponsive.
- Fixed the Beast Ball not applying its 0.1× penalty to Pokémon that are not Ultra Beasts.
- Fixed the Moon Ball reading the world's total elapsed time instead of the time of day, so its bonus applied during the day instead.
- Fixed the Love Ball never awarding its 2.5× opposite gender bonus, and matching species by display name instead of identifier.
- Fixed the Timer Ball being weaker than a regular Poké Ball on early turns and only reaching 4× on turn 14 instead of turn 10.
- Fixed the Luxury Ball only doubling Friendship gains of 1, leaving level up and berry gains unaffected.
- Fixed Rufflet, Braviary, and Hisuian Braviary flooding logs with errors about missing sound events.
- Fixed Pokémon property typos in Pangoro and Dedenne herd spawn files.
- Fixed unintentional watermelon cosmetic for Hisuian Electrode.
- Fixed Blastoise having an unintentional passenger seat.
- Fixed form typo in Rockruff-Dusk spawn, preventing it from being able to spawn.
- Fixed the `stat_compare` and `stat_equal` evolution requirements crashing the game when given `special_attack` or `special_defence`, and made them treat any non-permanent stat as a failed requirement instead of crashing.
- Fixed Rowap and Jacoba berries not correctly altering Pokémon sizes when used as bait.
- Fixed Ampharos' eyes not emitting particles.
- Fixed Alolan Raticate's cry not playing.
- Fixed several incorrect light-based spawning conditions for ghosts and bugs.
- Removed unused, placeholder habitat pools.
- Fixed Mantyke, Mantine, and Quaxly getting stuck in a recoil 'expression' during battles due to having an expression assigned as a recoil animation.
- Fixed Lucario's aura particles not emitting.
- Fixed Lycanroc's head movement.
- Added head movement to Archaludon.
- Fixed Duraludon line not having their sleep animations.
- Fixed Diglett line not having their faint animations.
- Fixed Kingambit moving its legs while walking.
### Developer
### Molang & Datapacks
### Particles
### Localization
- Updated translations for:
- Brazilian Portuguese
- Simplified Chinese
- Japanese
- Updated translations for:
@@ -21,8 +21,7 @@ import com.cobblemon.mod.common.pokemon.Pokemon
*/
data class FriendshipUpdatedEvent(
val pokemon: Pokemon,
val newFriendshipInitial: Int,
val earned: Boolean = false
val newFriendshipInitial: Int
) {
var newFriendship: Int = newFriendshipInitial
set(value) {
@@ -83,6 +83,12 @@ import net.minecraft.world.level.Level
import net.minecraft.world.level.biome.Biome
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.dimension.DimensionType
import net.minecraft.world.level.levelgen.Heightmap
import net.minecraft.world.level.pathfinder.PathType
import net.minecraft.world.level.storage.loot.LootParams
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
import net.minecraft.world.phys.AABB
import net.minecraft.world.phys.Vec3
import java.util.function.Function
@@ -93,31 +99,25 @@ import java.util.function.Function
* @since October 2nd, 2023
*/
object MoLangFunctions {
fun ItemStack.asMoLangValue(registryAccess: RegistryAccess) =
ObjectValue(this)
.addStandardFunctions()
.addFunctions(ItemStackMoLangFunctions.attach(Pair(this, registryAccess)))
fun ItemStack.asMoLangValue(registryAccess: RegistryAccess) = ObjectValue(this)
.addStandardFunctions()
.addFunctions(ItemStackMoLangFunctions.attach(Pair(this, registryAccess)))
fun Holder<Biome>.asBiomeMoLangValue() =
asMoLangValue(Registries.BIOME)
.addFunctions(BiomeMoLangFunctions.attach(this))
fun Holder<Biome>.asBiomeMoLangValue() = asMoLangValue(Registries.BIOME)
.addFunctions(BiomeMoLangFunctions.attach(this))
fun Holder<Level>.asWorldMoLangValue() =
asMoLangValue(Registries.DIMENSION)
.addFunctions(WorldMoLangFunctions.attach(this))
fun Holder<Level>.asWorldMoLangValue() = asMoLangValue(Registries.DIMENSION)
.addFunctions(WorldMoLangFunctions.attach(this))
fun Holder<Block>.asBlockMoLangValue() =
asMoLangValue(Registries.BLOCK)
.addFunctions(BlockMoLangFunctions.attach(this))
fun Holder<Block>.asBlockMoLangValue() = asMoLangValue(Registries.BLOCK)
.addFunctions(BlockMoLangFunctions.attach(this))
fun MinecraftServer.asMoLangValue() =
ObjectValue(this)
.addStandardFunctions()
.addFunctions(ServerMoLangFunctions.attach(this))
fun MinecraftServer.asMoLangValue() = ObjectValue(this)
.addStandardFunctions()
.addFunctions(ServerMoLangFunctions.attach(this))
fun Holder<DimensionType>.asDimensionTypeMoLangValue() =
asMoLangValue(Registries.DIMENSION_TYPE)
.addFunctions(DimensionTypeMoLangFunctions.attach(this))
fun Holder<DimensionType>.asDimensionTypeMoLangValue() = asMoLangValue(Registries.DIMENSION_TYPE)
.addFunctions(DimensionTypeMoLangFunctions.attach(this))
fun Player.asMoLangValue(): ObjectValue<Player> {
if (this is ServerPlayer && uuid in Cobblemon.serverPlayerStructs) {
@@ -129,11 +129,10 @@ object MoLangFunctions {
}
}
val value =
ObjectValue(
obj = this,
stringify = { it.effectiveName().string },
)
val value = ObjectValue(
obj = this,
stringify = { it.effectiveName().string }
)
value.addFunctions(EntityMoLangFunctions.attach(this))
value.addFunctions(LivingEntityMoLangFunctions.attach(this))
@@ -154,63 +153,57 @@ object MoLangFunctions {
}
fun PartyStore.asMoLangValue(): ObjectValue<PartyStore> {
val value =
ObjectValue(
obj = this,
stringify = { it.toString() },
)
val value = ObjectValue(
obj = this,
stringify = { it.toString() }
)
value.addFunctions(PokemonStoreMoLangFunctions.attach(this))
value.addFunctions(PartyMoLangFunctions.attach(this))
return value
}
fun DropEntry.asMoLangValue(): ObjectValue<DropEntry> {
val value =
ObjectValue(
obj = this,
stringify = { it.toString() },
)
val value = ObjectValue(
obj = this,
stringify = { it.toString() }
)
value.addFunctions(DropEntryMoLangFunctions.attach(this))
return value
}
fun PokemonProperties.asMoLangValue(): ObjectValue<PokemonProperties> {
val value =
ObjectValue(
obj = this,
stringify = { it.asString() },
)
val value = ObjectValue(
obj = this,
stringify = { it.asString() }
)
value.addFunctions(PokemonPropertiesMoLangFunctions.attach(this))
return value
}
fun Evolution.asMoLangValue(): ObjectValue<Evolution> {
val value =
ObjectValue(
obj = this,
stringify = { it.toString() },
)
val value = ObjectValue(
obj = this,
stringify = { it.toString() }
)
value.addFunctions(EvolutionMoLangFunctions.attach(this))
return value
}
fun PCStore.asMoLangValue(): ObjectValue<PCStore> {
val value =
ObjectValue(
obj = this,
stringify = { it.toString() },
)
val value = ObjectValue(
obj = this,
stringify = { it.toString() }
)
value.addFunctions(PokemonStoreMoLangFunctions.attach(this))
value.addFunctions(PCMoLangFunctions.attach(this))
return value
}
fun NPCEntity.asMoLangValue(): ObjectValue<NPCEntity> {
val value =
ObjectValue(
obj = this,
stringify = { it.name.string },
)
val value = ObjectValue(
obj = this,
stringify = { it.name.string }
)
value.addFunctions(EntityMoLangFunctions.attach(this))
value.addFunctions(LivingEntityMoLangFunctions.attach(this))
value.addFunctions(NPCMoLangFunctions.attach(this))
@@ -218,11 +211,10 @@ object MoLangFunctions {
}
fun PokemonEntity.asMoLangValue(): ObjectValue<PokemonEntity> {
val value =
ObjectValue(
obj = this,
stringify = { it.pokemon.uuid.toString() },
)
val value = ObjectValue(
obj = this,
stringify = { it.pokemon.uuid.toString() }
)
value.addFunctions(EntityMoLangFunctions.attach(this))
value.addFunctions(LivingEntityMoLangFunctions.attach(this))
@@ -233,40 +225,36 @@ object MoLangFunctions {
}
fun PokemonBattle.asMoLangValue(): ObjectValue<PokemonBattle> {
val value =
ObjectValue(
obj = this,
stringify = { it.battleId.toString() },
)
val value = ObjectValue(
obj = this,
stringify = { it.battleId.toString() }
)
value.addFunctions(BattleMoLangFunctions.attach(this))
return value
}
fun BattleActor.asMoLangValue(): ObjectValue<BattleActor> {
val value =
ObjectValue(
obj = this,
stringify = { it.toString() },
)
val value = ObjectValue(
obj = this,
stringify = { it.toString() }
)
value.addFunctions(BattleActorMoLangFunctions.attach(this))
return value
}
fun SpawnablePosition.asMoLangValue(): ObjectValue<SpawnablePosition> {
val value =
ObjectValue(
obj = this,
stringify = { it.toString() },
)
val value = ObjectValue(
obj = this,
stringify = { it.toString() }
)
value.addFunctions(SpawnablePositionMoLangFunctions.attach(this))
return value
}
fun Vec3.asMoLangValue(): ObjectValue<Vec3> {
val value =
ObjectValue(
obj = this,
)
val value = ObjectValue(
obj = this
)
value.addFunction("x") { this.x }
value.addFunction("y") { this.y }
value.addFunction("z") { this.z }
@@ -277,66 +265,45 @@ object MoLangFunctions {
/**
* Different functions exist depending on the entity type, this tries to make the struct that's most specific to the type.
*/
fun Entity.asMostSpecificMoLangValue(): ObjectValue<out Entity> =
when (this) {
is Player -> {
asMoLangValue()
fun Entity.asMostSpecificMoLangValue(): ObjectValue<out Entity> {
return when (this) {
is Player -> asMoLangValue()
is PokemonEntity -> struct
is NPCEntity -> struct
is ItemEntity -> ObjectValue(this).also { item ->
item.addStandardFunctions()
item.addFunctions(EntityMoLangFunctions.attach(this))
item.addFunctions(ItemStackMoLangFunctions.attach(Pair(this.item, this.registryAccess())))
}
is PokemonEntity -> {
struct
}
is NPCEntity -> {
struct
}
is ItemEntity -> {
ObjectValue(this).also { item ->
item.addStandardFunctions()
item.addFunctions(EntityMoLangFunctions.attach(this))
item.addFunctions(ItemStackMoLangFunctions.attach(Pair(this.item, this.registryAccess())))
}
}
else -> {
ObjectValue(this).also { objectValue ->
objectValue.addStandardFunctions()
objectValue.addFunctions(EntityMoLangFunctions.attach(this))
if (this is LivingEntity) {
objectValue.addFunctions(LivingEntityMoLangFunctions.attach(this))
}
else -> ObjectValue(this).also { objectValue ->
objectValue.addStandardFunctions()
objectValue.addFunctions(EntityMoLangFunctions.attach(this))
if (this is LivingEntity) {
objectValue.addFunctions(LivingEntityMoLangFunctions.attach(this))
}
}
}
}
fun <T> Holder<T>.asMoLangValue(key: ResourceKey<Registry<T>>): ObjectValue<Holder<T>> {
val value =
ObjectValue(
obj = this,
stringify = {
it
.unwrapKey()
.get()
.location()
.toString()
},
)
value.functions["is_in"] =
Function put@{ params: MoParams ->
val tag = TagKey.create(key, ResourceLocation.parse(params.getString(0).replace("#", "")))
return@put DoubleValue(if (value.obj.`is`(tag)) 1.0 else 0.0)
}
value.functions["is_of"] =
Function put@{ params: MoParams ->
val identifier = ResourceLocation.parse(params.getString(0))
return@put DoubleValue(if (value.obj.`is`(identifier)) 1.0 else 0.0)
}
val value = ObjectValue(
obj = this,
stringify = { it.unwrapKey().get().location().toString() }
)
value.functions["is_in"] = Function put@{ params: MoParams ->
val tag = TagKey.create(key, ResourceLocation.parse(params.getString(0).replace("#", "")))
return@put DoubleValue(if (value.obj.`is`(tag)) 1.0 else 0.0)
}
value.functions["is_of"] = Function put@{ params: MoParams ->
val identifier = ResourceLocation.parse(params.getString(0))
return@put DoubleValue(if (value.obj.`is`(identifier)) 1.0 else 0.0)
}
return value
}
fun QueryStruct.addStandardFunctions(): QueryStruct {
addFunctions(GeneralMoLangFunctions.functions)
addFunctions(GeneralMoLangFunctions.holder)
return this
}
@@ -403,17 +370,23 @@ object MoLangFunctions {
return this
}
fun moLangFunctionMap(vararg functions: Pair<String, (MoParams) -> MoValue>): Map<String, (MoParams) -> MoValue> = functions.toMap()
fun moLangFunctionMap(
vararg functions: Pair<String, (MoParams) -> MoValue>
): Map<String, (MoParams) -> MoValue> {
return functions.toMap()
}
fun queryStructOf(vararg functions: Pair<String, (MoParams) -> MoValue>): QueryStruct =
QueryStruct(
fun queryStructOf(
vararg functions: Pair<String, (MoParams) -> MoValue>
): QueryStruct {
return QueryStruct(
hashMapOf<String, Function<MoParams, Any>>(
*functions
.map { (name, func) ->
name to Function<MoParams, Any> { params -> func(params) }
}.toTypedArray(),
),
*functions.map { (name, func) ->
name to Function<MoParams, Any> { params -> func(params) }
}.toTypedArray()
)
)
}
fun MoLangRuntime.setup(): MoLangRuntime {
environment.query.addStandardFunctions()
@@ -422,14 +395,8 @@ object MoLangFunctions {
fun writeMoValueToNBT(value: MoValue): Tag? {
return when (value) {
is DoubleValue -> {
DoubleTag.valueOf(value.value)
}
is StringValue -> {
StringTag.valueOf(value.value)
}
is DoubleValue -> DoubleTag.valueOf(value.value)
is StringValue -> StringTag.valueOf(value.value)
is ArrayStruct -> {
val list = value.map.values
val nbtList = ListTag()
@@ -446,22 +413,14 @@ object MoLangFunctions {
nbt
}
else -> {
null
}
else -> null
}
}
fun readMoValueFromNBT(nbt: Tag): MoValue =
when (nbt) {
is DoubleTag -> {
DoubleValue(nbt.asDouble)
}
is StringTag -> {
StringValue(nbt.asString)
}
fun readMoValueFromNBT(nbt: Tag): MoValue {
return when (nbt) {
is DoubleTag -> DoubleValue(nbt.asDouble)
is StringTag -> StringValue(nbt.asString)
is ListTag -> {
val array = ArrayStruct(hashMapOf())
var index = 0
@@ -482,12 +441,11 @@ object MoLangFunctions {
variable
}
else -> {
VariableStruct()
}
else -> VariableStruct()
}
}
}
// TODO: this one is unused. Should we move it to [MoLangFunctions] object?
fun Either<ResourceLocation, ExpressionLike>.runScript(runtime: MoLangRuntime) =
map({ CobblemonScripts.run(it, runtime) }, { it.resolve(runtime) })
map({ CobblemonScripts.run(it, runtime) }, { it.resolve(runtime) })
@@ -17,29 +17,30 @@ import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
import com.cobblemon.mod.common.battles.actor.PokemonBattleActor
import com.cobblemon.mod.common.entity.npc.NPCBattleActor
object BattleActorMoLangFunctions : AbstractMoLangFunctionHolder<BattleActor>() {
override fun BattleActor.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val actor = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["is_npc"] = { DoubleValue(actor.type == ActorType.NPC) }
functions["is_player"] = { DoubleValue(actor.type == ActorType.PLAYER) }
functions["is_wild"] = { DoubleValue(actor.type == ActorType.WILD) }
val map = mutableMapOf<String, (MoParams) -> Any>(
"is_npc" to { DoubleValue(actor.type == ActorType.NPC) },
"is_player" to { DoubleValue(actor.type == ActorType.PLAYER) },
"is_wild" to { DoubleValue(actor.type == ActorType.WILD) }
)
when (actor) {
is NPCBattleActor -> {
functions["npc"] = { actor.entity.struct }
map["npc"] = { actor.entity.struct }
}
is PlayerBattleActor -> {
functions["player"] = { actor.entity?.asMoLangValue() ?: DoubleValue.ZERO }
map["player"] = { actor.entity?.asMoLangValue() ?: DoubleValue.ZERO }
}
is PokemonBattleActor -> {
functions["pokemon"] = { actor.entity?.asMoLangValue() ?: DoubleValue.ZERO }
map["pokemon"] = { actor.entity?.asMoLangValue() ?: DoubleValue.ZERO }
}
}
return functions
return map
}
}
@@ -16,19 +16,17 @@ import com.cobblemon.mod.common.util.getStringOrNull
object BattleMessageMoLangFunctions : AbstractMoLangFunctionHolder<BattleMessage>() {
override fun BattleMessage.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val battleMessage = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["has_argument_at"] = { params ->
val index = params.getInt(0)
val value = params.getStringOrNull(1) ?: ""
DoubleValue(value == battleMessage.argumentAt(index))
}
functions["has_argument"] = { params ->
val argumentName = params.getString(0)
val value = params.getStringOrNull(1) ?: ""
DoubleValue(value == battleMessage.optionalArgument(argumentName))
}
return functions
return mutableMapOf(
"has_argument_at" to { params ->
val index = params.getInt(0)
val value = params.getStringOrNull(1) ?: ""
DoubleValue(value == battleMessage.argumentAt(index))
},
"has_argument" to { params ->
val argumentName = params.getString(0)
val value = params.getStringOrNull(1) ?: ""
DoubleValue(value == battleMessage.optionalArgument(argumentName))
}
)
}
}
@@ -18,22 +18,20 @@ import java.util.*
object BattleMoLangFunctions : AbstractMoLangFunctionHolder<PokemonBattle>() {
override fun PokemonBattle.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val battle = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["environment"] = { battle.runtime.environment }
functions["battle_id"] = { StringValue(battle.battleId.toString()) }
functions["battle_type"] = { StringValue(battle.format.toString()) }
functions["is_pvn"] = { DoubleValue(battle.isPvN) }
functions["is_pvp"] = { DoubleValue(battle.isPvP) }
functions["is_pvw"] = { DoubleValue(battle.isPvW) }
functions["stop"] = { battle.stop() }
functions["actors"] = { battle.actors.toList().asArrayValue { it.struct } }
functions["get_actor"] = getActor@{ params ->
val uuid = UUID.fromString(params.getString(0))
val actor = battle.actors.find { it.uuid == uuid } ?: return@getActor DoubleValue.ZERO
actor.struct
}
return functions
return mutableMapOf(
"environment" to { battle.runtime.environment },
"battle_id" to { StringValue(battle.battleId.toString()) },
"battle_type" to { StringValue(battle.format.toString()) },
"is_pvn" to { DoubleValue(battle.isPvN) },
"is_pvp" to { DoubleValue(battle.isPvP) },
"is_pvw" to { DoubleValue(battle.isPvW) },
"stop" to { battle.stop() },
"actors" to { battle.actors.toList().asArrayValue { it.struct } },
"get_actor" to getActor@{ params ->
val uuid = UUID.fromString(params.getString(0))
val actor = battle.actors.find { it.uuid == uuid } ?: return@getActor DoubleValue.ZERO
actor.struct
}
)
}
}
@@ -12,11 +12,8 @@ import com.bedrockk.molang.runtime.MoParams
import net.minecraft.core.Holder
import net.minecraft.world.level.biome.Biome
object BiomeMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Biome>>() {
object BiomeMoLangFunctions: AbstractMoLangFunctionHolder<Holder<Biome>>() {
override fun Holder<Biome>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val biome = this
val functions = hashMapOf<String, (MoParams) -> Any>()
return functions
return mutableMapOf()
}
}
@@ -12,11 +12,8 @@ import com.bedrockk.molang.runtime.MoParams
import net.minecraft.core.Holder
import net.minecraft.world.level.block.Block
object BlockMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Block>>() {
object BlockMoLangFunctions: AbstractMoLangFunctionHolder<Holder<Block>>() {
override fun Holder<Block>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val block = this
val functions = hashMapOf<String, (MoParams) -> Any>()
return functions
return mutableMapOf()
}
}
@@ -14,9 +14,6 @@ import net.minecraft.world.level.dimension.DimensionType
object DimensionTypeMoLangFunctions : AbstractMoLangFunctionHolder<Holder<DimensionType>>() {
override fun Holder<DimensionType>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val dimension = this
val functions = hashMapOf<String, (MoParams) -> Any>()
return functions
return mutableMapOf()
}
}
@@ -18,16 +18,15 @@ import com.cobblemon.mod.common.util.getOrNull
object DropEntryMoLangFunctions : AbstractMoLangFunctionHolder<DropEntry>() {
override fun DropEntry.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val drop = this
val functions = hashMapOf<String, (MoParams) -> Any>()
val map = mutableMapOf<String, (MoParams) -> Any>()
functions["percentage"] = { DoubleValue(drop.percentage.toDouble()) }
functions["quantity"] = { DoubleValue(drop.quantity.toDouble()) }
functions["max_selectable_times"] = { DoubleValue(drop.maxSelectableTimes.toDouble()) }
functions["can_drop"] = { params ->
map["percentage"] = { DoubleValue(drop.percentage.toDouble()) }
map["quantity"] = { DoubleValue(drop.quantity.toDouble()) }
map["max_selectable_times"] = { DoubleValue(drop.maxSelectableTimes.toDouble()) }
map["can_drop"] = { params ->
val pokemon = params.getOrNull<ObjectValue<Pokemon>>(0)?.obj
DoubleValue(if (drop.canDrop(pokemon)) 1.0 else 0.0)
}
return functions
return map
}
}
@@ -56,300 +56,258 @@ import kotlin.math.sqrt
object EntityMoLangFunctions : AbstractMoLangFunctionHolder<Entity>() {
override fun Entity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val entity = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["uuid"] = { StringValue(entity.uuid.toString()) }
functions["name"] = { StringValue(entity.effectiveName().string) }
functions["yaw"] = { DoubleValue(entity.yRot.toDouble()) }
functions["pitch"] = { DoubleValue(entity.xRot.toDouble()) }
functions["x"] = { DoubleValue(entity.x) }
functions["y"] = { DoubleValue(entity.y) }
functions["z"] = { DoubleValue(entity.z) }
functions["velocity_x"] = { DoubleValue(entity.deltaMovement.x) }
functions["velocity_y"] = { DoubleValue(entity.deltaMovement.y) }
functions["velocity_z"] = { DoubleValue(entity.deltaMovement.z) }
functions["width"] = { DoubleValue(entity.boundingBox.xsize) }
functions["height"] = { DoubleValue(entity.boundingBox.ysize) }
functions["this_size"] = { DoubleValue(entity.boundingBox.run { if (xsize > ysize) xsize else ysize }) }
functions["this_width"] = { DoubleValue(entity.boundingBox.xsize) }
functions["this_height"] = { DoubleValue(entity.boundingBox.ysize) }
functions["id_modulo"] = { params -> DoubleValue(entity.uuid.hashCode() % params.getDouble(0)) }
functions["horizontal_velocity"] = { DoubleValue(entity.deltaMovement.horizontalDistance()) }
functions["vertical_velocity"] = { DoubleValue(entity.deltaMovement.y) }
functions["is_on_ground"] = { DoubleValue(entity.onGround()) }
functions["world"] = {
entity
.level()
.worldRegistry
.wrapAsHolder(entity.level())
.asWorldMoLangValue()
}
functions["biome"] = { entity.level().getBiome(entity.blockPosition()).asBiomeMoLangValue() }
functions["is_passenger"] = { DoubleValue(entity.isPassenger) }
functions["discard"] = { entity.discard() }
functions["is_sneaking"] = { DoubleValue(entity.isShiftKeyDown) }
functions["is_sprinting"] = { DoubleValue(entity.isSprinting) }
functions["is_in_water"] = { DoubleValue(entity.isUnderWater) }
functions["is_in_rain"] = { DoubleValue(entity.isInWaterOrRain && !entity.isInWater) }
functions["is_touching_water_or_rain"] = { DoubleValue(entity.isInWaterRainOrBubble) }
functions["is_touching_water"] = { DoubleValue(entity.isInWater) }
functions["is_underwater"] = { DoubleValue(entity.getIsSubmerged()) }
functions["is_in_lava"] = { DoubleValue(entity.isInLava) }
functions["is_on_fire"] = { DoubleValue(entity.isOnFire) }
functions["is_invisible"] = { DoubleValue(entity.isInvisible) }
functions["is_riding"] = { DoubleValue(entity.isPassenger) }
functions["set_name"] = { params ->
val name = params.getString(0)
entity.customName = name.text()
DoubleValue.ONE
}
functions["damage"] = { params ->
val amount = params.getDouble(0)
val source =
DamageSource(
entity
.level()
.registryAccess()
.registryOrThrow(Registries.DAMAGE_TYPE)
.getHolder(DamageTypes.GENERIC)
.get(),
val thisEntity = this
val map = mutableMapOf<String, (MoParams) -> Any>(
"uuid" to { StringValue(thisEntity.uuid.toString()) },
"name" to { _ -> StringValue(thisEntity.effectiveName().string) },
"yaw" to { _ -> DoubleValue(thisEntity.yRot.toDouble()) },
"pitch" to { _ -> DoubleValue(thisEntity.xRot.toDouble()) },
"x" to { _ -> DoubleValue(thisEntity.x) },
"y" to { _ -> DoubleValue(thisEntity.y) },
"z" to { _ -> DoubleValue(thisEntity.z) },
"velocity_x" to { _ -> DoubleValue(thisEntity.deltaMovement.x) },
"velocity_y" to { _ -> DoubleValue(thisEntity.deltaMovement.y) },
"velocity_z" to { _ -> DoubleValue(thisEntity.deltaMovement.z) },
"width" to { DoubleValue(thisEntity.boundingBox.xsize) },
"height" to { DoubleValue(thisEntity.boundingBox.ysize) },
"this_size" to { DoubleValue(thisEntity.boundingBox.run { if (xsize > ysize) xsize else ysize }) },
"this_width" to { DoubleValue(thisEntity.boundingBox.xsize) },
"this_height" to { DoubleValue(thisEntity.boundingBox.ysize) },
"id_modulo" to { params -> DoubleValue(thisEntity.uuid.hashCode() % params.getDouble(0)) },
"horizontal_velocity" to { _ -> DoubleValue(thisEntity.deltaMovement.horizontalDistance()) },
"vertical_velocity" to { DoubleValue(thisEntity.deltaMovement.y) },
"is_on_ground" to { _ -> DoubleValue(thisEntity.onGround()) },
"world" to { _ -> thisEntity.level().worldRegistry.wrapAsHolder(thisEntity.level()).asWorldMoLangValue() },
"biome" to { _ -> thisEntity.level().getBiome(thisEntity.blockPosition()).asBiomeMoLangValue() },
"is_passenger" to { DoubleValue(thisEntity.isPassenger) },
"discard" to { thisEntity.discard() },
"is_sneaking" to { _ -> DoubleValue(thisEntity.isShiftKeyDown) },
"is_sprinting" to { _ -> DoubleValue(thisEntity.isSprinting) },
"is_in_water" to { _ -> DoubleValue(thisEntity.isUnderWater) },
"is_in_rain" to { _ -> DoubleValue(thisEntity.isInWaterOrRain && !thisEntity.isInWater) },
"is_touching_water_or_rain" to { _ -> DoubleValue(thisEntity.isInWaterRainOrBubble) },
"is_touching_water" to { _ -> DoubleValue(thisEntity.isInWater) },
"is_underwater" to { DoubleValue(thisEntity.getIsSubmerged()) },
"is_in_lava" to { _ -> DoubleValue(thisEntity.isInLava) },
"is_on_fire" to { _ -> DoubleValue(thisEntity.isOnFire) },
"is_invisible" to { _ -> DoubleValue(thisEntity.isInvisible) },
"is_riding" to { _ -> DoubleValue(thisEntity.isPassenger) },
"set_name" to { params ->
val name = params.getString(0)
thisEntity.customName = name.text()
DoubleValue.ONE
},
"damage" to { params ->
val amount = params.getDouble(0)
val source = DamageSource(
thisEntity.level().registryAccess().registryOrThrow(Registries.DAMAGE_TYPE)
.getHolder(DamageTypes.GENERIC).get()
)
entity.hurt(source, amount.toFloat())
}
functions["distance_to_owner"] = distanceToOwner@{
if (entity !is TamableAnimal) {
return@distanceToOwner DoubleValue.ZERO
}
val owner = entity.owner ?: return@distanceToOwner DoubleValue.ZERO
DoubleValue(entity.distanceTo(owner))
}
functions["owner"] = owner@{
if (entity !is TamableAnimal) return@owner DoubleValue.ZERO
val owner = entity.owner
owner?.asMostSpecificMoLangValue() ?: DoubleValue.ZERO
}
functions["delta_movement"] = {
listOf(entity.deltaMovement.x, entity.deltaMovement.y, entity.deltaMovement.z)
.asArrayValue(::DoubleValue)
}
functions["tags"] = {
val tags = entity.tags
val array = ArrayStruct(hashMapOf())
tags.forEachIndexed { index, tag -> array.setDirectly("$index", StringValue(tag)) }
array
}
functions["add_tag"] = { params ->
val tag = params.getString(0)
entity.addTag(tag)
DoubleValue.ONE
}
functions["remove_tag"] = { params ->
val tag = params.getString(0)
entity.removeTag(tag)
DoubleValue.ONE
}
functions["has_tag"] = { params ->
val tag = params.getString(0)
DoubleValue(entity.tags.contains(tag))
}
functions["distance_to_pos"] = { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
DoubleValue(sqrt(entity.distanceToSqr(Vec3(x, y, z))))
}
functions["type"] = {
entity
.registryAccess()
.registry(Registries.ENTITY_TYPE)
.get()
.getKey(entity.type)
?.toString()
?.let {
thisEntity.hurt(source, amount.toFloat())
},
"distance_to_owner" to distanceToOwner@{
if (thisEntity !is TamableAnimal) {
return@distanceToOwner DoubleValue.ZERO
}
val owner = thisEntity.owner ?: return@distanceToOwner DoubleValue.ZERO
DoubleValue(thisEntity.distanceTo(owner))
},
"owner" to owner@{
if (thisEntity !is TamableAnimal) return@owner DoubleValue.ZERO
val owner = thisEntity.owner
owner?.asMostSpecificMoLangValue() ?: DoubleValue.ZERO
},
"delta_movement" to {
listOf(thisEntity.deltaMovement.x, thisEntity.deltaMovement.y, thisEntity.deltaMovement.z)
.asArrayValue(::DoubleValue)
},
"tags" to {
val tags = thisEntity.tags
val array = ArrayStruct(hashMapOf())
tags.forEachIndexed { index, tag -> array.setDirectly("$index", StringValue(tag)) }
array
},
"add_tag" to { params ->
val tag = params.getString(0)
thisEntity.addTag(tag)
DoubleValue.ONE
},
"remove_tag" to { params ->
val tag = params.getString(0)
thisEntity.removeTag(tag)
DoubleValue.ONE
},
"has_tag" to { params ->
val tag = params.getString(0)
DoubleValue(thisEntity.tags.contains(tag))
},
"distance_to_pos" to { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
DoubleValue(sqrt(thisEntity.distanceToSqr(Vec3(x, y, z))))
},
"type" to { _ ->
thisEntity.registryAccess().registry(Registries.ENTITY_TYPE).get().getKey(thisEntity.type)?.toString()?.let {
StringValue(it)
} ?: DoubleValue.ZERO
}
functions["find_nearby_block"] = findNearbyBlock@{ params ->
val input = params.getString(0)
val isTag = input.contains("#")
val type = input.replace("#", "").asIdentifierDefaultingNamespace(namespace = "minecraft")
val range = params.getDoubleOrNull(1) ?: 10
val blockPos =
entity
.level()
.getBlockStatesWithPos(
AABB.ofSize(
entity.position(),
range.toDouble(),
range.toDouble(),
range.toDouble(),
),
).filter { blockPosPair ->
blockPosPair.first.blockHolder.let {
if (isTag) {
it.`is`(
TagKey.create(
Registries.BLOCK,
type,
),
)
} else {
it.`is`(type)
}
}
}.minByOrNull { it.second.distSqr(entity.blockPosition()) }
?.second
if (blockPos != null) {
return@findNearbyBlock ArrayStruct(
mapOf(
"0" to DoubleValue(blockPos.x),
"1" to DoubleValue(blockPos.y),
"2" to DoubleValue(blockPos.z),
),
},
"find_nearby_block" to findNearbyBlock@{ params ->
val input = params.getString(0)
val isTag = input.contains("#")
val type = input.replace("#", "").asIdentifierDefaultingNamespace(namespace = "minecraft")
val range = params.getDoubleOrNull(1) ?: 10
val blockPos = thisEntity.level().getBlockStatesWithPos(
AABB.ofSize(
thisEntity.position(),
range.toDouble(),
range.toDouble(),
range.toDouble()
)
)
}
return@findNearbyBlock DoubleValue.ZERO
}
functions["get_nearby_entities"] = { params ->
val distance = params.getDouble(0)
val entities =
entity
.level()
.getEntities(entity, AABB.ofSize(entity.position(), distance, distance, distance))
.filter { blockPosPair ->
blockPosPair.first.blockHolder.let {
if (isTag) it.`is`(
TagKey.create(
Registries.BLOCK,
type
)
) else it.`is`(type)
}
}
.minByOrNull { it.second.distSqr(thisEntity.blockPosition()) }
?.second
if (blockPos != null) {
return@findNearbyBlock ArrayStruct(
mapOf(
"0" to DoubleValue(blockPos.x),
"1" to DoubleValue(blockPos.y),
"2" to DoubleValue(blockPos.z)
)
)
}
return@findNearbyBlock DoubleValue.ZERO
},
"get_nearby_entities" to { params ->
val distance = params.getDouble(0)
val entities =
thisEntity.level().getEntities(thisEntity, AABB.ofSize(thisEntity.position(), distance, distance, distance))
entities
.filterIsInstance<Entity>()
.map { it.asMostSpecificMoLangValue() }
.asArrayValue()
}
functions["is_standing_on_blocks"] = { params ->
val depth = params.getDouble(0).toInt()
val blockStrings: MutableSet<String> = mutableSetOf()
for (blockIndex in 1..<params.params.size) {
blockStrings.add(params.getString(blockIndex))
}
entities
.filterIsInstance<Entity>()
.map { it.asMostSpecificMoLangValue() }
.asArrayValue()
},
"is_standing_on_blocks" to { params ->
val depth = params.getDouble(0).toInt()
val blockStrings: MutableSet<String> = mutableSetOf()
for (blockIndex in 1..<params.params.size) {
blockStrings.add(params.getString(blockIndex))
}
if (entity.isStandingOn(blockStrings, depth)) DoubleValue.ONE else DoubleValue.ZERO
}
if (thisEntity.isStandingOn(blockStrings, depth)) DoubleValue.ONE else DoubleValue.ZERO
},
// q.entity.spawn_bedrock_particles(effect, locator, [player])
// sends to everyone nearby or just to the player if they're set.
// Locator is necessary even if unused on non-posables.
functions["spawn_bedrock_particles"] = { params ->
val particle = params.getString(0).asResource()
val locator = params.getString(1)
val player =
params.getOrNull<MoValue>(2)?.let {
// q.entity.spawn_bedrock_particles(effect, locator, [player])
// sends to everyone nearby or just to the player if they're set.
// Locator is necessary even if unused on non-posables.
"spawn_bedrock_particles" to { params ->
val particle = params.getString(0).asResource()
val locator = params.getString(1)
val player = params.getOrNull<MoValue>(2)?.let {
when (it) {
is StringValue -> entity.level().getPlayerByUUID(UUID.fromString(it.value))
is StringValue -> thisEntity.level().getPlayerByUUID(UUID.fromString(it.value))
is ObjectValue<*> -> it.obj
else -> null
}
} as? ServerPlayer
val packet = SpawnSnowstormEntityParticlePacket(particle, entity.id, listOf(locator))
if (player == null) {
packet.sendToPlayersAround(
entity.x,
entity.y,
entity.z,
64.0,
entity.level().dimension(),
)
} else {
packet.sendToPlayer(player)
val packet = SpawnSnowstormEntityParticlePacket(particle, thisEntity.id, listOf(locator))
if (player == null) {
packet.sendToPlayersAround(thisEntity.x, thisEntity.y, thisEntity.z, 64.0, thisEntity.level().dimension())
} else {
packet.sendToPlayer(player)
}
},
"make_intangible" to { params ->
val intangible = params.getBooleanOrNull(0) ?: true
thisEntity.noPhysics = intangible
DoubleValue.ONE
}
}
functions["make_intangible"] = { params ->
val intangible = params.getBooleanOrNull(0) ?: true
entity.noPhysics = intangible
DoubleValue.ONE
}
)
when (entity) {
is PosableEntity -> {
functions["play_animation"] = playAnimation@{ params ->
val animation = params.getString(0)
val packet = PlayPosableAnimationPacket(entity.id, setOf(animation), emptyList())
val target = params.getStringOrNull(1)
if (target != null) {
val targetPlayer =
if (target.asUUID != null) {
entity.level().getPlayerByUUID(target.asUUID!!) as ServerPlayer
} else if (entity.level() is ServerLevel) {
entity
.level()
.server!!
.playerList
.getPlayerByName(target)
} else {
null
}
if (targetPlayer != null) {
packet.sendToPlayer(targetPlayer)
return@playAnimation DoubleValue.ONE
} else {
return@playAnimation DoubleValue.ZERO
}
if (thisEntity is PosableEntity) {
map["play_animation"] = playAnimation@{ params ->
val animation = params.getString(0)
val packet = PlayPosableAnimationPacket(thisEntity.id, setOf(animation), emptyList())
val target = params.getStringOrNull(1)
if (target != null) {
val targetPlayer = if (target.asUUID != null) {
thisEntity.level().getPlayerByUUID(target.asUUID!!) as ServerPlayer
} else if (thisEntity.level() is ServerLevel) {
thisEntity.level().server!!.playerList.getPlayerByName(target)
} else {
packet.sendToPlayersAround(
entity.x,
entity.y,
entity.z,
64.0,
entity.level().dimension(),
)
null
}
if (targetPlayer != null) {
packet.sendToPlayer(targetPlayer)
return@playAnimation DoubleValue.ONE
}
}
functions["face"] = { params ->
ObjectValue(ReferenceDialogueFaceProvider(entity.id, params.getBooleanOrNull(0) != false))
}
}
is Schedulable -> {
functions["run_molang_after"] = { params ->
val expression = params.getString(0).asExpressionLike()
val delayInSeconds = params.getDouble(1).toFloat()
val runtime = MoLangRuntime()
runtime.environment.cloneFrom(params.environment)
entity.after(delayInSeconds) {
runtime.resolve(expression)
}
}
}
is MoLangScriptingEntity -> {
functions["add_callback"] = { params ->
val type = params.getString(0).asIdentifierDefaultingNamespace()
val callback = params.getString(1).asIdentifierDefaultingNamespace()
val allowDuplicates = params.getBooleanOrNull(2) ?: false
entity.callbacks.addCallback(type, callback, allowDuplicates)
}
functions["remove_callback"] = { params ->
val type = params.getString(0).asIdentifierDefaultingNamespace()
val callback = params.getString(1).asIdentifierDefaultingNamespace()
entity.callbacks.removeCallback(type, callback)
}
functions["has_callback"] = { params ->
val type = params.getString(0).asIdentifierDefaultingNamespace()
val callback = params.getString(1).asIdentifierDefaultingNamespace()
DoubleValue(callback in (entity.callbacks[type] ?: emptySet()))
}
functions["clear_callbacks"] = { params ->
val type = params.getStringOrNull(0)?.asIdentifierDefaultingNamespace()
if (type != null) {
entity.callbacks[type]?.clear()
} else {
entity.callbacks.clear()
return@playAnimation DoubleValue.ZERO
}
DoubleValue.ONE
} else {
packet.sendToPlayersAround(thisEntity.x, thisEntity.y, thisEntity.z, 64.0, thisEntity.level().dimension())
return@playAnimation DoubleValue.ONE
}
}
map["face"] = { params ->
ObjectValue(ReferenceDialogueFaceProvider(thisEntity.id, params.getBooleanOrNull(0) != false))
}
}
if (thisEntity is Schedulable) {
map["run_molang_after"] = { params ->
val expression = params.getString(0).asExpressionLike()
val delayInSeconds = params.getDouble(1).toFloat()
val runtime = MoLangRuntime()
runtime.environment.cloneFrom(params.environment)
thisEntity.after(delayInSeconds) {
runtime.resolve(expression)
}
}
}
return functions
if (thisEntity is MoLangScriptingEntity) {
map["add_callback"] = { params ->
val type = params.getString(0).asIdentifierDefaultingNamespace()
val callback = params.getString(1).asIdentifierDefaultingNamespace()
val allowDuplicates = params.getBooleanOrNull(2) ?: false
thisEntity.callbacks.addCallback(type, callback, allowDuplicates)
}
map["remove_callback"] = { params ->
val type = params.getString(0).asIdentifierDefaultingNamespace()
val callback = params.getString(1).asIdentifierDefaultingNamespace()
thisEntity.callbacks.removeCallback(type, callback)
}
map["has_callback"] = { params ->
val type = params.getString(0).asIdentifierDefaultingNamespace()
val callback = params.getString(1).asIdentifierDefaultingNamespace()
DoubleValue(callback in (thisEntity.callbacks[type] ?: emptySet()))
}
map["clear_callbacks"] = { params ->
val type = params.getStringOrNull(0)?.asIdentifierDefaultingNamespace()
if (type != null) {
thisEntity.callbacks[type]?.clear()
} else {
thisEntity.callbacks.clear()
}
DoubleValue.ONE
}
}
return map
}
}
@@ -19,26 +19,26 @@ import com.cobblemon.mod.common.pokemon.evolution.variants.TradeEvolution
object EvolutionMoLangFunctions : AbstractMoLangFunctionHolder<Evolution>() {
override fun Evolution.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val evolution = this
val functions = hashMapOf<String, (MoParams) -> Any>()
val map = hashMapOf<String, (MoParams) -> Any>()
functions["result"] = { evolution.result.asMoLangValue() }
functions["is_optional"] = { DoubleValue(evolution.optional) }
functions["consumes_held_item"] = { DoubleValue(evolution.consumeHeldItem) }
map["result"] = { evolution.result.asMoLangValue() }
map["is_optional"] = { DoubleValue(evolution.optional) }
map["consumes_held_item"] = { DoubleValue(evolution.consumeHeldItem) }
when (evolution) {
is LevelUpEvolution -> {
functions["is_level_up"] = { DoubleValue.ONE }
map["is_level_up"] = { DoubleValue.ONE }
}
is TradeEvolution -> {
functions["is_trade"] = { DoubleValue.ONE }
map["is_trade"] = { DoubleValue.ONE }
}
is ItemInteractionEvolution -> {
functions["is_item"] = { DoubleValue.ONE }
map["is_item"] = { DoubleValue.ONE }
}
}
return functions
return map
}
}
@@ -42,99 +42,101 @@ import net.minecraft.world.item.ItemStack
import java.text.ParseException
object GeneralMoLangFunctions {
val functions: MutableMap<String, (MoParams) -> Any> = mutableMapOf()
init {
functions["print"] = { params ->
val holder: HashMap<String, (MoParams) -> Any> = hashMapOf(
"print" to { params ->
val message = params.get<MoValue>(0).asString()
LOGGER.info(message)
}
functions["delete_variable"] = { params ->
},
"delete_variable" to deleteVar@{ params ->
val struct = params.get<VariableStruct>(0)
val variable = params.getString(1)
struct.map.remove(variable)
return@deleteVar DoubleValue.ONE
},
"delete_variables" to { params ->
val struct = params.get<VariableStruct>(0)
struct.map.clear()
DoubleValue.ONE
}
functions["get_variable"] = { params ->
},
"get_variable" to { params ->
val struct = params.get<VariableStruct>(0)
val variable = params.getString(1)
struct.map[variable] ?: DoubleValue.ZERO
}
functions["set_variable"] = { params ->
},
"set_variable" to { params ->
val struct = params.get<VariableStruct>(0)
val variable = params.getString(1)
val value = params.get<MoValue>(2)
struct.map[variable] = value
value
}
functions["set_query"] = { params ->
},
"set_query" to { params ->
val variable = params.getString(0)
val value = params.get<MoValue>(1)
params.environment.query.addFunction(variable) { value }
value
}
functions["replace"] = { params ->
},
"replace" to { params ->
val text = params.getString(0)
val search = params.getString(1)
val replace = params.getString(2)
StringValue(text.replace(search, replace))
}
functions["is_included"] = { params ->
},
"is_included" to { params ->
val text = params.getString(0)
val search = params.getString(1)
DoubleValue(text.contains(search))
}
functions["to_lower"] = { params ->
},
"to_lower" to { params ->
StringValue(params.getString(0).lowercase())
}
functions["to_upper"] = { params ->
},
"to_upper" to { params ->
StringValue(params.getString(0).uppercase())
}
functions["string_length"] = { params ->
},
"string_length" to { params ->
DoubleValue(params.getString(0).length)
}
functions["split_string"] = { params ->
},
"split_string" to { params ->
val text = params.getString(0)
val delimiter = params.getString(1)
val parts = text.split(delimiter).map { StringValue(it) }
val struct = ArrayStruct(hashMapOf())
parts.forEachIndexed { index, moValue -> struct.setDirectly("$index", moValue) }
struct
}
functions["is_blank"] = { params ->
},
"is_blank" to { params ->
val arg = params.get<MoValue>(0)
DoubleValue(
(arg is StringValue && (arg.value.isBlank() || arg.value.toDoubleOrNull() == 0.0)) ||
(arg is DoubleValue && arg.value == 0.0),
)
}
functions["run_command"] = { params ->
DoubleValue((arg is StringValue && (arg.value.isBlank() || arg.value.toDoubleOrNull() == 0.0)) || (arg is DoubleValue && arg.value == 0.0))
},
"run_command" to { params ->
val command = params.getString(0)
try {
server()!!.commands.performPrefixedCommand(server()!!.createCommandSourceStack(), command)
} catch (_: NullPointerException) {
DoubleValue.ZERO
}
}
functions["is_int"] = { params -> DoubleValue(params.get<MoValue>(0).asString().isInt()) }
functions["is_number"] = { params ->
},
"is_int" to { params -> DoubleValue(params.get<MoValue>(0).asString().isInt()) },
"is_number" to { params ->
DoubleValue(
params.get<MoValue>(0).asString().toDoubleOrNull() != null,
params.get<MoValue>(0).asString().toDoubleOrNull() != null
)
}
functions["to_number"] = { params ->
},
"to_number" to { params ->
DoubleValue(
params.get<MoValue>(0).asString().toDoubleOrNull() ?: 0.0,
params.get<MoValue>(0).asString().toDoubleOrNull() ?: 0.0
)
}
functions["to_int"] = { params ->
},
"to_int" to { params ->
DoubleValue(
params.get<MoValue>(0).asString().toIntOrNull() ?: 0,
params.get<MoValue>(0).asString().toIntOrNull() ?: 0
)
}
functions["to_string"] = { params -> StringValue(params.get<MoValue>(0).asString()) }
functions["do_effect_walks"] = { DoubleValue(Cobblemon.config.walkingInBattleAnimations) }
functions["random"] = { params ->
},
"to_string" to { params -> StringValue(params.get<MoValue>(0).asString()) },
"do_effect_walks" to { _ ->
DoubleValue(Cobblemon.config.walkingInBattleAnimations)
},
"random" to { params ->
val options = mutableListOf<MoValue>()
var index = 0
while (params.contains(index)) {
@@ -142,35 +144,35 @@ object GeneralMoLangFunctions {
index++
}
options.random() // Can throw an exception if they specified no args. They'd be idiots though.
}
functions["curve"] = { params ->
},
"curve" to { params ->
val curveName = params.getString(0)
val curve =
WaveFunctions.functions[curveName] ?: throw IllegalArgumentException("Unknown curve: $curveName")
ObjectValue(curve)
}
functions["array"] = { params ->
},
"array" to { params ->
val values = params.params
val array = ArrayStruct(hashMapOf())
values.forEachIndexed { index, moValue -> array.setDirectly("$index", moValue) }
array
}
functions["length"] = { params ->
},
"length" to { params ->
val array = (params.getOrNull<MoValue>(0) as? VariableStruct)
if (array == null) {
DoubleValue.ZERO
} else {
DoubleValue(array.map.size.toDouble())
}
}
functions["append"] = { params ->
},
"append" to { params ->
val array = params.get<ArrayStruct>(0)
val value = params.get<MoValue>(1)
val nextIndex = array.map.size
array.setDirectly("$nextIndex", value)
array
}
functions["insert"] = { params ->
},
"insert" to { params ->
val array = params.get<ArrayStruct>(0)
val index = params.getInt(1)
val value = params.get<MoValue>(2)
@@ -185,40 +187,36 @@ object GeneralMoLangFunctions {
}
array.map[index.toString()] = value
array
}
functions["delete"] = { params ->
},
"delete" to { params ->
val array = params.get<ArrayStruct>(0)
val index = params.getInt(1)
if (index in 0 until array.map.size) {
array.map.remove(index.toString())
// Re-index the array to keep keys sequential in numerical order
val newMap = hashMapOf<String, MoValue>()
array.map.keys
.mapNotNull { it.toIntOrNull() }
array.map.keys.mapNotNull { it.toIntOrNull() }
.sorted()
.forEachIndexed { i, k -> newMap[i.toString()] = array.map[k.toString()]!! }
array.map.clear()
array.map.putAll(newMap)
}
array
}
functions["run_script"] = { params ->
},
"run_script" to { params ->
val runtime = MoLangRuntime()
runtime.environment.query = params.environment.query
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(),
)
runtime.environment.context = ContextStruct(
(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
CobblemonScripts.run(script, runtime) ?: DoubleValue.ZERO
}
functions["run_molang"] = { params ->
},
"run_molang" to { params ->
val runtime = MoLangRuntime()
runtime.environment.query = params.environment.query
runtime.environment.variable = params.environment.variable
@@ -226,16 +224,17 @@ object GeneralMoLangFunctions {
val expression = params.getString(0).asExpressionLike()
val delayInSeconds = params.getDoubleOrNull(1)?.toFloat() ?: 0.0f
fun evaluate(): MoValue =
try {
fun evaluate(): MoValue {
return try {
runtime.resolve(expression)
} catch (ex: Exception) {
LOGGER.warn(
"Failed to evaluate MoLang expression${if (delayInSeconds > 0.0f) " (delayed)" else ""}: $expression",
ex,
ex
)
DoubleValue.ZERO
}
}
if (delayInSeconds > 0.0f) {
val tracker =
@@ -247,55 +246,55 @@ object GeneralMoLangFunctions {
} else {
evaluate()
}
}
functions["system_time_millis"] = { DoubleValue(System.currentTimeMillis()) }
},
"system_time_millis" to { _ ->
DoubleValue(System.currentTimeMillis())
},
// the rest of the world use dd/MM/yyyy grow up america (this comment was generated by copilot)
functions["date_local_time"] = {
"date_local_time" to { _ ->
val time = System.currentTimeMillis()
val date = java.util.Date(time)
val formatted = java.text.SimpleDateFormat("dd/MM/yyyy").format(date)
StringValue(formatted)
}
functions["date_of"] = { params ->
},
"date_of" to { params ->
val time = params.getDouble(0).toLong()
val date = java.util.Date(time)
val formatted = java.text.SimpleDateFormat("dd/MM/yyyy").format(date)
StringValue(formatted)
}
functions["date_is_after"] = { params ->
},
"date_is_after" to { params ->
val dateA = params.getString(0)
val dateB = params.getString(1)
val format = java.text.SimpleDateFormat("dd/MM/yyyy")
val a =
try {
format.parse(dateA)
} catch (_: ParseException) {
throw RuntimeException("Cannot parse date $dateA, expected it to be in dd/MM/yyyy format, other provided")
}
val b =
try {
format.parse(dateB)
} catch (_: ParseException) {
throw RuntimeException("Cannot parse date $dateB, expected it to be in dd/MM/yyyy format, other provided")
}
val a = try {
format.parse(dateA)
} catch (_: ParseException) {
throw RuntimeException("Cannot parse date ${dateA}, expected it to be in dd/MM/yyyy format, other provided")
}
val b = try {
format.parse(dateB)
} catch (_: ParseException) {
throw RuntimeException("Cannot parse date ${dateB}, expected it to be in dd/MM/yyyy format, other provided")
}
DoubleValue(a.after(b))
}
functions["get_move_from_id"] = { params ->
},
"get_move_from_id" to { params ->
val moveId = params.getString(0)
val moveTemplate = Moves.getByName(moveId)
moveTemplate?.struct ?: DoubleValue.ZERO
}
functions["create_simple_party_provider"] = {
},
"create_simple_party_provider" to { _ ->
val partyProvider = SimplePartyProvider()
partyProvider.struct
}
functions["create_pickup_item"] = { params ->
},
"create_pickup_item" to { params ->
val item = params.getOrNull<MoValue>(0)?.asString()?.let(ObtainableItemCondition::parseFromString)
val pickupPriority = params.getIntOrNull(1) ?: 0
val pickupItem = ObtainableItem(item = item, pickupPriority = pickupPriority)
pickupItem.struct
}
functions["create_itemstack"] = { params ->
},
"create_itemstack" to { params ->
val itemId = params.getString(0).asIdentifierDefaultingNamespace()
try {
val item = BuiltInRegistries.ITEM.get(itemId)
@@ -306,7 +305,7 @@ object GeneralMoLangFunctions {
LOGGER.error("Cannot create item stack from identifier: $itemId, item with that ID does not exist. Possible typo?")
DoubleValue.ZERO
}
}
functions["file"] = { MoLangLoadedFilesCache.struct }
}
},
"file" to { MoLangLoadedFilesCache.struct }
)
}
@@ -26,44 +26,43 @@ object ItemStackMoLangFunctions : AbstractMoLangFunctionHolder<Pair<ItemStack, R
val registryAccess = this.second
val itemRegistry = registryAccess.registryOrThrow(Registries.ITEM)
val holder = itemRegistry.wrapAsHolder(stack.item)
val functions = mutableMapOf<String, (MoParams) -> Any>()
functions["item"] = { holder.asMoLangValue(Registries.ITEM) }
functions["count"] = { DoubleValue(stack.count.toDouble()) }
functions["damage_value"] = { DoubleValue(stack.damageValue) }
functions["max_damage"] = { DoubleValue(stack.maxDamage) }
functions["is_empty"] = { DoubleValue(stack.isEmpty) }
functions["shrink"] = { params -> stack.shrink(params.getInt(0)) }
functions["grow"] = { params -> stack.grow(params.getInt(0)) }
functions["is_of"] = { params ->
val map = hashMapOf<String, (MoParams) -> Any>()
map["item"] = { _ -> holder.asMoLangValue(Registries.ITEM) }
map["count"] = { _ -> DoubleValue(stack.count.toDouble()) }
map["damage_value"] = { _ -> DoubleValue(stack.damageValue) }
map["max_damage"] = { _ -> DoubleValue(stack.maxDamage) }
map["is_empty"] = { _ -> DoubleValue(stack.isEmpty) }
map["shrink"] = { params -> stack.shrink(params.getInt(0)) }
map["grow"] = { params -> stack.grow(params.getInt(0)) }
map["is_of"] = { params ->
DoubleValue(
holder.`is`(
params.getString(0).asIdentifierDefaultingNamespace(),
),
params.getString(0).asIdentifierDefaultingNamespace()
)
)
}
functions["is_in"] = { params ->
map["is_in"] = { params ->
DoubleValue(
holder.`is`(
TagKey.create(
Registries.ITEM,
params.getString(0).replace("#", "").asIdentifierDefaultingNamespace(),
),
),
params.getString(0).replace("#", "").asIdentifierDefaultingNamespace()
)
)
)
}
functions["is_food"] = { DoubleValue(stack.has(DataComponents.FOOD)) }
functions["is_enchanted"] = { DoubleValue(stack.hasFoil()) }
functions["has_enchantment"] = hasEnchantment@{ params ->
map["is_food"] = { _ -> DoubleValue(stack.has(DataComponents.FOOD)) }
map["is_enchanted"] = { _ -> DoubleValue(stack.hasFoil()) }
map["has_enchantment"] = put@{ params ->
val enchantmentId = params.getString(0).asIdentifierDefaultingNamespace()
val minLevel = params.getIntOrNull(1) ?: 1
val enchantmentRegistry = registryAccess.registryOrThrow(Registries.ENCHANTMENT)
val holder =
enchantmentRegistry.getHolder(enchantmentId).orElse(null) ?: return@hasEnchantment DoubleValue.ZERO
enchantmentRegistry.getHolder(enchantmentId).orElse(null) ?: return@put DoubleValue.ZERO
val level = EnchantmentHelper.getItemEnchantmentLevel(holder, stack)
DoubleValue(level >= minLevel)
return@put DoubleValue(level >= minLevel)
}
return functions
return map
}
}
@@ -53,27 +53,26 @@ import java.util.*
object LivingEntityMoLangFunctions : AbstractMoLangFunctionHolder<LivingEntity>() {
override fun LivingEntity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val entity = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["is_player"] = { DoubleValue(entity is Player) }
functions["is_npc"] = { DoubleValue(entity is NPCEntity) }
functions["is_mob"] = { DoubleValue(entity is Mob) }
functions["is_pokemon"] = { DoubleValue(entity is PokemonEntity) }
functions["is_animal"] = { DoubleValue(entity is Animal) }
functions["is_tamable"] = { DoubleValue(entity is TamableAnimal) }
functions["is_tamed"] = { DoubleValue(entity is TamableAnimal && entity.isTame) }
functions["is_hostile"] = { DoubleValue(entity is Monster) }
functions["is_baby"] = { DoubleValue(entity.isBaby) }
functions["is_adult"] = { DoubleValue(!entity.isBaby) }
functions["remove_effect"] = removeEffect@{ params ->
val map = mutableMapOf<String, (MoParams) -> Any>()
map["is_player"] = { _ -> DoubleValue(entity is Player) }
map["is_npc"] = { _ -> DoubleValue(entity is NPCEntity) }
map["is_mob"] = { _ -> DoubleValue(entity is Mob) }
map["is_pokemon"] = { _ -> DoubleValue(entity is PokemonEntity) }
map["is_animal"] = { _ -> DoubleValue(entity is Animal) }
map["is_tamable"] = { _ -> DoubleValue(entity is TamableAnimal) }
map["is_tamed"] = { _ -> DoubleValue(entity is TamableAnimal && entity.isTame) }
map["is_hostile"] = { _ -> DoubleValue(entity is Monster) }
map["is_baby"] = { _ -> DoubleValue(entity.isBaby) }
map["is_adult"] = { _ -> DoubleValue(!entity.isBaby) }
map["remove_effect"] = put@{ params ->
val effectId = params.getString(0).asIdentifierDefaultingNamespace()
val effectHolder = BuiltInRegistries.MOB_EFFECT.getHolder(effectId).orElse(null)
if (effectHolder != null) {
entity.removeEffect(effectHolder)
return@removeEffect DoubleValue.ONE
return@put DoubleValue.ONE
}
}
functions["add_effect"] = addEffect@{ params ->
map["add_effect"] = put@{ params ->
val effectId = params.getString(0).asIdentifierDefaultingNamespace()
val duration = params.getInt(1)
val amplifier = params.getIntOrNull(2) ?: 0
@@ -82,37 +81,36 @@ object LivingEntityMoLangFunctions : AbstractMoLangFunctionHolder<LivingEntity>(
val effectHolder = BuiltInRegistries.MOB_EFFECT.getHolder(effectId).orElse(null)
if (effectHolder != null) {
entity.addEffect(MobEffectInstance(effectHolder, duration, amplifier, ambient, visible))
return@addEffect DoubleValue.ONE
return@put DoubleValue.ONE
}
}
functions["has_effect"] = { params ->
map["has_effect"] = put@{ params ->
val effectId = params.getString(0).asIdentifierDefaultingNamespace()
val effectHolder = BuiltInRegistries.MOB_EFFECT.getHolder(effectId).orElse(null)
DoubleValue(effectHolder != null && entity.hasEffect(effectHolder))
return@put DoubleValue(if (effectHolder != null) entity.hasEffect(effectHolder) else false)
}
functions["heal"] = { params ->
map["heal"] = { params ->
val amount = params.getDouble(0)
entity.heal(amount.toFloat())
}
functions["is_looking_at"] = isLookingAt@{ params ->
map["is_looking_at"] = put@{ params ->
val targetEntity = params.get<MoValue>(0)
val maxDistance = params.getDoubleOrNull(1)?.toFloat() ?: 2.0F
val entity =
if (targetEntity is ObjectValue<*> && targetEntity.obj is Entity) {
targetEntity.obj as Entity
} else {
return@isLookingAt DoubleValue.ZERO
}
val entity = if (targetEntity is ObjectValue<*> && targetEntity.obj is Entity) {
targetEntity.obj as Entity
} else {
return@put DoubleValue.ZERO
}
DoubleValue(entity.isLookingAt(entity, maxDistance))
return@put DoubleValue(entity.isLookingAt(entity, maxDistance))
}
functions["is_living_entity"] = { DoubleValue.ONE }
functions["is_flying"] = { DoubleValue(entity.isFallFlying) }
functions["is_sleeping"] = { DoubleValue(entity.isSleeping) }
functions["health"] = { DoubleValue(entity.health) }
functions["max_health"] = { DoubleValue(entity.maxHealth) }
functions["look_at_position"] = { params ->
map["is_living_entity"] = { DoubleValue.ONE }
map["is_flying"] = { _ -> DoubleValue(entity.isFallFlying) }
map["is_sleeping"] = { _ -> DoubleValue(entity.isSleeping) }
map["health"] = { _ -> DoubleValue(entity.health) }
map["max_health"] = { _ -> DoubleValue(entity.maxHealth) }
map["look_at_position"] = { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
@@ -122,174 +120,159 @@ object LivingEntityMoLangFunctions : AbstractMoLangFunctionHolder<LivingEntity>(
brain.setMemoryWithExpiry(
MemoryModuleType.LOOK_TARGET,
CobblemonBlockPosTracker(Vec3(x, y, z), flags.toSet()),
duration.toLong(),
duration.toLong()
)
}
functions["get_wander_control_memory"] = {
val value =
entity.brain.getMemorySafely(CobblemonMemories.WANDER_CONTROL).orElse(null)
?: CobblemonWanderControl()
map["get_wander_control_memory"] = put@{
val value = entity.brain.getMemorySafely(CobblemonMemories.WANDER_CONTROL).orElse(null)
?: CobblemonWanderControl()
if (
!entity.brain.checkMemory(CobblemonMemories.WANDER_CONTROL, MemoryStatus.VALUE_PRESENT) &&
entity.brain.checkMemory(CobblemonMemories.WANDER_CONTROL, MemoryStatus.REGISTERED)
!entity.brain.checkMemory(CobblemonMemories.WANDER_CONTROL, MemoryStatus.VALUE_PRESENT)
&& entity.brain.checkMemory(CobblemonMemories.WANDER_CONTROL, MemoryStatus.REGISTERED)
) {
entity.brain.setMemory(CobblemonMemories.WANDER_CONTROL, value)
}
value.struct
return@put value.struct
}
functions["get_position_memory"] = getPosMemory@{ params ->
map["get_position_memory"] = put@{ params ->
val id = params.getString(0).asIdentifierDefaultingNamespace()
val memoryType = BuiltInRegistries.MEMORY_MODULE_TYPE.get(id)
if (entity.brain.checkMemory(memoryType, MemoryStatus.VALUE_PRESENT)) {
return@getPosMemory when (val memory = entity.brain.getMemory(memoryType).get()) {
is Vec3i -> {
VariableStruct(
mapOf(
"x" to DoubleValue(memory.x),
"y" to DoubleValue(memory.y),
"z" to DoubleValue(memory.z),
),
return@put when (val memory = entity.brain.getMemory(memoryType).get()) {
is Vec3i -> VariableStruct(
mapOf(
"x" to DoubleValue(memory.x),
"y" to DoubleValue(memory.y),
"z" to DoubleValue(memory.z)
)
}
)
is Position -> {
VariableStruct(
mapOf(
"x" to DoubleValue(memory.x()),
"y" to DoubleValue(memory.y()),
"z" to DoubleValue(memory.z()),
),
is Position -> VariableStruct(
mapOf(
"x" to DoubleValue(memory.x()),
"y" to DoubleValue(memory.y()),
"z" to DoubleValue(memory.z())
)
}
)
else -> {
DoubleValue.ZERO
}
else -> DoubleValue.ZERO
}
} else {
return@put DoubleValue.ZERO
}
DoubleValue.ZERO
}
functions["set_uuid_memory"] = setUuidMemory@{ params ->
val memory =
params
.getString(0)
.asIdentifierDefaultingNamespace()
.let(BuiltInRegistries.MEMORY_MODULE_TYPE::get) as MemoryModuleType<UUID>
val uuid = params.getString(1).asUUID ?: return@setUuidMemory DoubleValue.ZERO
map["set_uuid_memory"] = put@{ params ->
val memory = params.getString(0).asIdentifierDefaultingNamespace()
.let(BuiltInRegistries.MEMORY_MODULE_TYPE::get) as MemoryModuleType<UUID>
val uuid = params.getString(1).asUUID ?: return@put DoubleValue.ZERO
val expiry = params.getIntOrNull(2) ?: -1
if (expiry != -1) {
entity.brain.setMemoryWithExpiry(memory, uuid, expiry.toLong())
} else {
entity.brain.setMemory(memory, uuid)
}
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["erase_memory"] = { params ->
val memories =
params.params
.map { it.asString().asIdentifierDefaultingNamespace() }
.map(BuiltInRegistries.MEMORY_MODULE_TYPE::get)
map["erase_memory"] = put@{ params ->
val memories = params.params.map { it.asString().asIdentifierDefaultingNamespace() }
.map(BuiltInRegistries.MEMORY_MODULE_TYPE::get)
memories.forEach { entity.brain.eraseMemory(it) }
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["has_memory_value"] = hasMemoryValue@{ params ->
map["has_memory_value"] = put@{ params ->
for (param in params.params) {
if (!entity.hasMemoryFromString(param.asString())) {
return@hasMemoryValue DoubleValue.ZERO
return@put DoubleValue.ZERO
}
}
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["lacks_memory_value"] = lacksMemoryValue@{ params ->
map["lacks_memory_value"] = put@{ params ->
for (param in params.params) {
if (entity.hasMemoryFromString(param.asString())) {
return@lacksMemoryValue DoubleValue.ZERO
return@put DoubleValue.ZERO
}
}
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["is_doing_activity"] = isDoingActivity@{ params ->
map["is_doing_activity"] = put@{ params ->
for (param in params.params) {
if (entity.isDoingActivityFromString(param.asString())) {
return@isDoingActivity DoubleValue.ONE
return@put DoubleValue.ONE
}
}
DoubleValue.ZERO
return@put DoubleValue.ZERO
}
functions["can_see"] = canSee@{ params ->
map["can_see"] = put@{ params ->
val target = params.get<MoValue>(0)
val range = params.getDoubleOrNull(1) ?: 32.0
if (target is ObjectValue<*>) {
val targetEntity = target.obj as? LivingEntity ?: return@canSee DoubleValue.ZERO
val targetEntity = target.obj as? LivingEntity ?: return@put DoubleValue.ZERO
val vector = targetEntity.eyePosition.subtract(entity.eyePosition).normalize()
val trace =
entity.traceEntityCollision(
maxDistance = range.toFloat(),
stepDistance = 0.1F,
direction = vector,
entityClass = targetEntity.javaClass,
collideBlock = ClipContext.Fluid.NONE,
val trace = entity.traceEntityCollision(
maxDistance = range.toFloat(),
stepDistance = 0.1F,
direction = vector,
entityClass = targetEntity.javaClass,
collideBlock = ClipContext.Fluid.NONE
)
return@put DoubleValue(targetEntity in (trace?.entities ?: emptyList()))
} else {
return@put DoubleValue.ZERO
}
}
if (entity is PathfinderMob) {
map["walk_to"] = { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
val speedMultiplier = params.getDoubleOrNull(3) ?: 0.35
if (entity.brain.checkMemory(MemoryModuleType.WALK_TARGET, MemoryStatus.REGISTERED)) {
entity.brain.setMemory(
MemoryModuleType.WALK_TARGET,
WalkTarget(Vec3(x, y, z), speedMultiplier.toFloat(), 1)
)
return@canSee DoubleValue(targetEntity in (trace?.entities ?: emptyList()))
}
DoubleValue.ZERO
}
when (entity) {
is PathfinderMob -> {
functions["walk_to"] = { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
val speedMultiplier = params.getDoubleOrNull(3) ?: 0.35
if (entity.brain.checkMemory(MemoryModuleType.WALK_TARGET, MemoryStatus.REGISTERED)) {
entity.brain.setMemory(
MemoryModuleType.WALK_TARGET,
WalkTarget(Vec3(x, y, z), speedMultiplier.toFloat(), 1),
)
entity.brain.setMemory(
MemoryModuleType.LOOK_TARGET,
BlockPosTracker(Vec3(x, y + entity.eyeHeight, z)),
)
} else {
entity.navigation.moveTo(x, y, z, speedMultiplier)
entity.lookControl.setLookAt(Vec3(x, y + entity.eyeHeight, z))
}
}
functions["has_walk_target"] = {
DoubleValue(entity.brain.getMemorySafely(MemoryModuleType.WALK_TARGET).isPresent || entity.isPathFinding)
}
functions["set_can_float"] = { params ->
val canFloat = params.getBooleanOrNull(0) != false
entity.navigation.setCanFloat(canFloat)
DoubleValue.ONE
}
functions["get_pathfinding_malus"] = getPfMalus@{ params ->
val type = PathType.entries.find { it.name == params.getString(0).uppercase() }
if (type != null) {
return@getPfMalus DoubleValue(entity.getPathfindingMalus(type))
}
Cobblemon.LOGGER.error("Cannot get pathfinding type, unknown value: ${params.getString(0)}")
DoubleValue.ZERO
}
functions["set_pathfinding_malus"] = setPfMalus@{ params ->
val type = PathType.entries.find { it.name == params.getString(0).uppercase() }
val malus = params.getDouble(1).toFloat()
if (type != null) {
entity.setPathfindingMalus(type, malus)
return@setPfMalus DoubleValue.ONE
}
Cobblemon.LOGGER.error("Cannot set pathfinding type, unknown value: ${params.getString(0)}")
DoubleValue.ZERO
entity.brain.setMemory(
MemoryModuleType.LOOK_TARGET,
BlockPosTracker(Vec3(x, y + entity.eyeHeight, z))
)
} else {
entity.navigation.moveTo(x, y, z, speedMultiplier)
entity.lookControl.setLookAt(Vec3(x, y + entity.eyeHeight, z))
}
}
}
return functions
map["has_walk_target"] = { _ ->
DoubleValue(entity.brain.getMemorySafely(MemoryModuleType.WALK_TARGET).isPresent || entity.isPathFinding)
}
map["set_can_float"] = { params ->
val canFloat = params.getBooleanOrNull(0) != false
entity.navigation.setCanFloat(canFloat)
DoubleValue.ONE
}
map["get_pathfinding_malus"] = put@{ params ->
val type = PathType.entries.find { it.name == params.getString(0).uppercase() }
if (type != null) {
return@put DoubleValue(entity.getPathfindingMalus(type))
}
Cobblemon.LOGGER.error("Unknown pathfinding type: ${params.getString(0)}")
return@put DoubleValue.ZERO
}
map["set_pathfinding_malus"] = put@{ params ->
val type = PathType.entries.find { it.name == params.getString(0).uppercase() }
val malus = params.getDouble(1).toFloat()
if (type != null) {
entity.setPathfindingMalus(type, malus)
return@put DoubleValue.ONE
}
Cobblemon.LOGGER.error("Unknown pathfinding type: ${params.getString(0)}")
return@put DoubleValue.ZERO
}
}
return map
}
}
@@ -50,23 +50,18 @@ import kotlin.collections.any
object NPCMoLangFunctions : AbstractMoLangFunctionHolder<NPCEntity>() {
override fun NPCEntity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val npc = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["class"] = { StringValue(npc.npc.id.toString()) }
functions["name"] = { StringValue(npc.name.string) }
functions["level"] = { DoubleValue(npc.level) }
functions["has_aspect"] = { params -> DoubleValue(npc.aspects.contains(params.getString(0))) }
functions["in_battle"] = { DoubleValue(npc.isInBattle()) }
functions["battles"] = {
ArrayStruct(
npc.battleIds
.mapNotNull { BattleRegistry.getBattle(it)?.struct }
.mapIndexed { index, value -> "$index" to value }
.toMap(),
)
val map = hashMapOf<String, (MoParams) -> Any>()
map["class"] = { StringValue(npc.npc.id.toString()) }
map["name"] = { StringValue(npc.name.string) }
map["level"] = { DoubleValue(npc.level) }
map["has_aspect"] = { params -> DoubleValue(npc.aspects.contains(params.getString(0))) }
map["in_battle"] = { DoubleValue(npc.isInBattle()) }
map["battles"] = {
ArrayStruct(npc.battleIds.mapNotNull { BattleRegistry.getBattle(it)?.struct }
.mapIndexed { index, value -> "$index" to value }.toMap())
}
functions["stop_battles"] = { npc.battleIds.forEach { BattleRegistry.getBattle(it)?.stop() } }
functions["run_script_on_client"] = { params ->
map["stop_battles"] = { _ -> npc.battleIds.forEach { BattleRegistry.getBattle(it)?.stop() } }
map["run_script_on_client"] = { params ->
val world = npc.level()
if (world is ServerLevel) {
val script = params.getString(0)
@@ -75,142 +70,141 @@ object NPCMoLangFunctions : AbstractMoLangFunctionHolder<NPCEntity>() {
}
Unit
}
functions["run_script"] = { params ->
map["run_script"] = { params ->
val script = params.getString(0).asIdentifierDefaultingNamespace()
val runtime = MoLangRuntime()
runtime.environment.cloneFrom(params.environment)
CobblemonScripts.run(script, runtime) ?: DoubleValue(0)
}
functions["set_movable"] = { params ->
map["set_movable"] = put@{ params ->
val movable = params.getBooleanOrNull(0) != false
npc.isMovable = movable
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["set_invulnerable"] = { params ->
map["set_invulnerable"] = put@{ params ->
val invulnerable = params.getBooleanOrNull(0) != false
npc.isInvulnerable = invulnerable
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["set_leashable"] = { params ->
map["set_leashable"] = put@{ params ->
val leashable = params.getBooleanOrNull(0) != false
npc.isLeashable = leashable
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["set_allow_projectile_hits"] = { params ->
map["set_allow_projectile_hits"] = put@{ params ->
val allowProjectileHits = params.getBooleanOrNull(0) != false
npc.allowProjectileHits = allowProjectileHits
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["set_name_tag_visible"] = { params ->
map["set_name_tag_visible"] = put@{ params ->
val nameTagVisible = params.getBooleanOrNull(0) != false
npc.hideNameTag = !nameTagVisible
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["unset_interaction"] = {
map["unset_interaction"] = put@{
npc.interaction = null
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["set_dialogue_interaction"] = { params ->
map["set_dialogue_interaction"] = put@{ params ->
val dialogue = params.getString(0).asIdentifierDefaultingNamespace()
npc.interaction =
DialogueNPCInteractionConfiguration().also {
it.dialogue = dialogue
}
DoubleValue.ONE
npc.interaction = DialogueNPCInteractionConfiguration().also {
it.dialogue = dialogue
}
return@put DoubleValue.ONE
}
functions["set_script_interaction"] = { params ->
map["set_script_interaction"] = put@{ params ->
val script = params.getString(0).asIdentifierDefaultingNamespace()
npc.interaction =
ScriptNPCInteractionConfiguration().also {
it.script = script
}
DoubleValue.ONE
npc.interaction = ScriptNPCInteractionConfiguration().also {
it.script = script
}
return@put DoubleValue.ONE
}
functions["set_player_texture"] = setPlayerTexture@{ params ->
map["set_player_texture"] = put@{ params ->
val username = params.getString(0)
// Re-applying it would be unnecessarily laggy.
if (username == npc.data.map["player_texture_username"]?.asString()) {
return@setPlayerTexture DoubleValue.ZERO
return@put DoubleValue.ZERO
}
npc.loadTextureFromGameProfileName(username)
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["unset_player_texture"] = {
map["unset_player_texture"] = put@{
npc.unloadTexture()
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["set_resource_identifier"] = { params ->
map["set_resource_identifier"] = put@{ params ->
val identifier = params.getStringOrNull(0)?.asIdentifierDefaultingNamespace()
npc.forcedResourceIdentifier = identifier
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["unset_resource_identifier"] = {
map["unset_resource_identifier"] = put@{
npc.forcedResourceIdentifier = null
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["set_class"] = setClass@{ params ->
map["set_class"] = put@{ params ->
val identifier = params.getString(0).asIdentifierDefaultingNamespace()
val npcClass = NPCClasses.getByIdentifier(identifier)
if (npcClass != null) {
npc.npc = npcClass
return@setClass DoubleValue.ONE
return@put DoubleValue.ONE
} else {
Cobblemon.LOGGER.error("Unknown NPC class: $identifier")
return@put DoubleValue.ZERO
}
Cobblemon.LOGGER.error("Unknown NPC class: $identifier")
DoubleValue.ZERO
}
functions["set_render_scale"] = { params ->
map["set_render_scale"] = put@{ params ->
val scale = params.getDouble(0)
npc.renderScale = scale.toFloat()
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["render_scale"] = { DoubleValue(npc.renderScale) }
functions["set_hitbox_scale"] = { params ->
map["render_scale"] = { _ -> DoubleValue(npc.renderScale) }
map["set_hitbox_scale"] = put@{ params ->
val scale = params.getDouble(0).toFloat()
npc.hitboxScale = scale
npc.refreshDimensions()
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["hitbox_scale"] = { DoubleValue(npc.hitboxScale) }
functions["set_hitbox"] = setHitbox@{ params ->
map["hitbox_scale"] = { _ -> DoubleValue(npc.hitboxScale) }
map["set_hitbox"] = put@{ params ->
if (params.params.isEmpty()) {
npc.hitbox = null
return@setHitbox DoubleValue.ONE
return@put DoubleValue.ONE
}
val width = params.getDouble(0).toFloat()
val height = params.getDouble(1).toFloat()
val eyeHeight = params.getDoubleOrNull(2)?.toFloat() ?: (height * 0.85F)
npc.hitbox = EntityDimensions.scalable(width, height).withEyeHeight(eyeHeight)
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["unset_hitbox"] = {
map["unset_hitbox"] = put@{
npc.hitbox = null
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["aspects"] = {
map["aspects"] = put@{
val aspects = npc.aspects
aspects.asArrayValue { StringValue(it) }
return@put aspects.asArrayValue { StringValue(it) }
}
functions["add_aspect"] = { params ->
map["add_aspect"] = put@{ params ->
val aspects = params.params.map { it.asString() }
npc.appliedAspects.addAll(aspects)
npc.updateAspects()
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["remove_aspect"] = { params ->
map["remove_aspect"] = put@{ params ->
val aspects = params.params.map { it.asString() }
npc.appliedAspects.removeAll(aspects.toSet())
npc.updateAspects()
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["party"] = party@{
val party = npc.party ?: return@party DoubleValue.ZERO
party.asMoLangValue()
map["party"] = put@{
val party = npc.party ?: return@put DoubleValue.ZERO
return@put party.asMoLangValue()
}
functions["create_npc_party"] = {
map["create_npc_party"] = put@{
val party = NPCPartyStore(npc)
party.asMoLangValue()
return@put party.asMoLangValue()
}
functions["set_npc_party"] = { params ->
map["set_npc_party"] = { params ->
val party = params.get<MoValue>(0)
if (party is ObjectValue<*>) {
npc.party = party.obj as NPCPartyStore
@@ -219,19 +213,18 @@ object NPCMoLangFunctions : AbstractMoLangFunctionHolder<NPCEntity>() {
}
DoubleValue.ONE
}
functions["run_action_effect"] = runActionEffect@{ params ->
map["run_action_effect"] = put@{ params ->
val runtime = MoLangRuntime().setup()
runtime.environment.cloneFrom(params.environment)
runtime.withNPCValue(value = npc)
val actionEffect = ActionEffects.actionEffects[params.getString(0).asIdentifierDefaultingNamespace()]
if (actionEffect != null) {
val context =
ActionEffectContext(
actionEffect = actionEffect,
providers = mutableListOf(NPCProvider(npc)),
runtime = runtime,
level = npc.level(),
)
val context = ActionEffectContext(
actionEffect = actionEffect,
providers = mutableListOf(NPCProvider(npc)),
runtime = runtime,
level = npc.level()
)
npc.actionEffect = context
npc.brain.setMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT, context)
npc.brain.setActiveActivityIfPossible(CobblemonActivities.ACTION_EFFECT)
@@ -243,40 +236,37 @@ object NPCMoLangFunctions : AbstractMoLangFunctionHolder<NPCEntity>() {
}
}
return@runActionEffect DoubleValue.ONE
return@put DoubleValue.ONE
}
DoubleValue.ZERO
return@put DoubleValue.ZERO
}
functions["put_pokemon_in_healer"] = putPokeInHealer@{ params ->
val healer =
npc
.level()
.getBlockEntity(params.get<ArrayStruct>(0).asBlockPos(), CobblemonBlockEntities.HEALING_MACHINE)
.orElse(null) ?: return@putPokeInHealer DoubleValue.ZERO
val party = npc.party ?: return@putPokeInHealer DoubleValue.ZERO
map["put_pokemon_in_healer"] = put@{ params ->
val healer = npc.level()
.getBlockEntity(params.get<ArrayStruct>(0).asBlockPos(), CobblemonBlockEntities.HEALING_MACHINE)
.orElse(null) ?: return@put DoubleValue.ZERO
val party = npc.party ?: return@put DoubleValue.ZERO
if (healer.canHeal(party)) {
healer.activate(npc.uuid, party)
return@putPokeInHealer DoubleValue.ONE
return@put DoubleValue.ONE
} else {
return@put DoubleValue.ZERO
}
DoubleValue.ZERO
}
functions["look_at_position"] = { params ->
map["look_at_position"] = { params ->
val pos = Vec3(params.getDouble(0), params.getDouble(1), params.getDouble(2))
npc.lookAt(EntityAnchorArgument.Anchor.EYES, pos)
}
functions["environment"] = { npc.runtime.environment }
functions["party"] = { npc.party?.struct ?: DoubleValue.ZERO }
functions["has_party"] = { DoubleValue(npc.party != null) }
functions["is_npc"] = { DoubleValue.ONE }
functions["can_battle"] = {
DoubleValue(npc.party?.any { it.currentHealth > 0 } == true || npc.npc.party?.isStatic == false)
}
functions["set_battle_theme"] = { params ->
map["environment"] = { _ -> npc.runtime.environment }
map["party"] = { npc.party?.struct ?: DoubleValue.ZERO }
map["has_party"] = { DoubleValue(npc.party != null) }
map["is_npc"] = { DoubleValue.ONE }
map["can_battle"] =
{ DoubleValue(npc.party?.any { it.currentHealth > 0 } == true || npc.npc.party?.isStatic == false) }
map["set_battle_theme"] = put@{ params ->
val soundId = params.getString(0).asResource()
npc.npc.battleTheme = soundId
DoubleValue.ONE
return@put DoubleValue.ONE
}
return functions
return map
}
}
@@ -23,40 +23,40 @@ import com.cobblemon.mod.common.util.getBooleanOrNull
object PCMoLangFunctions : AbstractMoLangFunctionHolder<PCStore>() {
override fun PCStore.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val pc = this
val functions = hashMapOf<String, (MoParams) -> Any>()
val map = mutableMapOf<String, (MoParams) -> Any>()
functions["get_pokemon"] = getPokemon@{ params ->
map["get_pokemon"] = getPokemon@{ params ->
val box = params.getInt(0)
val slot = params.getInt(1)
val pokemon = pc[PCPosition(box, slot)] ?: return@getPokemon DoubleValue.ZERO
pokemon.struct
return@getPokemon pokemon.struct
}
functions["set_pokemon"] = { params ->
map["set_pokemon"] = { params ->
val box = params.getInt(0)
val slot = params.getInt(1)
val pokemon = params.get<ObjectValue<Pokemon>>(2).obj
pc[PCPosition(box, slot)] = pokemon
DoubleValue.ONE
}
functions["resize"] = { params ->
map["resize"] = { params ->
val newSize = params.getInt(0)
val lockNewSize = params.getBooleanOrNull(1) == true
pc.resize(newSize, lockNewSize)
DoubleValue.ONE
}
functions["get_box_count"] = { DoubleValue(pc.boxes.size.toDouble()) }
functions["has_unlocked_wallpaper"] = { params ->
map["get_box_count"] = { DoubleValue(pc.boxes.size.toDouble()) }
map["has_unlocked_wallpaper"] = { params ->
val wallpaper = params.getString(0).asIdentifierDefaultingNamespace()
DoubleValue(pc.unlockedWallpapers.contains(wallpaper))
}
functions["get_unlocked_wallpapers"] = { pc.unlockedWallpapers.asArrayValue { StringValue(it.toString()) } }
functions["unlock_wallpaper"] = unlockWallpaper@{
map["get_unlocked_wallpapers"] = { pc.unlockedWallpapers.asArrayValue { StringValue(it.toString()) } }
map["unlock_wallpaper"] = unlockWallpaper@{
val wallpaper = it.getString(0).asIdentifierDefaultingNamespace()
val playSound = it.getBooleanOrNull(1) != false
CobblemonUnlockableWallpapers.unlockableWallpapers[wallpaper] ?: return@unlockWallpaper DoubleValue.ZERO
DoubleValue(pc.unlockWallpaper(wallpaper, playSound))
return@unlockWallpaper DoubleValue(pc.unlockWallpaper(wallpaper, playSound))
}
return functions
return map
}
}
@@ -14,23 +14,21 @@ import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.storage.party.PartyStore
import com.cobblemon.mod.common.pokemon.Pokemon
object PartyMoLangFunctions : AbstractMoLangFunctionHolder<PartyStore>() {
object PartyMoLangFunctions: AbstractMoLangFunctionHolder<PartyStore>() {
override fun PartyStore.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val party = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["get_pokemon"] = getPokemon@{ params ->
val map = hashMapOf<String, (MoParams) -> Any>()
map["get_pokemon"] = getPokemon@{ params ->
val index = params.getInt(0)
val pokemon = party.get(index) ?: return@getPokemon DoubleValue.ZERO
pokemon.struct
}
functions["set_pokemon"] = { params ->
map["set_pokemon"] = { params ->
val index = params.getInt(0)
val pokemon = params.get<ObjectValue<Pokemon>>(1).obj
party.set(index, pokemon)
DoubleValue.ONE
}
return functions
return map
}
}
@@ -17,12 +17,12 @@ import com.bedrockk.molang.runtime.value.MoValue
import com.bedrockk.molang.runtime.value.StringValue
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonBlockEntities
import com.cobblemon.mod.common.api.moves.Moves
import com.cobblemon.mod.common.api.tms.TechnicalMachines
import com.cobblemon.mod.common.api.dialogue.PlayerDialogueFaceProvider
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMoLangValue
import com.cobblemon.mod.common.api.molang.ObjectValue
import com.cobblemon.mod.common.api.moves.Moves
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.api.tms.TechnicalMachines
import com.cobblemon.mod.common.battles.BattleBuilder
import com.cobblemon.mod.common.battles.BattleFormat
import com.cobblemon.mod.common.entity.npc.NPCEntity
@@ -52,389 +52,355 @@ import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.sounds.SoundSource
import net.minecraft.stats.Stats
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.GameType
import kotlin.collections.iterator
object PlayerMoLangFunctions : AbstractMoLangFunctionHolder<Player>() {
override fun Player.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val player = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["username"] = { StringValue(player.gameProfile.name) }
functions["uuid"] = { StringValue(player.gameProfile.id.toString()) }
functions["main_held_item"] = { player.mainHandItem.asMoLangValue(player.registryAccess()) }
functions["off_held_item"] = { player.offhandItem.asMoLangValue(player.registryAccess()) }
functions["inventory"] = {
val map = mutableMapOf<String, (MoParams) -> Any>()
map["username"] = { _ -> StringValue(player.gameProfile.name) }
map["uuid"] = { _ -> StringValue(player.gameProfile.id.toString()) }
map["main_held_item"] = { _ -> player.mainHandItem.asMoLangValue(player.registryAccess()) }
map["off_held_item"] = { _ -> player.offhandItem.asMoLangValue(player.registryAccess()) }
map["inventory"] = put@{ _ ->
val inventory = player.inventory
val items = ArrayStruct(hashMapOf())
for (i in 0 until inventory.containerSize) {
items.setDirectly("$i", inventory.getItem(i).asMoLangValue(player.registryAccess()))
}
items
return@put items
}
functions["has_inventory_space"] = {
map["has_inventory_space"] = put@{ _ ->
val inventory = player.inventory
if (inventory.freeSlot != -1) DoubleValue.ONE else DoubleValue.ZERO
return@put if (inventory.getFreeSlot() != -1) DoubleValue.ONE else DoubleValue.ZERO
}
functions["set_inventory_slot"] = setInvSlot@{ params ->
map["set_inventory_slot"] = put@{ params ->
val slot = params.getInt(0)
val inventory = player.inventory
if (slot !in 0 until inventory.containerSize) return@setInvSlot DoubleValue.ZERO
if (slot !in 0 until inventory.containerSize) return@put DoubleValue.ZERO
val value = params.getOrNull<MoValue>(1) ?: return@setInvSlot DoubleValue.ZERO
val value = params.getOrNull<MoValue>(1) ?: return@put DoubleValue.ZERO
val stack: ItemStack? =
when (value) {
is ObjectValue<*> -> {
value.obj as? ItemStack
}
is StringValue -> {
val id = ResourceLocation.parse(value.value)
val item =
player.registryAccess().registryOrThrow(Registries.ITEM).get(id)
?: return@setInvSlot DoubleValue.ZERO
ItemStack(item)
}
else -> {
null
}
val stack: ItemStack? = when (value) {
is ObjectValue<*> -> value.obj as? ItemStack
is StringValue -> {
val id = ResourceLocation.parse(value.value)
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(id)
?: return@put DoubleValue.ZERO
ItemStack(item)
}
if (stack == null) return@setInvSlot DoubleValue.ZERO
else -> null
}
if (stack == null) return@put DoubleValue.ZERO
inventory.setItem(slot, stack)
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["give_item"] = giveItem@{ params ->
map["give_item"] = put@{ params ->
val inventory = player.inventory
val freeSlot = inventory.freeSlot
val value = params.getOrNull<MoValue>(0) ?: return@giveItem DoubleValue.ZERO
val freeSlot = inventory.getFreeSlot()
val value = params.getOrNull<MoValue>(0) ?: return@put DoubleValue.ZERO
val dropIfFull = params.getBooleanOrNull(1) ?: false
val stack: ItemStack? =
when (value) {
is ObjectValue<*> -> {
value.obj as? ItemStack
}
is StringValue -> {
val id = ResourceLocation.parse(value.value)
val item =
player.registryAccess().registryOrThrow(Registries.ITEM).get(id)
?: return@giveItem DoubleValue.ZERO
ItemStack(item)
}
else -> {
null
}
val stack: ItemStack? = when (value) {
is ObjectValue<*> -> value.obj as? ItemStack
is StringValue -> {
val id = ResourceLocation.parse(value.value)
val item = player.registryAccess().registryOrThrow(Registries.ITEM).get(id)
?: return@put DoubleValue.ZERO
ItemStack(item)
}
if (stack == null) return@giveItem DoubleValue.ZERO
else -> null
}
if (stack == null) return@put DoubleValue.ZERO
if (freeSlot == -1) {
if (dropIfFull) {
player.drop(stack, false)
return@giveItem DoubleValue.ONE
return@put DoubleValue.ONE
} else {
return@giveItem DoubleValue.ZERO
return@put DoubleValue.ZERO
}
}
inventory.setItem(freeSlot, stack)
DoubleValue.ONE
return@put DoubleValue.ONE
}
functions["face"] = { params ->
map["face"] = { params ->
ObjectValue(
PlayerDialogueFaceProvider(
player.uuid,
params.getBooleanOrNull(0) != false,
),
params.getBooleanOrNull(0) != false
)
)
}
functions["swing_hand"] = { player.swing(player.usedItemHand) }
functions["food_level"] = { DoubleValue(player.foodData.foodLevel) }
functions["saturation_level"] = { DoubleValue(player.foodData.saturationLevel) }
functions["tell"] = { params ->
map["swing_hand"] = { _ -> player.swing(player.usedItemHand) }
map["food_level"] = { _ -> DoubleValue(player.foodData.foodLevel) }
map["saturation_level"] = { _ -> DoubleValue(player.foodData.saturationLevel) }
map["tell"] = { params ->
val message = params.getString(0).text()
val overlay = params.getBooleanOrNull(1) == true
player.displayClientMessage(message, overlay)
}
functions["teleport"] = { params ->
map["teleport"] = { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
val playParticleOptions = params.getBooleanOrNull(3) ?: false
player.randomTeleport(x, y, z, playParticleOptions)
val playParticleOptionss = params.getBooleanOrNull(3) ?: false
player.randomTeleport(x, y, z, playParticleOptionss)
}
functions["heal"] = { params ->
map["heal"] = { params ->
val amount = params.getDoubleOrNull(0) ?: player.maxHealth
player.heal(amount.toFloat())
}
functions["environment"] = {
map["environment"] = {
val environment = MoLangEnvironment()
environment.query = player.asMoLangValue()
environment
}
functions["is_player"] = { DoubleValue.ONE }
functions["riding_pokemon"] = ridingPokemon@{
map["is_player"] = { DoubleValue.ONE }
map["riding_pokemon"] = put@{
val vehicle = player.vehicle
if (vehicle is PokemonEntity) {
return@ridingPokemon vehicle.struct
return@put vehicle.struct
} else {
return@put DoubleValue.ZERO
}
DoubleValue.ZERO
}
when (player) {
is ServerPlayer -> {
functions["seen_credits"] = { DoubleValue(player.seenCredits) }
functions["is_in_dialogue"] = { DoubleValue(player.isInDialogue) }
functions["active_dialogue"] = activeDialogue@{
if (player.isInDialogue) {
return@activeDialogue player.activeDialogue?.toMoLangStruct() ?: DoubleValue.ZERO
}
if (player is ServerPlayer) {
map["seen_credits"] = { _ ->
DoubleValue(player.seenCredits)
}
map["is_in_dialogue"] = { _ ->
DoubleValue(player.isInDialogue)
}
map["active_dialogue"] = put@{ _ ->
if (player.isInDialogue) {
return@put player.activeDialogue?.toMoLangStruct() ?: DoubleValue.ZERO
} else {
DoubleValue.ZERO
}
functions["is_spectator"] = { DoubleValue(player.isSpectator) }
functions["is_creative"] = { DoubleValue(player.isCreative) }
functions["is_survival"] = { DoubleValue(player.gameMode.isSurvival) }
functions["is_adventure"] = { DoubleValue(player.gameMode.gameModeForPlayer == GameType.ADVENTURE) }
functions["run_command"] = { params ->
val command = params.getString(0)
player.server.commands.performPrefixedCommand(player.createCommandSourceStack(), command)
}
functions["set_battle_theme"] = { params ->
val soundId = params.getString(0).asResource()
Cobblemon.playerDataManager.getGenericData(player).battleTheme = soundId
DoubleValue.ONE
}
functions["battle_music"] = battleMusic@{ params ->
val soundId = params.getString(0).asResource()
val volume = params.getDoubleOrNull(1)?.toFloat() ?: 1.0f
val pitch = params.getDoubleOrNull(2)?.toFloat() ?: 1.0f
val restart = params.getBooleanOrNull(3) ?: true
}
map["is_spectator"] = { DoubleValue(player.isSpectator) }
map["is_creative"] = { DoubleValue(player.isCreative) }
map["is_survival"] = { DoubleValue(player.gameMode.isSurvival) }
map["is_adventure"] = { DoubleValue(player.gameMode.gameModeForPlayer == GameType.ADVENTURE) }
map["run_command"] = { params ->
val command = params.getString(0)
player.server.commands.performPrefixedCommand(player.createCommandSourceStack(), command)
}
map["set_battle_theme"] = put@{ params ->
val soundId = params.getString(0).asResource()
Cobblemon.playerDataManager.getGenericData(player).battleTheme = soundId
return@put DoubleValue.ONE
}
map["battle_music"] = put@{ params ->
val soundId = params.getString(0).asResource()
val volume = params.getDoubleOrNull(1)?.toFloat() ?: 1.0f
val pitch = params.getDoubleOrNull(2)?.toFloat() ?: 1.0f
val restart = params.getBooleanOrNull(3) ?: true
if (soundId != null) {
val packet = BattleMusicPacket(soundId, volume, pitch, restart)
packet.sendToPlayer(player)
return@battleMusic DoubleValue.ONE
}
DoubleValue.ZERO
}
functions["stop_battle_music"] = {
val packet = BattleMusicPacket(null)
if (soundId != null) {
val packet = BattleMusicPacket(soundId, volume, pitch, restart)
packet.sendToPlayer(player)
DoubleValue.ONE
return@put DoubleValue.ONE
} else {
return@put DoubleValue.ZERO
}
functions["play_sound_on_server"] = { params ->
val sound = params.getString(0).asResource()
val soundSource = SoundSource.valueOf(params.getString(1).uppercase())
val volume = params.getDoubleOrNull(2)?.toFloat() ?: 1.0f
val pitch = params.getDoubleOrNull(3)?.toFloat() ?: 1.0f
}
map["stop_battle_music"] = put@{ _ ->
val packet = BattleMusicPacket(null)
packet.sendToPlayer(player)
return@put DoubleValue.ONE
}
map["play_sound_on_server"] = { params ->
val sound = params.getString(0).asResource()
val soundSource = SoundSource.valueOf(params.getString(1).uppercase())
val volume = params.getDoubleOrNull(2)?.toFloat() ?: 1.0f
val pitch = params.getDoubleOrNull(3)?.toFloat() ?: 1.0f
val packet =
UnvalidatedPlaySoundS2CPacket(
sound,
soundSource,
player.x,
player.y,
player.z,
volume,
pitch,
)
packet.sendToPlayer(player)
val packet =
UnvalidatedPlaySoundS2CPacket(sound, soundSource, player.x, player.y, player.z, volume, pitch)
packet.sendToPlayer(player)
}
map["is_party_at_full_health"] = { _ ->
DoubleValue(player.party().none(Pokemon::canBeHealed))
}
map["can_heal_at_healer"] = put@{ params ->
val pos = params.get<ArrayStruct>(0).asBlockPos()
val healer = player.level().getBlockEntity(pos, CobblemonBlockEntities.HEALING_MACHINE).orElse(null)
?: return@put DoubleValue.ZERO
val party = player.party()
return@put DoubleValue(healer.canHeal(party))
}
map["put_pokemon_in_healer"] = put@{ params ->
val healer = player.level()
.getBlockEntity(params.get<ArrayStruct>(0).asBlockPos(), CobblemonBlockEntities.HEALING_MACHINE)
.orElse(null) ?: return@put DoubleValue.ZERO
val party = player.party()
if (healer.canHeal(party)) {
healer.activate(player.uuid, party)
return@put DoubleValue.ONE
} else {
return@put DoubleValue.ZERO
}
functions["is_party_at_full_health"] = { DoubleValue(player.party().none(Pokemon::canBeHealed)) }
functions["can_heal_at_healer"] = canHealAtHealer@{ params ->
val pos = params.get<ArrayStruct>(0).asBlockPos()
val healer =
player.level().getBlockEntity(pos, CobblemonBlockEntities.HEALING_MACHINE).orElse(null)
?: return@canHealAtHealer DoubleValue.ZERO
val party = player.party()
DoubleValue(healer.canHeal(party))
}
functions["put_pokemon_in_healer"] = putPokemonAtHealer@{ params ->
val healer =
player
.level()
.getBlockEntity(
params.get<ArrayStruct>(0).asBlockPos(),
CobblemonBlockEntities.HEALING_MACHINE,
).orElse(null) ?: return@putPokemonAtHealer DoubleValue.ZERO
val party = player.party()
if (healer.canHeal(party)) {
healer.activate(player.uuid, party)
return@putPokemonAtHealer DoubleValue.ONE
}
DoubleValue.ZERO
}
functions["party"] = { player.party().struct }
functions["pc"] = { player.pc().struct }
functions["has_permission"] = { params ->
DoubleValue(
Cobblemon.permissionValidator.hasPermission(
player,
params.getString(0),
params.getIntOrNull(1) ?: 4,
),
}
map["party"] = { player.party().struct }
map["pc"] = { player.pc().struct }
map["has_permission"] = { params ->
DoubleValue(
Cobblemon.permissionValidator.hasPermission(
player,
params.getString(0),
params.getIntOrNull(1) ?: 4
)
}
functions["data"] = { params -> Cobblemon.molangData.load(player.uuid, params.getStringOrNull(0)) }
functions["save_data"] = { params -> Cobblemon.molangData.save(player.uuid, params.getStringOrNull(0)) }
functions["in_battle"] = { DoubleValue(player.isInBattle()) }
functions["battle"] = { player.getBattleState()?.first?.struct ?: DoubleValue.ZERO }
functions["get_npc_data"] = getNpcData@{ params ->
val npcId =
((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
?: params.getString(0)
val data = Cobblemon.molangData.load(player.uuid, params.getStringOrNull(1))
if (data.map.containsKey(npcId)) {
return@getNpcData data.map[npcId]!!
}
)
}
map["data"] = { params -> Cobblemon.molangData.load(player.uuid, params.getStringOrNull(0)) }
map["save_data"] = { params -> Cobblemon.molangData.save(player.uuid, params.getStringOrNull(0)) }
map["in_battle"] = { DoubleValue(player.isInBattle()) }
map["battle"] = { player.getBattleState()?.first?.struct ?: DoubleValue.ZERO }
map["get_npc_data"] = put@{ params ->
val npcId = ((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
?: params.getString(0)
val data = Cobblemon.molangData.load(player.uuid, params.getStringOrNull(1))
if (data.map.containsKey(npcId)) {
return@put data.map[npcId]!!
} else {
val vars = VariableStruct()
data.map[npcId] = vars
vars
}
functions["get_npc_variable"] = getNpcVariable@{ params ->
val npcId =
((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
?: params.getString(0)
val variable = params.getString(1)
val data = Cobblemon.molangData.load(player.uuid, params.getStringOrNull(2))
if (data.map.containsKey(npcId)) {
return@getNpcVariable (data.map[npcId] as VariableStruct).map[variable] ?: DoubleValue.ZERO
}
DoubleValue.ZERO
}
functions["set_npc_variable"] = { params ->
val npcId =
((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
?: params.getString(0)
val variable = params.getString(1)
val value = params.get<MoValue>(2)
val saveAfterwards = params.getBooleanOrNull(3) != false
val path = params.getStringOrNull(4)
val data = Cobblemon.molangData.load(player.uuid, path)
val npcData = data.map.getOrPut(npcId) { VariableStruct() } as VariableStruct
npcData.map[variable] = value
if (saveAfterwards) {
Cobblemon.molangData.save(player.uuid, path)
}
DoubleValue.ONE
}
functions["pokedex"] = { player.pokedex().struct }
functions["has_advancement"] = hasAdvancement@{ params ->
val requiredAdvancement = ResourceLocation.parse(params.getString(0))
player.advancements.progress.forEach { (holder, progress) ->
if (holder.id == requiredAdvancement && progress.isDone) {
return@hasAdvancement DoubleValue.ONE
}
}
DoubleValue.ZERO
}
functions["has_tm_move_unlocked"] = hasTmMoveUnlocked@{ params ->
val move = Moves.getByName(params.getString(0)) ?: return@hasTmMoveUnlocked DoubleValue.ZERO
val tm = TechnicalMachines.moveToTM[move] ?: return@hasTmMoveUnlocked DoubleValue.ZERO
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 1.0 else 0.0)
}
functions["unlock_tm_move"] = unlockTmMove@{ params ->
val move = Moves.getByName(params.getString(0)) ?: return@unlockTmMove DoubleValue.ZERO
val tm = TechnicalMachines.moveToTM[move] ?: return@unlockTmMove DoubleValue.ZERO
player.tmList().syncTMFromMove(move)
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 1.0 else 0.0)
}
functions["lock_tm_move"] = lockTmMove@{ params ->
val move = Moves.getByName(params.getString(0)) ?: return@lockTmMove DoubleValue.ZERO
val tm = TechnicalMachines.moveToTM[move] ?: return@lockTmMove DoubleValue.ZERO
player.tmList().syncTMLockFromMove(move)
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 0.0 else 1.0)
}
functions["start_battle"] = startBattle@{ params ->
val opponentValue = params.get<MoValue>(0)
val opponent =
if (opponentValue is ObjectValue<*>) {
opponentValue.obj as ServerPlayer
} else {
val paramString = opponentValue.asString()
val playerUUID = paramString.asUUID
if (playerUUID != null) {
server()?.playerList?.getPlayer(playerUUID) ?: return@startBattle DoubleValue.ZERO
} else {
server()?.playerList?.getPlayerByName(paramString)
?: return@startBattle DoubleValue.ZERO
}
}
val format =
params
.getStringOrNull(1)
?.let(BattleFormat::fromFormatIdentifier)
?: BattleFormat.GEN_9_SINGLES
val setLevel = params.getIntOrNull(2) ?: -1
format.adjustLevel = setLevel
val rules =
params
.getStringOrNull(5)
?.split(",")
?.toSet()
?: emptySet()
val modifiedBattleFormat =
BattleFormat.setBattleRules(
battleFormat = format,
rules = rules,
)
val cloneParties = (setLevel != -1) || (params.getBooleanOrNull(3) ?: false)
val healFirst = params.getBooleanOrNull(4) ?: false
val battleStartResult =
BattleBuilder.pvp1v1(
player1 = player,
player2 = opponent,
battleFormat = modifiedBattleFormat,
cloneParties = cloneParties,
healFirst = healFirst,
)
var returnValue: MoValue = DoubleValue.ZERO
battleStartResult.ifSuccessful { returnValue = it.struct }
returnValue
}
functions["get_custom_stat"] = getCustomStat@{ params ->
val statName = params.getString(0)
val resourceLocation = ResourceLocation.tryParse(statName) ?: return@getCustomStat DoubleValue.ZERO
val statResourceLocation =
BuiltInRegistries.CUSTOM_STAT.get(resourceLocation) ?: return@getCustomStat DoubleValue.ZERO
val exists = Stats.CUSTOM.contains(statResourceLocation)
if (!exists) return@getCustomStat DoubleValue.ZERO
val stat = Stats.CUSTOM.get(statResourceLocation)
val value = player.stats.getValue(stat)
DoubleValue(value)
}
functions["get_starter_uuid"] = {
Cobblemon.playerDataManager.getGenericData(player).starterUUID?.let {
StringValue(
it.toString(),
)
} ?: DoubleValue.ZERO
}
functions["has_chosen_starter"] = {
DoubleValue(Cobblemon.playerDataManager.getGenericData(player).starterSelected)
return@put vars
}
}
map["get_npc_variable"] = put@{ params ->
val npcId = ((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
?: params.getString(0)
val variable = params.getString(1)
val data = Cobblemon.molangData.load(player.uuid, params.getStringOrNull(2))
if (data.map.containsKey(npcId)) {
return@put (data.map[npcId] as VariableStruct).map[variable] ?: DoubleValue.ZERO
} else {
return@put DoubleValue.ZERO
}
}
map["set_npc_variable"] = put@{ params ->
val npcId = ((params.get<MoValue>(0) as? ObjectValue<*>)?.obj as? NPCEntity)?.stringUUID
?: params.getString(0)
val variable = params.getString(1)
val value = params.get<MoValue>(2)
val saveAfterwards = params.getBooleanOrNull(3) != false
val path = params.getStringOrNull(4)
val data = Cobblemon.molangData.load(player.uuid, path)
val npcData = data.map.getOrPut(npcId) { VariableStruct() } as VariableStruct
npcData.map[variable] = value
if (saveAfterwards) {
Cobblemon.molangData.save(player.uuid, path)
}
return@put DoubleValue.ONE
}
map["pokedex"] = { player.pokedex().struct }
map["has_advancement"] = put@{ params ->
val requiredAdvancement = ResourceLocation.parse(params.getString(0))
for (entry in player.advancements.progress) {
if (entry.key.id == requiredAdvancement && entry.value.isDone) {
return@put DoubleValue.ONE
}
}
return@put DoubleValue.ZERO
}
map["has_tm_move_unlocked"] = put@{ params ->
val move = Moves.getByName(params.getString(0)) ?: return@put DoubleValue.ZERO
val tm = TechnicalMachines.moveToTM[move] ?: return@put DoubleValue.ZERO
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 1.0 else 0.0)
}
map["unlock_tm_move"] = put@{ params ->
val move = Moves.getByName(params.getString(0)) ?: return@put DoubleValue.ZERO
val tm = TechnicalMachines.moveToTM[move] ?: return@put DoubleValue.ZERO
player.tmList().syncTMFromMove(move)
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 1.0 else 0.0)
}
map["lock_tm_move"] = put@{ params ->
val move = Moves.getByName(params.getString(0)) ?: return@put DoubleValue.ZERO
val tm = TechnicalMachines.moveToTM[move] ?: return@put DoubleValue.ZERO
player.tmList().syncTMLockFromMove(move)
DoubleValue(if (player.tmList().learnedTMs.contains(tm.id)) 0.0 else 1.0)
}
map["start_battle"] = put@{ params ->
val opponentValue = params.get<MoValue>(0)
val opponent = if (opponentValue is ObjectValue<*>) {
opponentValue.obj as ServerPlayer
} else {
val paramString = opponentValue.asString()
val playerUUID = paramString.asUUID
if (playerUUID != null) {
server()?.playerList?.getPlayer(playerUUID) ?: return@put DoubleValue.ZERO
} else {
server()?.playerList?.getPlayerByName(paramString) ?: return@put DoubleValue.ZERO
}
}
val format = params.getStringOrNull(1)
?.let(BattleFormat::fromFormatIdentifier)
?: BattleFormat.GEN_9_SINGLES
val setLevel = params.getIntOrNull(2) ?: -1
format.adjustLevel = setLevel
val rules = params.getStringOrNull(5)
?.split(",")
?.toSet()
?: emptySet()
val modifiedBattleFormat = BattleFormat.setBattleRules(
battleFormat = format,
rules = rules
)
val cloneParties = (setLevel != -1) || (params.getBooleanOrNull(3) ?: false)
val healFirst = params.getBooleanOrNull(4) ?: false
val battleStartResult = BattleBuilder.pvp1v1(
player1 = player,
player2 = opponent,
battleFormat = modifiedBattleFormat,
cloneParties = cloneParties,
healFirst = healFirst
)
var returnValue: MoValue = DoubleValue.ZERO
battleStartResult.ifSuccessful { returnValue = it.struct }
return@put returnValue
}
map["get_custom_stat"] = put@{ 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["get_starter_uuid"] = { _ ->
Cobblemon.playerDataManager.getGenericData(player).starterUUID?.let {
StringValue(
it.toString()
)
} ?: DoubleValue.ZERO
}
map["has_chosen_starter"] = { _ -> DoubleValue(Cobblemon.playerDataManager.getGenericData(player).starterSelected) }
}
return functions
return map
}
}
@@ -27,69 +27,57 @@ import com.cobblemon.mod.common.util.getStringOrNull
object PokedexMoLangFunctions : AbstractMoLangFunctionHolder<AbstractPokedexManager>() {
override fun AbstractPokedexManager.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val pokedex = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["get_species_record"] = { params ->
val map = mutableMapOf<String, (MoParams) -> Any>()
map["get_species_record"] = { params ->
val speciesId = params.getString(0).asIdentifierDefaultingNamespace()
pokedex.speciesRecords[speciesId]?.struct ?: QueryStruct(hashMapOf())
}
functions["has_seen"] = hasSeen@{ params ->
map["has_seen"] = put@{ params ->
val speciesId = params.getString(0).asIdentifierDefaultingNamespace()
val formName =
params.getStringOrNull(1)
?: return@hasSeen DoubleValue(
pokedex.getHighestKnowledgeForSpecies(speciesId).ordinal >= PokedexEntryProgress.SEEN.ordinal,
)
val formName = params.getStringOrNull(1)
DoubleValue(
(
pokedex
.getSpeciesRecord(speciesId)
?.getFormRecord(formName)
?.knowledge
?.ordinal
?: 0
) >= PokedexEntryProgress.SEEN.ordinal,
)
}
functions["has_caught"] = hasCaught@{ params ->
val speciesId = params.getString(0).asIdentifierDefaultingNamespace()
val formName =
params.getStringOrNull(1) ?: return@hasCaught DoubleValue(
pokedex.getHighestKnowledgeForSpecies(
speciesId,
) == PokedexEntryProgress.OWNED,
if (formName == null) {
return@put DoubleValue(pokedex.getHighestKnowledgeForSpecies(speciesId).ordinal >= PokedexEntryProgress.SEEN.ordinal)
} else {
return@put DoubleValue(
(pokedex.getSpeciesRecord(speciesId)?.getFormRecord(formName)?.knowledge?.ordinal
?: 0) >= PokedexEntryProgress.SEEN.ordinal
)
DoubleValue(
pokedex
.getSpeciesRecord(speciesId)
?.getFormRecord(formName)
?.knowledge == PokedexEntryProgress.OWNED,
)
}
functions["caught_count"] = { DoubleValue(pokedex.getGlobalCalculatedValue(CaughtCount)) }
functions["seen_count"] = { DoubleValue(pokedex.getGlobalCalculatedValue(SeenCount)) }
functions["caught_percent"] = { DoubleValue(pokedex.getGlobalCalculatedValue(CaughtPercent)) }
functions["seen_percent"] = { DoubleValue(pokedex.getGlobalCalculatedValue(SeenPercent)) }
when (pokedex) {
is PokedexManager -> {
functions["player_id"] = { StringValue(pokedex.uuid.toString()) }
functions["see"] = { params ->
val pokemon = params.get<ObjectValue<Pokemon>>(0).obj
pokedex.encounter(pokemon)
DoubleValue.ONE
}
functions["catch"] = { params ->
val pokemon = params.get<ObjectValue<Pokemon>>(0).obj
pokedex.obtain(pokemon)
DoubleValue.ONE
}
}
}
return functions
map["has_caught"] = put@{ params ->
val speciesId = params.getString(0).asIdentifierDefaultingNamespace()
val formName = params.getStringOrNull(1)
if (formName == null) {
return@put DoubleValue(pokedex.getHighestKnowledgeForSpecies(speciesId) == PokedexEntryProgress.OWNED)
} else {
return@put DoubleValue(
pokedex.getSpeciesRecord(speciesId)
?.getFormRecord(formName)?.knowledge == PokedexEntryProgress.OWNED
)
}
}
map["caught_count"] = { DoubleValue(pokedex.getGlobalCalculatedValue(CaughtCount)) }
map["seen_count"] = { DoubleValue(pokedex.getGlobalCalculatedValue(SeenCount)) }
map["caught_percent"] = { DoubleValue(pokedex.getGlobalCalculatedValue(CaughtPercent)) }
map["seen_percent"] = { DoubleValue(pokedex.getGlobalCalculatedValue(SeenPercent)) }
if (pokedex is PokedexManager) {
map["player_id"] = { StringValue(pokedex.uuid.toString()) }
map["see"] = put@{ params ->
val pokemon = params.get<ObjectValue<Pokemon>>(0).obj
pokedex.encounter(pokemon)
return@put DoubleValue.ONE
}
map["catch"] = put@{ params ->
val pokemon = params.get<ObjectValue<Pokemon>>(0).obj
pokedex.obtain(pokemon)
return@put DoubleValue.ONE
}
}
return map
}
}
@@ -32,113 +32,100 @@ import com.cobblemon.mod.common.util.withQueryValue
object PokemonEntityMoLangFunctions : AbstractMoLangFunctionHolder<PokemonEntity>() {
override fun PokemonEntity.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val pokemonEntity = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["is_busy"] = { DoubleValue(pokemonEntity.isBusy) }
functions["in_battle"] = { DoubleValue(pokemonEntity.isBattling) }
functions["is_moving"] =
{ DoubleValue((pokemonEntity.moveControl as? PokemonMoveControl)?.hasWanted() == true) }
functions["is_flying"] = { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
functions["get_riding_state"] = { params ->
val map = mutableMapOf<String, (MoParams) -> Any>()
map["is_busy"] = { DoubleValue(pokemonEntity.isBusy) }
map["in_battle"] = { DoubleValue(pokemonEntity.isBattling) }
map["is_moving"] = { DoubleValue((pokemonEntity.moveControl as? PokemonMoveControl)?.hasWanted() == true) }
map["is_flying"] = { DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.FLYING)) }
map["get_riding_state"] = { params ->
val name = params.getStringOrNull(0)
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
return@ifRidingAvailableSupply moValue.functions[name]?.apply(MoParams.EMPTY) as? MoValue ?: moValue
}
}
functions["is_gliding"] = {
map["is_gliding"] = {
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
return@ifRidingAvailableSupply moValue.functions["gliding"]?.apply(MoParams.EMPTY) as? MoValue
?: DoubleValue.ZERO
}
}
functions["is_sprinting"] = {
map["is_sprinting"] = {
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
return@ifRidingAvailableSupply moValue.functions["sprinting"]?.apply(MoParams.EMPTY) as? MoValue
?: DoubleValue.ZERO
}
}
functions["is_drifting"] = {
map["is_drifting"] = {
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
return@ifRidingAvailableSupply moValue.functions["drifting"]?.apply(MoParams.EMPTY) as? MoValue
?: DoubleValue.ZERO
}
}
functions["is_powered_drifting"] = {
map["is_powered_drifting"] = {
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
return@ifRidingAvailableSupply moValue.functions["powered_drifting"]?.apply(MoParams.EMPTY) as? MoValue
?: DoubleValue.ZERO
}
}
functions["in_air"] = {
map["in_air"] = {
pokemonEntity.ifRidingAvailableSupply(DoubleValue.ZERO) { behaviour, settings, state ->
val moValue = behaviour.asMoLangValue(settings, state, pokemonEntity)
return@ifRidingAvailableSupply moValue.functions["in_air"]?.apply(MoParams.EMPTY) as? MoValue
?: DoubleValue.ZERO
}
}
functions["is_wild"] = { DoubleValue(pokemonEntity.ownerUUID == null) }
functions["is_in_party"] = {
DoubleValue(
pokemonEntity.pokemon.storeCoordinates
.get()
?.store is PartyStore,
)
map["is_wild"] = { DoubleValue(pokemonEntity.ownerUUID == null) }
map["is_in_party"] = { DoubleValue(pokemonEntity.pokemon.storeCoordinates.get()?.store is PartyStore) }
map["is_ridden"] = { DoubleValue(pokemonEntity.hasControllingPassenger()) }
map["has_aspect"] = { DoubleValue(it.getString(0) in pokemonEntity.aspects) }
map["is_pokemon"] = { DoubleValue.ONE }
map["is_holding_item"] = {
DoubleValue(!pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).let {
it.isEmpty || it.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS) || it.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)
})
}
functions["is_ridden"] = { DoubleValue(pokemonEntity.hasControllingPassenger()) }
functions["has_aspect"] = { DoubleValue(it.getString(0) in pokemonEntity.aspects) }
functions["is_pokemon"] = { DoubleValue.ONE }
functions["is_holding_item"] = {
DoubleValue(
!pokemonEntity.entityData.get(PokemonEntity.SHOWN_HELD_ITEM).let {
it.isEmpty || it.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS) || it.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)
},
)
map["riding_style"] = {
StringValue(pokemonEntity.ifRidingAvailableSupply("") { behaviour, settings, state ->
behaviour.getRidingStyle(settings, state).name
})
}
functions["riding_style"] = {
StringValue(
pokemonEntity.ifRidingAvailableSupply("") { behaviour, settings, state ->
behaviour.getRidingStyle(settings, state).name
},
)
}
functions["is_wearing_hat"] = {
map["is_wearing_hat"] = {
DoubleValue(
pokemonEntity.entityData
.get(PokemonEntity.SHOWN_HELD_ITEM)
.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS),
.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS)
)
}
functions["is_wearing_face"] = {
map["is_wearing_face"] = {
DoubleValue(
pokemonEntity.entityData
.get(PokemonEntity.SHOWN_HELD_ITEM)
.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS),
.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)
)
}
functions["is_pastured"] = {
map["is_pastured"] = {
DoubleValue((pokemonEntity.tethering != null))
}
functions["pasture_conflict_enabled"] = {
map["pasture_conflict_enabled"] = {
DoubleValue(pokemonEntity.getBehaviourFlag(PokemonBehaviourFlag.PASTURE_CONFLICT))
}
functions["run_action_effect"] = runActionEffect@{ params ->
map["run_action_effect"] = runActionEffect@{ params ->
val runtime = MoLangRuntime().setup()
runtime.environment.cloneFrom(params.environment)
runtime.withQueryValue("entity", pokemonEntity.struct)
val actionEffect = ActionEffects.actionEffects[params.getString(0).asIdentifierDefaultingNamespace()]
if (actionEffect != null) {
val context =
ActionEffectContext(
actionEffect = actionEffect,
providers = mutableListOf(TargetsProvider(pokemonEntity)),
runtime = runtime,
level = pokemonEntity.level(),
)
val context = ActionEffectContext(
actionEffect = actionEffect,
providers = mutableListOf(TargetsProvider(pokemonEntity)),
runtime = runtime,
level = pokemonEntity.level()
)
// This was taken from NPC run_action_effect but this variable isn't used, so I just commented it out.
// pokemonEntity.actionEffect = context
pokemonEntity.brain.setMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT, context)
@@ -148,16 +135,14 @@ object PokemonEntityMoLangFunctions : AbstractMoLangFunctionHolder<PokemonEntity
pokemonEntity.brain.getMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT).orElse(null)
if (pokemonActionEffect == context && pokemonEntity.brain.isActive(CobblemonActivities.ACTION_EFFECT)) {
pokemonEntity.brain.eraseMemory(CobblemonMemories.ACTIVE_ACTION_EFFECT)
// pokemonEntity.actionEffect = null
//pokemonEntity.actionEffect = null
}
}
return@runActionEffect DoubleValue.ONE
}
DoubleValue.ZERO
return@runActionEffect DoubleValue.ZERO
}
return functions
return map
}
}
@@ -33,214 +33,218 @@ import com.cobblemon.mod.common.util.getDoubleOrNull
import com.cobblemon.mod.common.util.getIntOrNull
import com.cobblemon.mod.common.util.server
import com.cobblemon.mod.common.util.toProperties
import net.minecraft.resources.ResourceLocation
import kotlin.random.Random
import net.minecraft.resources.ResourceLocation
object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
override fun Pokemon.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val pokemon = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["id"] = { StringValue(pokemon.uuid.toString()) }
functions["nickname"] = { StringValue(pokemon.nickname.toString()) }
functions["level"] = { DoubleValue(pokemon.level.toDouble()) }
functions["max_hp"] = { DoubleValue(pokemon.maxHealth.toDouble()) }
functions["current_hp"] = { DoubleValue(pokemon.currentHealth.toDouble()) }
functions["friendship"] = { DoubleValue(pokemon.friendship.toDouble()) }
functions["max_fullness"] = { DoubleValue(pokemon.getMaxFullness().toDouble()) }
functions["fullness"] = { DoubleValue(pokemon.currentFullness.toDouble()) }
functions["lose_fullness"] = { params ->
val map = mutableMapOf<String, (MoParams) -> Any>()
map["id"] = { StringValue(pokemon.uuid.toString()) }
map["nickname"] = { StringValue(pokemon.nickname.toString()) }
map["level"] = { DoubleValue(pokemon.level.toDouble()) }
map["max_hp"] = { DoubleValue(pokemon.maxHealth.toDouble()) }
map["current_hp"] = { DoubleValue(pokemon.currentHealth.toDouble()) }
map["friendship"] = { DoubleValue(pokemon.friendship.toDouble()) }
map["max_fullness"] = { DoubleValue(pokemon.getMaxFullness().toDouble()) }
map["fullness"] = { DoubleValue(pokemon.currentFullness.toDouble()) }
map["lose_fullness"] = { params ->
val amount = params.getDouble(0)
pokemon.loseFullness(amount.toInt())
}
functions["feed_pokemon"] = { params ->
map["feed_pokemon"] = { params ->
val amount = params.getDouble(0)
val playSound = params.getBooleanOrNull(1) ?: true
pokemon.feedPokemon(amount.toInt(), playSound)
}
functions["behaviour"] = { pokemon.form.behaviour.struct }
functions["behavior"] = { pokemon.form.behaviour.struct } // Inferior
functions["pokeball"] = { StringValue(pokemon.caughtBall.toString()) }
functions["ability"] = { StringValue(pokemon.ability.name) }
functions["has_learned"] = hasLearned@{ params ->
map["behaviour"] = { pokemon.form.behaviour.struct }
map["behavior"] = { pokemon.form.behaviour.struct } // Inferior
map["pokeball"] = { StringValue(pokemon.caughtBall.toString()) }
map["ability"] = { StringValue(pokemon.ability.name) }
map["has_learned"] = put@{ params ->
val moveName = params.getString(0)
val move = pokemon.allAccessibleMoves.find { it.name == moveName }
if (move != null) return@hasLearned DoubleValue.ONE
DoubleValue.ZERO
if (move != null) {
return@put DoubleValue.ONE
} else {
return@put DoubleValue.ZERO
}
}
functions["moveset"] = {
map["moveset"] = {
val struct = QueryStruct(hashMapOf())
for ((index, move) in pokemon.moveSet.withIndex()) {
struct.addFunction(index.toString()) { move.struct }
}
struct
}
functions["evs"] = {
map["evs"] = {
val struct = QueryStruct(hashMapOf())
for (stat in Stats.PERMANENT) {
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.evs.getOrDefault(stat).toDouble()) }
}
struct
}
functions["ivs"] = {
map["ivs"] = {
val struct = QueryStruct(hashMapOf())
for (stat in Stats.PERMANENT) {
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.ivs.getOrDefault(stat).toDouble()) }
}
struct
}
functions["hyper_trained_ivs"] = {
map["hyper_trained_ivs"] = {
val struct = QueryStruct(hashMapOf())
for (stat in Stats.PERMANENT) {
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.ivs.hyperTrainedIVs[stat] ?: -1.0) }
}
struct
}
functions["ride_boosts"] = {
map["ride_boosts"] = {
val struct = QueryStruct(hashMapOf())
for (stat in RidingStat.entries) {
struct.addFunction(stat.name.lowercase()) { DoubleValue(pokemon.getRideBoost(stat)) }
}
struct
}
functions["natdex_number"] = {
map["natdex_number"] = {
DoubleValue(pokemon.species.nationalPokedexNumber.toDouble())
}
functions["types"] = {
pokemon.form.types
.map { it.showdownId }
.asArrayValue(::StringValue)
map["types"] = {
pokemon.form.types.map { it.showdownId }.asArrayValue(::StringValue)
}
functions["gender_ratio"] = {
map["gender_ratio"] = {
DoubleValue(pokemon.form.maleRatio.toDouble())
}
functions["ev_yield"] = {
map["ev_yield"] = {
val struct = QueryStruct(hashMapOf())
for (stat in Stats.PERMANENT) {
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.form.evYield[stat]?.toDouble()) }
}
struct
}
functions["base_stats"] = {
map["base_stats"] = {
val struct = QueryStruct(hashMapOf())
for (stat in Stats.PERMANENT) {
struct.addFunction(stat.showdownId) { DoubleValue(pokemon.form.baseStats[stat]?.toDouble()) }
}
struct
}
functions["catch_rate"] = {
map["catch_rate"] = {
DoubleValue(pokemon.form.catchRate.toDouble())
}
functions["base_experience_yield"] = {
map["base_experience_yield"] = {
DoubleValue(pokemon.form.baseExperienceYield.toDouble())
}
functions["drops"] = {
map["drops"] = {
val struct = QueryStruct(hashMapOf())
for ((index, drop) in pokemon.form.drops.entries
.withIndex()) {
for ((index, drop) in pokemon.form.drops.entries.withIndex()) {
struct.addFunction(index.toString()) { drop }
}
struct
}
functions["tm_learnset"] = {
map["tm_learnset"] = {
val struct = QueryStruct(hashMapOf())
for ((index, move) in pokemon.form.moves.tmMoves
.withIndex()) {
for ((index, move) in pokemon.form.moves.tmMoves.withIndex()) {
struct.addFunction(index.toString()) { move.struct }
}
struct
}
functions["egg_learnset"] = {
map["egg_learnset"] = {
val struct = QueryStruct(hashMapOf())
for ((index, move) in pokemon.form.moves.eggMoves
.withIndex()) {
for ((index, move) in pokemon.form.moves.eggMoves.withIndex()) {
struct.addFunction(index.toString()) { move.struct }
}
struct
}
functions["tutor_learnset"] = {
map["tutor_learnset"] = {
val struct = QueryStruct(hashMapOf())
for ((index, move) in pokemon.form.moves.tutorMoves
.withIndex()) {
for ((index, move) in pokemon.form.moves.tutorMoves.withIndex()) {
struct.addFunction(index.toString()) { move.struct }
}
struct
}
functions["level_learnset"] = {
map["level_learnset"] = {
val struct = QueryStruct(hashMapOf())
for ((index, move) in pokemon.form.moves.levelUpMoves) {
struct.addFunction(index.toString()) { move }
}
struct
}
functions["ability_pool"] = {
map["ability_pool"] = {
val struct = QueryStruct(hashMapOf())
for ((index, ability) in pokemon.form.abilities.withIndex()) {
struct.addFunction(index.toString()) { StringValue(ability.toString()) }
}
struct
}
functions["egg_groups"] = {
map["egg_groups"] = {
val struct = QueryStruct(hashMapOf())
for ((index, group) in pokemon.form.eggGroups.withIndex()) {
struct.addFunction(index.toString()) { StringValue(group.toString()) }
}
struct
}
functions["egg_cycles"] = {
map["egg_cycles"] = {
DoubleValue(pokemon.species.eggCycles.toDouble())
}
functions["labels"] = {
map["labels"] = {
val struct = QueryStruct(hashMapOf())
for ((index, label) in pokemon.form.labels.withIndex()) {
struct.addFunction(index.toString()) { StringValue(label) }
}
struct
}
functions["aspects"] = {
map["aspects"] = {
val aspects = pokemon.aspects
aspects.asArrayValue { StringValue(it) }
}
functions["form_aspects"] = {
map["form_aspects"] = {
val aspects = pokemon.form.aspects
aspects.asArrayValue { StringValue(it) }
}
functions["form_name"] = {
map["form_name"] = {
StringValue(pokemon.form.name)
}
// Yes, this is the lazy call for a single hardcoded pre-evolution.
// Lol. Lmao, even.
// TO-DO: Subscribe to [PokemonSpecies.observable].
functions["pre_evolution"] = { pokemon.species.preEvolution ?: DoubleValue.ZERO }
functions["nature"] = { StringValue(pokemon.nature.toString()) }
functions["is_wild"] = { DoubleValue(pokemon.entity?.let { it.ownerUUID == null } == true) }
functions["is_shiny"] = { DoubleValue(pokemon.shiny) }
functions["is_in_party"] = { DoubleValue(pokemon.storeCoordinates.get()?.store is PartyStore) }
functions["species"] = { pokemon.species.struct }
functions["form"] = { StringValue(pokemon.form.name) }
functions["weight"] = { DoubleValue(pokemon.species.weight.toDouble()) }
functions["matches"] = { params -> DoubleValue(params.getString(0).toProperties().matches(pokemon)) }
functions["apply"] = { params ->
// Gito: surely this is just a typo, right? not touching the function name just in case
map["prevolution"] = preEvolution@{
val preEvolution = pokemon.species.preEvolution ?: return@preEvolution DoubleValue.ZERO
return@preEvolution preEvolution
}
map["nature"] = { StringValue(pokemon.nature.toString()) }
map["is_wild"] = { DoubleValue(pokemon.entity?.let { it.ownerUUID == null } == true) }
map["is_shiny"] = { DoubleValue(pokemon.shiny) }
map["is_in_party"] = { DoubleValue(pokemon.storeCoordinates.get()?.store is PartyStore) }
map["species"] = { pokemon.species.struct }
map["form"] = { StringValue(pokemon.form.name) }
map["weight"] = { DoubleValue(pokemon.species.weight.toDouble()) }
map["matches"] = { params -> DoubleValue(params.getString(0).toProperties().matches(pokemon)) }
map["apply"] = { params ->
params.getString(0).toProperties().apply(pokemon)
DoubleValue.ONE
}
functions["owner"] = { pokemon.getOwnerPlayer()?.asMoLangValue() ?: DoubleValue.ZERO }
functions["held_item"] = { pokemon.heldItem().asMoLangValue(server()!!.registryAccess()) }
functions["remove_held_item"] = { pokemon.removeHeldItem() }
functions["add_aspects"] = { params ->
map["owner"] = { pokemon.getOwnerPlayer()?.asMoLangValue() ?: DoubleValue.ZERO }
map["held_item"] = { pokemon.heldItem().asMoLangValue(server()!!.registryAccess()) }
map["remove_held_item"] = { _ ->
pokemon.removeHeldItem()
}
map["add_aspects"] = { params ->
for (aspect in params.params) pokemon.forcedAspects += aspect.asString()
pokemon.updateAspects()
}
functions["remove_aspects"] = { params ->
map["remove_aspects"] = { params ->
for (aspect in params.params) pokemon.forcedAspects -= aspect.asString()
pokemon.updateAspects()
}
functions["cosmetic_item"] = {
map["cosmetic_item"] = {
pokemon.cosmeticItem().asMoLangValue(server()!!.registryAccess())
}
functions["remove_cosmetic_item"] = { pokemon.removeCosmeticItem() }
functions["marks"] = { pokemon.marks.asArrayValue { StringValue(it.identifier.toString()) } }
functions["has_mark"] = { params ->
map["remove_cosmetic_item"] = { _ ->
pokemon.removeCosmeticItem()
}
map["marks"] = { _ -> pokemon.marks.asArrayValue { StringValue(it.identifier.toString()) } }
map["has_mark"] = { params ->
var hasMark = false
val identifier = params.getString(0).asIdentifierDefaultingNamespace()
val mark = Marks.getByIdentifier(identifier)
@@ -250,7 +254,7 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
DoubleValue(hasMark)
}
functions["remove_marks"] = { params ->
map["remove_marks"] = { params ->
var removedMark = false
for (param in params.params) {
val identifier = param.asString().asIdentifierDefaultingNamespace()
@@ -263,7 +267,7 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
DoubleValue(removedMark)
}
functions["add_marks"] = { params ->
map["add_marks"] = { params ->
var appliedMark = false
for (param in params.params) {
val identifier = param.asString().asIdentifierDefaultingNamespace()
@@ -276,7 +280,7 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
DoubleValue(appliedMark)
}
functions["add_marks_with_chance"] = { params ->
map["add_marks_with_chance"] = { params ->
var appliedMark = false
for (param in params.params) {
val identifier = param.asString().asIdentifierDefaultingNamespace()
@@ -294,15 +298,17 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
DoubleValue(appliedMark)
}
functions["add_potential_marks"] = { params ->
map["add_potential_marks"] = { params ->
for (param in params.params) {
val identifier = param.asString().asIdentifierDefaultingNamespace()
val mark = Marks.getByIdentifier(identifier)
if (mark != null) pokemon.addPotentialMark(mark)
}
}
functions["apply_potential_marks"] = { DoubleValue(pokemon.applyPotentialMarks()) }
functions["hyper_train_iv"] = hyperTrainIv@{ params ->
map["apply_potential_marks"] = put@{
return@put DoubleValue(pokemon.applyPotentialMarks())
}
map["hyper_train_iv"] = hyperTrainIv@{ params ->
val statId = params.getString(0)
val stat = Stats.getStat(statId)
val value = params.getIntOrNull(1) ?: IVs.MAX_VALUE
@@ -315,12 +321,12 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
return@hyperTrainIv DoubleValue.ZERO
}
}
functions["add_exp"] = { params ->
map["add_exp"] = { params ->
val exp = params.getDouble(0).toInt()
pokemon.addExperience(SidemodExperienceSource("molang"), exp)
DoubleValue.ONE
}
functions["set_iv"] = setIv@{ params ->
map["set_iv"] = setIv@{ params ->
val statId = params.getString(0)
val stat = Stats.getStat(statId)
val value = params.getIntOrNull(1)?.coerceIn(0, IVs.MAX_VALUE) ?: IVs.MAX_VALUE
@@ -332,7 +338,7 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
return@setIv DoubleValue.ZERO
}
}
functions["set_ev"] = setEv@{ params ->
map["set_ev"] = setEv@{ params ->
val statId = params.getString(0)
val stat = Stats.getStat(statId)
val value = (params.getIntOrNull(1) ?: 0).coerceIn(0, 255)
@@ -344,54 +350,49 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
return@setEv DoubleValue.ZERO
}
}
functions["set_ride_boost"] = setRideBoost@{ params ->
map["set_ride_boost"] = setRideBoost@{ params ->
val statName = params.getString(0).uppercase()
val stat =
RidingStat.entries.find { it.name.equals(statName, ignoreCase = true) }
?: return@setRideBoost DoubleValue.ZERO
val stat = RidingStat.entries.find { it.name.equals(statName, ignoreCase = true) }
?: return@setRideBoost DoubleValue.ZERO
val value = params.getDoubleOrNull(1)?.toFloat() ?: return@setRideBoost DoubleValue.ZERO
pokemon.setRideBoost(stat, value)
DoubleValue.ONE
return@setRideBoost DoubleValue.ONE
}
functions["add_ride_boost"] = addRideBoost@{ params ->
map["add_ride_boost"] = addRideBoost@{ params ->
val statName = params.getString(0).uppercase()
val stat =
RidingStat.entries.find { it.name.equals(statName, ignoreCase = true) }
?: return@addRideBoost DoubleValue.ZERO
val stat = RidingStat.entries.find { it.name.equals(statName, ignoreCase = true) }
?: return@addRideBoost DoubleValue.ZERO
val value = params.getDoubleOrNull(1)?.toFloat() ?: return@addRideBoost DoubleValue.ZERO
DoubleValue(if (pokemon.addRideBoost(stat, value)) 1.0 else 0.0)
return@addRideBoost DoubleValue(if (pokemon.addRideBoost(stat, value)) 1.0 else 0.0)
}
functions["initialize_moveset"] = initializeMoveset@{ params ->
map["initialize_moveset"] = put@{ params ->
val param = params.get<MoValue>(0) ?: StringValue(pokemon.form.defaultWildMovesetBuilder.toString())
if (param is DoubleValue) {
pokemon.initializeMoveset(param == DoubleValue.ONE)
} else {
val movesetBuilderId = ResourceLocation.parse(param.asString())
val movesetBuilder =
CobblemonMovesetBuilders.movesetBuilders[movesetBuilderId]
?: run {
Cobblemon.LOGGER.error(
"Tried initializing moveset from moveset builder ${param.asString()} but it does not exist.",
)
return@initializeMoveset DoubleValue.ZERO
}
val movesetBuilder = CobblemonMovesetBuilders.movesetBuilders[movesetBuilderId]
?: run {
Cobblemon.LOGGER.error("Tried initializing moveset from moveset builder ${param.asString()} but it does not exist.")
return@put DoubleValue.ZERO
}
pokemon.initializeMovesetFrom(movesetBuilder)
}
DoubleValue.ONE
}
functions["validate_moveset"] = { params ->
map["validate_moveset"] = { params ->
val includeLegacy = params.getBooleanOrNull(0) ?: true
pokemon.validateMoveset(includeLegacy)
DoubleValue.ONE
}
functions["teach_learnable_moves"] = { params ->
map["teach_learnable_moves"] = { params ->
val includeLegacy = params.getBooleanOrNull(0) ?: true
pokemon.teachLearnableMoves(includeLegacy)
DoubleValue.ONE
}
functions["teach_move"] = teachMove@{ params ->
map["teach_move"] = teachMove@{ params ->
val moveName = params.getString(0)
val moveTemplate = Moves.getByName(moveName) ?: return@teachMove DoubleValue.ZERO
val bypass = params.getBooleanOrNull(1) ?: false
@@ -401,9 +402,8 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
return@teachMove DoubleValue.ZERO
}
val alreadyKnows =
pokemon.moveSet.getMoves().any { it.template == moveTemplate } ||
pokemon.benchedMoves.any { it.moveTemplate == moveTemplate }
val alreadyKnows = pokemon.moveSet.getMoves().any { it.template == moveTemplate } ||
pokemon.benchedMoves.any { it.moveTemplate == moveTemplate }
if (alreadyKnows) {
return@teachMove DoubleValue.ZERO
}
@@ -416,43 +416,42 @@ object PokemonMoLangFunctions : AbstractMoLangFunctionHolder<Pokemon>() {
DoubleValue.ONE
}
functions["can_learn_move"] = canLearnMove@{ params ->
map["can_learn_move"] = canLearnMove@{ params ->
val moveName = params.getString(0)
val moveTemplate = Moves.getByName(moveName) ?: return@canLearnMove DoubleValue.ZERO
val includeLegacy = params.getBooleanOrNull(1) ?: true
val canLearn =
if (includeLegacy) {
LearnsetQuery.ANY.canLearn(moveTemplate, pokemon.form.moves)
} else {
LearnsetQuery.LEGAL.canLearn(moveTemplate, pokemon.form.moves)
}
DoubleValue(if (canLearn) 1.0 else 0.0)
val canLearn = if (includeLegacy) {
LearnsetQuery.ANY.canLearn(moveTemplate, pokemon.form.moves)
} else {
LearnsetQuery.LEGAL.canLearn(moveTemplate, pokemon.form.moves)
}
return@canLearnMove DoubleValue(if (canLearn) 1.0 else 0.0)
}
functions["unlearn_move"] = unlearnMove@{ params ->
map["unlearn_move"] = unlearnMove@{ params ->
val moveName = params.getString(0)
val moveTemplate = Moves.getByName(moveName)
if (moveTemplate != null) {
pokemon.unlearnMove(moveTemplate)
return@unlearnMove DoubleValue.ONE
} else {
return@unlearnMove DoubleValue.ZERO
}
DoubleValue.ZERO
}
functions["can_evolve"] = { DoubleValue(pokemon.evolutions.any()) }
functions["force_evolve"] = forceEvolve@{ params ->
map["can_evolve"] = { _ ->
DoubleValue(pokemon.evolutions.any())
}
map["force_evolve"] = forceEvolve@{ params ->
val idx = params.getInt(0)
val evolution =
if (idx >= 0) pokemon.evolutions.elementAtOrNull(idx) else return@forceEvolve DoubleValue.ZERO
val evolution = if (idx >= 0) pokemon.evolutions.elementAtOrNull(idx) else return@forceEvolve DoubleValue.ZERO
evolution?.forceEvolve(pokemon)
StringValue(evolution.toString())
}
functions["entity"] = { pokemon.entity?.asMoLangValue() ?: DoubleValue.ZERO }
functions["is_alpha"] = { DoubleValue(pokemon.isAlpha) }
functions["size_category"] = { StringValue(pokemon.getSizeCategory().name) }
map["entity"] = { pokemon.entity?.asMoLangValue() ?: DoubleValue.ZERO }
map["is_alpha"] = { DoubleValue(pokemon.isAlpha) }
map["size_category"] = { _ -> StringValue(pokemon.getSizeCategory().name) }
return functions
return map
}
}
@@ -20,50 +20,52 @@ import com.cobblemon.mod.common.util.getStringOrNull
object PokemonPropertiesMoLangFunctions : AbstractMoLangFunctionHolder<PokemonProperties>() {
override fun PokemonProperties.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val props = this
val functions = hashMapOf<String, (MoParams) -> Any>()
val map = mutableMapOf<String, (MoParams) -> Any>()
functions["level"] = { DoubleValue(props.level?.toDouble() ?: 0) }
functions["set_level"] = { params ->
map["level"] = { DoubleValue(props.level?.toDouble() ?: 0) }
map["set_level"] = { params ->
props.level = params.getIntOrNull(0)
DoubleValue.ONE
}
functions["shiny"] = { DoubleValue(props.shiny) }
functions["set_shiny"] = { params ->
map["shiny"] = { DoubleValue(props.shiny) }
map["set_shiny"] = { params ->
props.shiny = params.getBooleanOrNull(0)
DoubleValue.ONE
}
functions["species"] = { props.species?.let { StringValue(it) } ?: DoubleValue.ZERO }
functions["set_species"] = { params ->
map["species"] = { props.species?.let { StringValue(it) } ?: DoubleValue.ZERO }
map["set_species"] = { params ->
props.species = params.getStringOrNull(0)
DoubleValue.ONE
}
functions["gender"] = { props.gender?.let { StringValue(it.name) } ?: DoubleValue.ZERO }
functions["set_gender"] = { params ->
map["gender"] = { props.gender?.let { StringValue(it.name) } ?: DoubleValue.ZERO }
map["set_gender"] = { params ->
props.gender = params.getStringOrNull(0)?.let { Gender.valueOf(it) }
DoubleValue.ONE
}
functions["form"] = { props.form?.let { StringValue(it) } ?: DoubleValue.ZERO }
functions["ivs"] = ivs@{
map["form"] = { props.form?.let { StringValue(it) } ?: DoubleValue.ZERO }
map["ivs"] = ivs@{
val ivs = props.ivs ?: return@ivs DoubleValue.ZERO
ivs.struct
return@ivs ivs.struct
}
functions["evs"] = evs@{
map["evs"] = evs@{
val evs = props.evs ?: return@evs DoubleValue.ZERO
evs.struct
return@evs evs.struct
}
functions["friendship"] = { DoubleValue(props.friendship?.toDouble() ?: DoubleValue.ZERO) }
functions["set_friendship"] = { params ->
map["friendship"] = { DoubleValue(props.friendship?.toDouble() ?: DoubleValue.ZERO) }
map["set_friendship"] = { params ->
props.friendship = params.getIntOrNull(0)
DoubleValue.ONE
}
functions["create"] = { (props.create()).struct }
functions["to_string"] = { params ->
map["create"] = {
val pokemon = props.create()
pokemon.struct
}
map["to_string"] = { params ->
val separator = params.getStringOrNull(0) ?: " "
StringValue(props.asString(separator = separator))
}
return functions
return map
}
}
@@ -22,84 +22,83 @@ import com.cobblemon.mod.common.util.asUUID
import com.cobblemon.mod.common.util.getPlayer
import com.cobblemon.mod.common.util.toProperties
object PokemonStoreMoLangFunctions : AbstractMoLangFunctionHolder<PokemonStore<*>>() {
object PokemonStoreMoLangFunctions: AbstractMoLangFunctionHolder<PokemonStore<*>>() {
override fun PokemonStore<*>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val store = this
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["uuid"] = { StringValue(store.uuid.toString()) }
functions["add"] = { params ->
val map = mutableMapOf<String, (MoParams) -> Any>()
map["uuid"] = { StringValue(store.uuid.toString()) }
map["add"] = { params ->
val pokemon = params.get<ObjectValue<Pokemon>>(0)
DoubleValue(store.add(pokemon.obj))
}
functions["add_by_properties"] = { params ->
map["add_by_properties"] = { params ->
val props = params.getString(0).toProperties()
val player =
(store as? PlayerPartyStore)?.playerUUID?.getPlayer() // Only really know for sure when it's a player party store
val player = (store as? PlayerPartyStore)?.playerUUID?.getPlayer() // Only really know for sure when it's a player party store
val pokemon = props.create(player = player)
DoubleValue(store.add(pokemon))
}
functions["find_by_properties"] = { params ->
map["find_by_properties"] = { params ->
val props = params.getString(0).toProperties()
val pokemon = store.find { props.matches(it) }
pokemon?.asStruct() ?: DoubleValue.ZERO
}
functions["find_all_by_properties"] = { params ->
map["find_all_by_properties"] = { params ->
val props = params.getString(0).toProperties()
val pokemon = store.filter { props.matches(it) }
ArrayStruct(pokemon.mapIndexed { index, value -> "$index" to value.asStruct() }.toMap())
}
functions["find_by_id"] = { params ->
map["find_by_id"] = { params ->
val id = params.getString(0).asUUID
val pokemon = store.find { it.uuid == id }
pokemon?.asStruct() ?: DoubleValue.ZERO
}
functions["remove_by_id"] = removeById@{ params ->
map["remove_by_id"] = removeById@{ params ->
val id = params.getString(0).asUUID
val pokemon = store.find { it.uuid == id } ?: return@removeById DoubleValue.ZERO
DoubleValue(store.remove(pokemon))
return@removeById DoubleValue(store.remove(pokemon))
}
functions["average_level"] = averageLevel@{
map["average_level"] = averageLevel@{ _ ->
var numberOfPokemon = 0
var totalLevel = 0
for (pokemon in store) {
totalLevel += pokemon.level
numberOfPokemon++
}
if (numberOfPokemon == 0) return@averageLevel DoubleValue.ZERO
DoubleValue(totalLevel.toDouble() / numberOfPokemon)
if (numberOfPokemon == 0) {
return@averageLevel DoubleValue.ZERO
}
return@averageLevel DoubleValue(totalLevel.toDouble() / numberOfPokemon)
}
functions["count"] = { DoubleValue(store.count()) }
functions["count_by_properties"] = { params ->
map["count"] = { _ -> DoubleValue(store.count()) }
map["count_by_properties"] = { params ->
val props = params.getString(0).toProperties()
DoubleValue(store.count { props.matches(it) })
}
functions["highest_level"] = {
map["highest_level"] = {
val highest = store.maxOfOrNull { it.level } ?: 0
DoubleValue(highest)
}
functions["lowest_level"] = {
map["lowest_level"] = {
val lowest = store.minOfOrNull { it.level } ?: 0
DoubleValue(lowest)
}
functions["heal"] = {
map["heal"] = {
for (pokemon in store) {
pokemon.heal()
}
DoubleValue.ONE
}
functions["healing_remainder_percent"] = {
map["healing_remainder_percent"] = { _ ->
var totalPercent = 0.0f
for (pokemon in store) {
totalPercent += (1.0f - (pokemon.currentHealth.toFloat() / pokemon.maxHealth))
}
DoubleValue(totalPercent)
}
functions["has_usable_pokemon"] = { DoubleValue(store.any { !it.isFainted() }) }
functions["pokemon"] = { store.map { it.asStruct() }.asArrayValue() }
return functions
map["has_usable_pokemon"] = { _ -> DoubleValue(store.any { !it.isFainted() }) }
map["pokemon"] = {
store.map { it.asStruct() }.asArrayValue()
}
return map
}
}
@@ -25,63 +25,62 @@ import java.util.*
object ServerMoLangFunctions : AbstractMoLangFunctionHolder<MinecraftServer>() {
override fun MinecraftServer.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val server = this
val functions = hashMapOf<String, (MoParams) -> Any>()
val map = mutableMapOf<String, (MoParams) -> Any>()
functions["get_world"] = getWorld@{ params ->
val world =
server.getLevel(
ResourceKey.create(
Registries.DIMENSION,
params.getString(0).asIdentifierDefaultingNamespace(namespace = "minecraft"),
),
) ?: return@getWorld DoubleValue.ZERO
map["get_world"] = getWorld@{ params ->
val world = server.getLevel(
ResourceKey.create(
Registries.DIMENSION,
params.getString(0).asIdentifierDefaultingNamespace(namespace = "minecraft")
)
) ?: return@getWorld DoubleValue.ZERO
world
return@getWorld world
.registryAccess()
.registryOrThrow(Registries.DIMENSION)
.wrapAsHolder(world)
.asWorldMoLangValue()
}
functions["broadcast"] = { params ->
map["broadcast"] = { params ->
val message = params.getString(0)
server.playerList.broadcastSystemMessage(message.text(), params.getBooleanOrNull(1) == true)
DoubleValue.ONE
}
functions["get_player_by_uuid"] = getPlayerByUuid@{ params ->
map["get_player_by_uuid"] = getPlayerByUuid@{ params ->
val uuid = UUID.fromString(params.getString(0))
val player = server.playerList.getPlayer(uuid) ?: return@getPlayerByUuid DoubleValue.ZERO
player.asMoLangValue()
return@getPlayerByUuid player.asMoLangValue()
}
functions["get_player_by_username"] = getPlayerByUsername@{ params ->
map["get_player_by_username"] = getPlayerByUsername@{ params ->
val username = params.getString(0)
val player = server.playerList.getPlayerByName(username) ?: return@getPlayerByUsername DoubleValue.ZERO
player.asMoLangValue()
return@getPlayerByUsername player.asMoLangValue()
}
functions["data"] = { params ->
map["data"] = { params ->
Cobblemon.molangData.load(
UUID(0L, 0L),
params.getStringOrNull(0),
params.getStringOrNull(0)
)
}
functions["save_data"] = { params ->
map["save_data"] = { params ->
Cobblemon.molangData.save(
UUID(0L, 0L),
params.getStringOrNull(index = 0),
params.getStringOrNull(index = 0)
)
DoubleValue.ONE
}
// Maybe later...
// functions.put("stop") { params ->
// map.put("stop") { params ->
// Cobblemon.LOGGER.warn("Server is being stopped from a MoLang script.")
// server.stopServer()
// }
return functions
return map
}
}
@@ -20,34 +20,27 @@ import net.minecraft.server.level.ServerPlayer
object SpawnablePositionMoLangFunctions : AbstractMoLangFunctionHolder<SpawnablePosition>() {
override fun SpawnablePosition.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val spawningContext = this
val worldValue =
spawningContext
.world
.registryAccess()
.registryOrThrow(Registries.DIMENSION)
.wrapAsHolder(spawningContext.world)
.asWorldMoLangValue()
val biomeValue =
spawningContext
.biomeHolder
.asBiomeMoLangValue()
val functions = hashMapOf<String, (MoParams) -> Any>()
functions["biome"] = { biomeValue }
functions["world"] = { worldValue }
functions["light"] = { DoubleValue(spawningContext.light.toDouble()) }
functions["x"] = { DoubleValue(spawningContext.position.x.toDouble()) }
functions["y"] = { DoubleValue(spawningContext.position.y.toDouble()) }
functions["z"] = { DoubleValue(spawningContext.position.z.toDouble()) }
functions["moon_phase"] = { DoubleValue(spawningContext.moonPhase.toDouble()) }
functions["can_see_sky"] = { DoubleValue(spawningContext.canSeeSky) }
functions["sky_light"] = { DoubleValue(spawningContext.skyLight.toDouble()) }
functions["player"] = player@{
val causeEntity = spawningContext.cause.entity ?: return@player DoubleValue.ZERO
if (causeEntity is ServerPlayer) return@player causeEntity.asMoLangValue()
DoubleValue.ZERO
val map = mutableMapOf<String, (MoParams) -> Any>()
val worldValue = spawningContext.world.registryAccess().registryOrThrow(Registries.DIMENSION)
.wrapAsHolder(spawningContext.world).asWorldMoLangValue()
val biomeValue = spawningContext.biomeHolder.asBiomeMoLangValue()
map["biome"] = { _ -> biomeValue }
map["world"] = { _ -> worldValue }
map["light"] = { _ -> DoubleValue(spawningContext.light.toDouble()) }
map["x"] = { _ -> DoubleValue(spawningContext.position.x.toDouble()) }
map["y"] = { _ -> DoubleValue(spawningContext.position.y.toDouble()) }
map["z"] = { _ -> DoubleValue(spawningContext.position.z.toDouble()) }
map["moon_phase"] = { _ -> DoubleValue(spawningContext.moonPhase.toDouble()) }
map["can_see_sky"] = { _ -> DoubleValue(spawningContext.canSeeSky) }
map["sky_light"] = { _ -> DoubleValue(spawningContext.skyLight.toDouble()) }
map["player"] = put@{ _ ->
val causeEntity = spawningContext.cause.entity ?: return@put DoubleValue.ZERO
if (causeEntity is ServerPlayer) {
return@put causeEntity.asMoLangValue()
} else {
return@put DoubleValue.ZERO
}
}
return functions
return map
}
}
@@ -17,23 +17,23 @@ import com.cobblemon.mod.common.util.asArrayValue
object SpeciesMoLangFunctions : AbstractMoLangFunctionHolder<Species>() {
override fun Species.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val species = this
val functions = hashMapOf<String, (MoParams) -> Any>()
val map = mutableMapOf<String, (MoParams) -> Any>(
"identifier" to { StringValue(species.resourceIdentifier.toString()) },
"name" to { StringValue(species.name) },
"primary_type" to { StringValue(species.primaryType.showdownId) },
"secondary_type" to { StringValue(species.secondaryType?.showdownId ?: "null") },
"experience_group" to { StringValue(species.experienceGroup.name) },
"height" to { DoubleValue(species.height) },
"weight" to { DoubleValue(species.weight) },
"base_scale" to { DoubleValue(species.baseScale) },
"hitbox_width" to { DoubleValue(species.hitbox.width) },
"hitbox_height" to { DoubleValue(species.hitbox.height) },
"hitbox_fixed" to { DoubleValue(species.hitbox.fixed) },
"catch_rate" to { DoubleValue(species.catchRate) },
"labels" to { species.labels.asArrayValue { StringValue(it) } },
"has_label" to { params -> DoubleValue(species.labels.contains(params.getString(0))) }
)
functions["identifier"] = { StringValue(species.resourceIdentifier.toString()) }
functions["name"] = { StringValue(species.name) }
functions["primary_type"] = { StringValue(species.primaryType.showdownId) }
functions["secondary_type"] = { StringValue(species.secondaryType?.showdownId ?: "null") }
functions["experience_group"] = { StringValue(species.experienceGroup.name) }
functions["height"] = { DoubleValue(species.height) }
functions["weight"] = { DoubleValue(species.weight) }
functions["base_scale"] = { DoubleValue(species.baseScale) }
functions["hitbox_width"] = { DoubleValue(species.hitbox.width) }
functions["hitbox_height"] = { DoubleValue(species.hitbox.height) }
functions["hitbox_fixed"] = { DoubleValue(species.hitbox.fixed) }
functions["catch_rate"] = { DoubleValue(species.catchRate) }
functions["labels"] = { species.labels.asArrayValue { StringValue(it) } }
functions["has_label"] = { params -> DoubleValue(species.labels.contains(params.getString(0))) }
return functions
return map
}
}
@@ -24,6 +24,7 @@ import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormParticlePacket
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
import com.cobblemon.mod.common.util.*
import java.util.UUID
import net.minecraft.core.BlockPos
import net.minecraft.core.Holder
import net.minecraft.core.registries.Registries
@@ -45,89 +46,85 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
import net.minecraft.world.phys.AABB
import net.minecraft.world.phys.Vec3
import java.util.UUID
object WorldMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Level>>() {
override fun Holder<Level>.moLangFunctions(): MutableMap<String, (MoParams) -> Any> {
val world = this.value()
val functions = hashMapOf<String, (MoParams) -> Any>()
val map = mutableMapOf<String, (MoParams) -> Any>(
)
functions["is_time_of_day"] = isTimeOfDay@{ params ->
val timeOfDay =
TimeRange.timeRanges[params.getString(0).lowercase()]
?: return@isTimeOfDay DoubleValue.ZERO
map["is_time_of_day"] = put@{ params ->
val timeOfDay = TimeRange.timeRanges[params.getString(0).lowercase()]
?: return@put DoubleValue.ZERO
val time = world.dayTime % 24000
DoubleValue(timeOfDay.contains(time.toInt()))
return@put DoubleValue(timeOfDay.contains(time.toInt()))
}
functions["game_time"] = { DoubleValue(world.gameTime.toDouble()) }
functions["time_of_day"] = { DoubleValue((world.dayTime % 24000).toDouble()) }
functions["server"] = { server()?.asMoLangValue() ?: DoubleValue.ZERO }
functions["is_raining_at"] = { params ->
map["game_time"] = { _ -> DoubleValue(world.gameTime.toDouble()) }
map["time_of_day"] = put@{
val time = world.dayTime % 24000
return@put DoubleValue(time.toDouble())
}
map["server"] = { _ -> server()?.asMoLangValue() ?: DoubleValue.ZERO }
map["is_raining_at"] = put@{ params ->
val x = params.getInt(0)
val y = params.getInt(1)
val z = params.getInt(2)
DoubleValue(world.isRainingAt(BlockPos(x, y, z)))
return@put DoubleValue(world.isRainingAt(BlockPos(x, y, z)))
}
functions["is_snowing_at"] = { params ->
map["is_snowing_at"] = put@{ params ->
val x = params.getInt(0)
val y = params.getInt(1)
val z = params.getInt(2)
val blockPos = BlockPos(x, y, z)
when {
!world.isRaining -> {
DoubleValue.ZERO
}
!world.canSeeSky(blockPos) -> {
DoubleValue.ZERO
}
!world.isRaining -> return@put DoubleValue.ZERO
!world.canSeeSky(blockPos) -> return@put DoubleValue.ZERO
(world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, blockPos).y > blockPos.y) -> {
DoubleValue.ZERO
return@put DoubleValue.ZERO
}
else -> {
val biome = world.getBiome(blockPos).value() as Biome
DoubleValue(biome.getPrecipitationAt(blockPos) == Biome.Precipitation.SNOW)
return@put DoubleValue(biome.getPrecipitationAt(blockPos) == Biome.Precipitation.SNOW)
}
}
}
functions["is_chunk_loaded_at"] = { params ->
map["is_chunk_loaded_at"] = put@{ params ->
val x = params.getInt(0)
val y = params.getInt(1)
val z = params.getInt(2)
DoubleValue(world.isLoaded(BlockPos(x, y, z)))
return@put DoubleValue(world.isLoaded(BlockPos(x, y, z)))
}
functions["is_thundering"] = { DoubleValue(world.isThundering) }
functions["is_raining"] = { DoubleValue(world.isRaining) }
functions["set_block"] = setBlock@{ params ->
map["is_thundering"] = { _ -> DoubleValue(world.isThundering) }
map["is_raining"] = { _ -> DoubleValue(world.isRaining) }
map["set_block"] = put@{ params ->
val x = params.getInt(0)
val y = params.getInt(1)
val z = params.getInt(2)
val block =
world.blockRegistry.get(params.getString(3).asIdentifierDefaultingNamespace())
?: run {
Cobblemon.LOGGER.error("Unknown block: ${params.getString(3)}")
return@setBlock DoubleValue.ZERO
}
val block = world.blockRegistry.get(params.getString(3).asIdentifierDefaultingNamespace())
?: run {
Cobblemon.LOGGER.error("Unknown block: ${params.getString(3)}")
return@put DoubleValue.ZERO
}
world.setBlock(BlockPos(x, y, z), block.defaultBlockState(), Block.UPDATE_ALL)
}
functions["is_air"] = { params ->
map["is_air"] = put@{ params ->
val x = params.getDouble(0).toInt()
val y = params.getDouble(1).toInt()
val z = params.getDouble(2).toInt()
val blockState = world.getBlockState(BlockPos(x, y, z))
DoubleValue(blockState.isAir)
return@put DoubleValue(blockState.isAir)
}
functions["get_block"] = { params ->
map["get_block"] = put@{ params ->
val x = params.getInt(0)
val y = params.getInt(1)
val z = params.getInt(2)
val block = world.getBlockState(BlockPos(x, y, z)).block
world.blockRegistry.wrapAsHolder(block).asMoLangValue(Registries.BLOCK)
return@put world.blockRegistry.wrapAsHolder(block).asMoLangValue(Registries.BLOCK)
}
functions["spawn_explosion"] = { params ->
map["spawn_explosion"] = { params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
@@ -139,33 +136,32 @@ object WorldMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Level>>() {
z,
range,
ExplosionInteraction.valueOf(
params.getStringOrNull(4)?.uppercase() ?: ExplosionInteraction.TNT.name,
),
params.getStringOrNull(4)?.uppercase() ?: ExplosionInteraction.TNT.name
)
)
}
functions["spawn_lightning"] = { params ->
map["spawn_lightning"] = put@{ params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
val lightning = LightningBolt(EntityType.LIGHTNING_BOLT, world)
lightning.setPos(x, y, z)
world.addFreshEntity(lightning)
DoubleValue.ONE
return@put DoubleValue.ONE
}
// q.entity.world.spawn_bedrock_particles(effect, x, y, z, [player]) - sends to everyone nearby or just to the player if they're set.
functions["spawn_bedrock_particles"] = { params ->
map["spawn_bedrock_particles"] = { params ->
val particle = params.getString(0).asResource()
val x = params.getDouble(1)
val y = params.getDouble(2)
val z = params.getDouble(3)
val player =
params.getOrNull<MoValue>(4)?.let {
when (it) {
is StringValue -> world.getPlayerByUUID(UUID.fromString(it.value))
is ObjectValue<*> -> it.obj
else -> null
}
} as? ServerPlayer
val player = params.getOrNull<MoValue>(4)?.let {
when (it) {
is StringValue -> world.getPlayerByUUID(UUID.fromString(it.value))
is ObjectValue<*> -> it.obj
else -> null
}
} as? ServerPlayer
val pos = Vec3(x, y, z)
val packet = SpawnSnowstormParticlePacket(particle, pos)
@@ -175,7 +171,7 @@ object WorldMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Level>>() {
packet.sendToPlayersAround(x, y, z, 64.0, world.dimension())
}
}
functions["spawn_pokemon"] = spawnPokemon@{ params ->
map["spawn_pokemon"] = put@{ params ->
val x = params.getInt(0)
val y = params.getInt(1)
val z = params.getInt(2)
@@ -183,50 +179,49 @@ object WorldMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Level>>() {
val pos = BlockPos(x, y, z)
if (!Level.isInSpawnableBounds(pos)) return@spawnPokemon DoubleValue.ZERO
if (!Level.isInSpawnableBounds(pos)) {
return@put DoubleValue.ZERO
}
val pokemon = props.createEntity(world)
pokemon.moveTo(pos, pokemon.yRot, pokemon.xRot)
if (world.addFreshEntity(pokemon)) return@spawnPokemon pokemon.struct
DoubleValue.ZERO
if (world.addFreshEntity(pokemon)) {
return@put pokemon.struct
} else {
return@put DoubleValue.ZERO
}
}
functions["spawn_npc"] = spawnNpc@{ params ->
map["spawn_npc"] = put@{ params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
val npcClass =
params
.getStringOrNull(3)
?.let { NPCClasses.getByIdentifier(it.asIdentifierDefaultingNamespace()) }
val npcClass = params.getStringOrNull(3)
?.let { NPCClasses.getByIdentifier(it.asIdentifierDefaultingNamespace()) }
val level = params.getInt(4)
if (npcClass == null) return@spawnNpc DoubleValue.ZERO
if (npcClass == null) return@put DoubleValue.ZERO
val npc = NPCEntity(world)
npc.moveTo(x, y, z, npc.yRot, npc.xRot)
npc.npc = npcClass
npc.initialize(level)
if (world.addFreshEntity(npc)) return@spawnNpc npc.asMoLangValue()
DoubleValue.ZERO
if (world.addFreshEntity(npc)) {
return@put npc.asMoLangValue()
}
return@put DoubleValue.ZERO
}
functions["play_sound_on_server"] = { params ->
map["play_sound_on_server"] = { params ->
val sound = params.getString(0).asResource()
val soundSource = params.getString(1).uppercase()
val x = params.getDouble(2)
val y = params.getDouble(3)
val z = params.getDouble(4)
val player =
params.getOrNull<MoValue>(5)?.let {
when (it) {
is StringValue -> world.getPlayerByUUID(UUID.fromString(it.value))
is ObjectValue<*> -> it.obj
else -> null
}
} as? ServerPlayer
val player = params.getOrNull<MoValue>(5)?.let {
when (it) {
is StringValue -> world.getPlayerByUUID(UUID.fromString(it.value))
is ObjectValue<*> -> it.obj
else -> null
}
} as? ServerPlayer
val volume = params.getDoubleOrNull(6)?.toFloat() ?: 1.0f
val pitch = params.getDoubleOrNull(7)?.toFloat() ?: 1.0f
@@ -238,30 +233,29 @@ object WorldMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Level>>() {
packet.sendToPlayersAround(x, y, z, 16.0, world.dimension())
}
}
functions["get_entities_around"] = { params ->
map["get_entities_around"] = put@{ params ->
val x = params.getDouble(0)
val y = params.getDouble(1)
val z = params.getDouble(2)
val range = params.getDouble(3) * 2
val entities = world.getEntities(null, AABB.ofSize(Vec3(x, y, z), range, range, range))
entities
return@put entities
.filterIsInstance<LivingEntity>()
.map { it.asMostSpecificMoLangValue() }
.asArrayValue()
}
functions["is_healer_in_use"] = isHealerInUse@{ params ->
map["is_healer_in_use"] = put@{ params ->
val pos = params.get<ArrayStruct>(0).asBlockPos()
val healer =
world.getBlockEntity(pos, CobblemonBlockEntities.HEALING_MACHINE).orElse(null)
?: return@isHealerInUse DoubleValue.ONE
return@isHealerInUse DoubleValue(healer.isInUse)
val healer = world.getBlockEntity(pos, CobblemonBlockEntities.HEALING_MACHINE).orElse(null)
?: return@put DoubleValue.ONE
return@put DoubleValue(healer.isInUse)
}
functions["spawn_loot_table_items"] = spawnLootTableItems@{ params ->
map["spawn_loot_table_items"] = put@{ params ->
val serverLevel = world as? ServerLevel
if (serverLevel == null) {
Cobblemon.LOGGER.warn("spawn_loot_table_items: world is not a ServerLevel")
return@spawnLootTableItems DoubleValue.ZERO
return@put DoubleValue.ZERO
}
val lootTableId = params.getString(0).asIdentifierDefaultingNamespace()
val x = params.getDouble(1)
@@ -271,11 +265,9 @@ object WorldMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Level>>() {
val lootTableKey = ResourceKey.create(Registries.LOOT_TABLE, lootTableId)
val lootTable = serverLevel.server.reloadableRegistries().getLootTable(lootTableKey)
val lootParams =
LootParams
.Builder(serverLevel)
.withParameter(LootContextParams.ORIGIN, Vec3(x, y, z))
.create(LootContextParamSets.COMMAND)
val lootParams = LootParams.Builder(serverLevel)
.withParameter(LootContextParams.ORIGIN, Vec3(x, y, z))
.create(LootContextParamSets.COMMAND)
val items = lootTable.getRandomItems(lootParams)
val spawnedItems = ArrayStruct(hashMapOf())
@@ -293,10 +285,9 @@ object WorldMoLangFunctions : AbstractMoLangFunctionHolder<Holder<Level>>() {
}
}
}
spawnedItems
return@put spawnedItems
}
return functions
return map
}
}
@@ -269,7 +269,7 @@ object PokeBalls : JsonDataRegistry<PokeBall> {
createDefault("dive_ball", CatchRateModifiers.SUBMERGED_IN_WATER, waterDragValue = 0.99F)
createDefault("nest_ball", CatchRateModifiers.NEST)
createDefault("repeat_ball", CatchRateModifiers.REPEAT)
createDefault("timer_ball", CatchRateModifiers.turnBased { turn -> (1F + turn * (1229F / 4096F)).coerceAtMost(4F) })
createDefault("timer_ball", CatchRateModifiers.turnBased { turn -> (1F * turn * (1229F / 4096F)).coerceAtMost(4F) })
createDefault("luxury_ball", effects = listOf(FriendshipEarningBoostEffect(2F)))
createDefault("premier_ball")
createDefault("dusk_ball", CatchRateModifiers.LIGHT_LEVEL)
@@ -278,7 +278,7 @@ object PokeBalls : JsonDataRegistry<PokeBall> {
createDefault("cherish_ball")
createDefault("park_ball", CatchRateModifiers.PARK)
createDefault("dream_ball", CatchRateModifiers.statusBoosting(4F, Statuses.SLEEP))
createDefault("beast_ball", DynamicMultiplierModifier({ _, pokemon -> if (pokemon.hasLabels(CobblemonPokemonLabels.ULTRA_BEAST)) 5F else 0.1F }) { _, _ -> true })
createDefault("beast_ball", LabelModifier(5F, true, CobblemonPokemonLabels.ULTRA_BEAST)/*, LabelModifier(0.1F, false, CobblemonPokemonLabels.ULTRA_BEAST))*/)
createDefault("ancient_poke_ball", ancient = true)
createDefault("ancient_citrine_ball", ancient = true)
createDefault("ancient_verdant_ball", ancient = true)
@@ -297,15 +297,13 @@ object PokeBalls : JsonDataRegistry<PokeBall> {
createDefault("ancient_origin_ball", GuaranteedModifier(), ancient = true)
// Luxury ball effect, low priority as it must be triggered before soothe bell as of gen 4
CobblemonEvents.FRIENDSHIP_UPDATED.subscribe(priority = Priority.LOW) { event ->
if (!event.earned) {
return@subscribe
}
var increment = (event.newFriendship - event.pokemon.friendship).toFloat()
if (increment <= 0) {
if (increment <= 0) //these affects are only meant to affect positive gains
return@subscribe
if (increment <= 1F) {
event.pokemon.caughtBall.effects.filterIsInstance<FriendshipEarningBoostEffect>()
.forEach { increment *= it.multiplier }
}
event.pokemon.caughtBall.effects.filterIsInstance<FriendshipEarningBoostEffect>()
.forEach { increment *= it.multiplier }
event.newFriendship = event.pokemon.friendship + increment.roundToInt()
}
}
@@ -340,6 +338,7 @@ object PokeBalls : JsonDataRegistry<PokeBall> {
ancient: Boolean = false
): PokeBall {
val identifier = cobblemonResource(name)
//val finalModifiers = if (appendUltraBeastPenalty) modifiers + listOf(LabelModifier(0.1F, true, CobblemonPokemonLabels.ULTRA_BEAST)) else modifiers
val pokeball = PokeBall(identifier, modifier, effects, waterDragValue, model2d, model3d, throwPower, ancient)
this.defaults[identifier] = pokeball
return pokeball
@@ -54,20 +54,22 @@ object CatchRateModifiers {
/**
* Used by [PokeBalls.LOVE_BALL].
* Boosts the catch rate 2.5× if any of the player's active Pokémon is of the opposite gender,
* or 8× if that Pokémon is also of the same species.
* Boosts the catch rate if the Pokémon is of the same species and opposite gender
*/
val LOVE = BattleModifier { _, playerPokemon, pokemon ->
if (pokemon.gender == Gender.GENDERLESS) {
return@BattleModifier 1F
if (
pokemon.gender != Gender.GENDERLESS
&& playerPokemon.mapNotNull { it.battlePokemon?.originalPokemon }
.any {
it.gender != Gender.GENDERLESS &&
it.species.name.equals(pokemon.species.name, true) &&
it.gender != pokemon.gender
}
) {
if (playerPokemon.any { it.battlePokemon?.originalPokemon?.species?.resourceIdentifier == pokemon.species.resourceIdentifier }) 8F else 2.5F
}
val oppositeGender = playerPokemon
.mapNotNull { it.battlePokemon?.originalPokemon }
.filter { it.gender != Gender.GENDERLESS && it.gender != pokemon.gender }
when {
oppositeGender.any { it.species.resourceIdentifier == pokemon.species.resourceIdentifier } -> 8F
oppositeGender.isNotEmpty() -> 2.5F
else -> 1F
else {
1F
}
}
@@ -79,7 +81,7 @@ object CatchRateModifiers {
* 1× otherwise.
*/
val MOON_PHASES: CatchRateModifier = WorldStateModifier { _, entity ->
if (entity.level().dayTime % 24000 < 12000)
if (entity.level().gameTime in 12000..24000)
return@WorldStateModifier 1F
when (entity.level().moonPhase) {
2, 6 -> 1.5F
@@ -42,7 +42,7 @@ class PokedexManager(
}
// Java interop isn't great lol
@Deprecated("Use obtain(Pokemon) instead")
@Deprecated("Use encounter(PokedexEntityData) instead")
fun catch(pokemon: Pokemon) {
obtain(pokemon)
}
@@ -54,8 +54,8 @@ enum class Stats(override val identifier: ResourceLocation, override val display
"hp" -> HP
"atk", "attack" -> ATTACK // Hyper Cutter states the full stat name "Attack"
"def", "defense", "defence" -> DEFENCE // Big Pecks states the full stat name "Defense"
"spa", "special_attack" -> SPECIAL_ATTACK
"spd", "special_defence", "special_defense" -> SPECIAL_DEFENCE
"spa" -> SPECIAL_ATTACK
"spd" -> SPECIAL_DEFENCE
"spe", "speed" -> SPEED
"evasion" -> EVASION
else -> ACCURACY
@@ -71,7 +71,7 @@ class FishingSpawnCause(
}
fun alterSize(pokemonEntity: PokemonEntity, effect: SpawnBait.Effect) {
pokemonEntity.pokemon.scaleModifier += effect.value.toFloat() / 1000.0f
pokemonEntity.pokemon.scaleModifier *= effect.value.toFloat() / 1000.0f
}
fun saveDropsReroll(pokemonEntity: PokemonEntity, effect: SpawnBait.Effect) {
@@ -17,10 +17,10 @@ import com.cobblemon.mod.common.api.storage.factory.PokemonStoreFactory
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.DataKeys
import com.google.gson.JsonObject
import java.util.UUID
import net.minecraft.core.RegistryAccess
import net.minecraft.nbt.CompoundTag
import net.minecraft.server.level.ServerPlayer
import java.util.UUID
/**
* The base class for all stores of [Pokemon]. A store specifies the kind of coordinate it needs to be given
@@ -77,6 +77,7 @@ abstract class PokemonStore<T : StorePosition> : Iterable<Pokemon> {
remove(pokemon)
val position = getFirstAvailablePosition() ?: return false // Couldn't fit, shrug emoji
set(position, pokemon)
Cobblemon.playerDataManager.getTMData(uuid)?.syncTMsFromPokemon(pokemon)
return true
}
@@ -8,7 +8,6 @@
package com.cobblemon.mod.common.block
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.api.tags.CobblemonBlockTags
import com.cobblemon.mod.common.block.TypeGemClusterBlock.Companion.SHOULD_GROW
@@ -34,9 +33,6 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
const val MIN_DISTANCE_BETWEEN_GEMS = 1
const val CONTINUATION_CHANCE = 0.8f
// Upper safety check to prevent infinite loops
const val MAX_FORCE_GROW_ATTEMPTS = 64
val BLOCK_TO_CLUSTER: Map<ResourceLocation, Block> by lazy {
mapOf(
ResourceLocation.parse("cobblemon:normal_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_NORMAL,
@@ -116,16 +112,13 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
fun forceGrow(level: WorldGenLevel, pos: BlockPos, random: RandomSource, percentage: Float) {
val desiredLength = MAX_CONNECTED_GEMS * percentage
repeat(MAX_FORCE_GROW_ATTEMPTS) {
val (grown, clusterSize) = grow(level, pos, random, true)
if (!grown || clusterSize >= desiredLength) return
}
while (true) {
val growInfo = grow(level, pos, random, true)
val grown = growInfo.first
val clusterSize = growInfo.second
Cobblemon.LOGGER.warn(
"Forced type gem growth at {} stopped after {} attempts without reaching its target size; keeping the partial formation.",
pos,
MAX_FORCE_GROW_ATTEMPTS
)
if (!grown || clusterSize >= desiredLength) break
}
}
private fun grow(
@@ -137,7 +130,7 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
val connectedGems = getConnectedGemBlocks(level, pos) // maybe we can store this and access it for better performance? check for changes in list rather than checking each time grow is called? idk
val gemCount = connectedGems.size
val overLimit = gemCount >= MAX_CONNECTED_GEMS
if (overLimit) {
// if there is no open air pockets to grow any new clusters then exit early
if (!hasBreathingRoom(level, connectedGems)) {
@@ -172,11 +165,6 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
level.setBlock(targetPos, placeState, UPDATE_ALL)
// During world gen, the region silently discards writes into neighboring chunks that are already fully generated.
// Through ImposterProtoChunk with writes set to disabled. Checks if the block is still air after the write and skips if so as it can't be filled.
// Preventing infinite loops.
if (!level.getBlockState(targetPos).`is`(clusterBlock)) continue
if (forced) {
forceAdvanceClusterGrowth(level, targetPos, random)
}
@@ -222,4 +210,4 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
}
override fun isRandomlyTicking(state: BlockState): Boolean = true
}
}
@@ -21,10 +21,7 @@ object SetActiveTMPacketHandler : ServerNetworkPacketHandler<SetActiveTMPacket>
val menu = player.containerMenu as? TMMachineMenu ?: return
val tmData = Cobblemon.playerDataManager.getTMData(player)
if (packet.tm != null
&& !Cobblemon.config.unlockAllMoveDexMovesByDefault
&& !packet.tm.isPassivelyObtained()
&& packet.tm.id !in tmData.learnedTMs) {
if (packet.tm != null && (!packet.tm.isPassivelyObtained() && packet.tm.id !in tmData.learnedTMs)) {
return // Hacker smh
}
@@ -40,8 +40,7 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent<T, PlayerModel<T>>) :
RenderLayer<T, PlayerModel<T>>(renderLayerParent) {
class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent<T, PlayerModel<T>>) : RenderLayer<T, PlayerModel<T>>(renderLayerParent) {
val context = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.WORLD)
@@ -69,62 +68,19 @@ class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent
// It's unclear why Minecraft's providing a partial ticks based on 60FPS regardless of the real FPS.
// Whatever - the delta manager works correctly.
val realPartialTicks = Minecraft.getInstance().timer.realtimeDeltaTicks
this.render(
matrixStack,
buffer,
packedLight,
livingEntity,
limbSwing,
limbSwingAmount,
realPartialTicks,
ageInTicks,
netHeadYaw,
headPitch,
true
)
this.render(
matrixStack,
buffer,
packedLight,
livingEntity,
limbSwing,
limbSwingAmount,
realPartialTicks,
ageInTicks,
netHeadYaw,
headPitch,
false
)
this.render(matrixStack, buffer, packedLight, livingEntity, limbSwing, limbSwingAmount, realPartialTicks, ageInTicks, netHeadYaw, headPitch, true)
this.render(matrixStack, buffer, packedLight, livingEntity, limbSwing, limbSwingAmount, realPartialTicks, ageInTicks, netHeadYaw, headPitch, false)
}
fun configureState(
state: FloatingState,
model: PosableModel,
leftShoulder: Boolean,
shoulderData: ShoulderData
): FloatingState {
fun configureState(state: FloatingState, model: PosableModel, leftShoulder: Boolean, shoulderData: ShoulderData): FloatingState {
state.currentModel = model
state.setPoseToFirstSuitable(if (leftShoulder) PoseType.SHOULDER_LEFT else PoseType.SHOULDER_RIGHT)
state.runtime.environment.query.addFunction("is_holding_item") {
return@addFunction DoubleValue(shoulderData.shownItem.let {
!it.isEmpty && !it.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS) && !it.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)
})
}
state.runtime.environment.query.addFunction("is_wearing_hat") {
return@addFunction DoubleValue(
shoulderData.shownItem.`is`(
CobblemonItemTags.WEARABLE_HAT_ITEMS
)
)
}
state.runtime.environment.query.addFunction("is_wearing_face") {
return@addFunction DoubleValue(
shoulderData.shownItem.`is`(
CobblemonItemTags.WEARABLE_FACE_ITEMS
)
)
}
state.runtime.environment.query.addFunction("is_holding_item") { return@addFunction DoubleValue(shoulderData.shownItem.let {
!it.isEmpty && !it.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS) && !it.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)
}) }
state.runtime.environment.query.addFunction("is_wearing_hat") { return@addFunction DoubleValue(shoulderData.shownItem.`is`(CobblemonItemTags.WEARABLE_HAT_ITEMS)) }
state.runtime.environment.query.addFunction("is_wearing_face") { return@addFunction DoubleValue(shoulderData.shownItem.`is`(CobblemonItemTags.WEARABLE_FACE_ITEMS)) }
return state
}
@@ -144,12 +100,12 @@ class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent
) {
val compoundTag = if (pLeftShoulder) livingEntity.shoulderEntityLeft else livingEntity.shoulderEntityRight
if (compoundTag.isPokemonEntity()) {
livingEntity.level().profiler.push("shoulder_render_".plus(if (pLeftShoulder) "left" else "right"))
livingEntity.level().profiler.push("shoulder_render_".plus(if(pLeftShoulder) "left" else "right"))
val cache = playerCache.getOrPut(livingEntity.uuid) { ShoulderCache() }
val shoulderData = shoulderDataFrom(compoundTag)
if (pLeftShoulder) cache.lastKnownLeft = shoulderData else cache.lastKnownRight = shoulderData
if (shoulderData == null) {
if (shoulderData == null){
// Nothing to do
return
}
@@ -181,11 +137,11 @@ class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent
matrixStack.scale(scale, scale, scale)
matrixStack.translate(0f, 1.5f, 0f)
state = if (pLeftShoulder && !shoulderData.matches(lastRenderedLeft)) {
state = if (pLeftShoulder && shoulderData != lastRenderedLeft) {
leftState = configureState(state, model, true, shoulderData)
lastRenderedLeft = shoulderData
leftState
} else if (!pLeftShoulder && !shoulderData.matches(lastRenderedRight)) {
} else if (!pLeftShoulder && shoulderData != lastRenderedRight) {
rightState = configureState(state, model, false, shoulderData)
lastRenderedRight = shoulderData
rightState
@@ -195,14 +151,7 @@ class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent
state.updatePartialTicks(partialTicks)
context.put(RenderContext.POSABLE_STATE, state)
state.currentModel = model
val vertexConsumer = buffer.getBuffer(
RenderType.entityCutout(
VaryingModelRepository.getTexture(
shoulderData.species.resourceIdentifier,
state
)
)
)
val vertexConsumer = buffer.getBuffer(RenderType.entityCutout(VaryingModelRepository.getTexture(shoulderData.species.resourceIdentifier, state)))
val i = LivingEntityRenderer.getOverlayCoords(livingEntity, 0.0f)
model.applyAnimations(
@@ -215,11 +164,7 @@ class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent
ageInTicks = livingEntity.tickCount.toFloat()
)
model.render(context, matrixStack, vertexConsumer, packedLight, i, -0x1)
model.withLayerContext(
buffer,
state,
VaryingModelRepository.getLayers(shoulderData.species.resourceIdentifier, state)
) {
model.withLayerContext(buffer, state, VaryingModelRepository.getLayers(shoulderData.species.resourceIdentifier, state)) {
model.render(context, matrixStack, vertexConsumer, packedLight, OverlayTexture.NO_OVERLAY, -0x1)
}
@@ -234,7 +179,8 @@ class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent
model.setDefault()
matrixStack.popPose()
livingEntity.level().profiler.pop()
} else {
}
else {
val entry = playerCache.getOrPut(livingEntity.uuid) { ShoulderCache() }
if (pLeftShoulder) entry.lastKnownLeft = null else entry.lastKnownRight = null
}
@@ -245,21 +191,14 @@ class PokemonOnShoulderRenderer<T : Player>(renderLayerParent: RenderLayerParent
var lastKnownRight: ShoulderData? = null
)
class ShoulderData(
data class ShoulderData(
val uuid: UUID,
val species: Species,
val form: FormData,
val aspects: Set<String>,
val scaleModifier: Float,
val shownItem: ItemStack,
) {
fun matches(other: ShoulderData?): Boolean = other != null
&& uuid == other.uuid
&& species == other.species
&& form == other.form
&& aspects == other.aspects
&& shownItem.item == other.shownItem.item
}
val shownItem: ItemStack
)
companion object {
@@ -25,8 +25,7 @@ object PokedexHandler : EventHandler {
}
fun onPokemonGained(event: PokemonGainedEvent) {
Cobblemon.playerDataManager.getPokedexData(event.playerId).obtain(event.pokemon)
Cobblemon.playerDataManager.getTMData(event.playerId).syncTMsFromPokemon(event.pokemon)
Cobblemon.playerDataManager.getPokedexData(event.playerId).catch(event.pokemon)
}
fun onPokemonSeen(event: PokemonSeenEvent) {
@@ -35,7 +34,7 @@ object PokedexHandler : EventHandler {
fun onPokemonAspectsChanged(event: PokemonAspectsChangedEvent) {
if (event.ownerId != null) {
Cobblemon.playerDataManager.getPokedexData(event.ownerId).obtain(event.pokemon)
Cobblemon.playerDataManager.getPokedexData(event.ownerId).catch(event.pokemon)
}
}
@@ -32,11 +32,6 @@ object TMMachineTeachMoveHandler : ServerNetworkPacketHandler<TMMachineTeachMove
val menu = player.containerMenu as? TMMachineMenu ?: return
val inventory = menu.inventory ?: return
// This is checked on the client, but a modified client could still try to teach an illegal move.
if (moveTemplate !in pokemon.form.moves.tmLearnableMoves()) {
return
}
if (ItemStack.isSameItemSameComponents(packet.heldStack, menu.carried) &&
moveTemplate == TMMoveComponent.getTMMove(packet.heldStack) &&
packet.heldStack.count == menu.carried.count &&
@@ -58,4 +53,4 @@ object TMMachineTeachMoveHandler : ServerNetworkPacketHandler<TMMachineTeachMove
player.playNotifySound(CobblemonSounds.MOVE_LEARN, SoundSource.MASTER, 1.0F, 1.0F)
}
}
}
}
@@ -18,11 +18,6 @@ import net.minecraft.server.level.ServerPlayer
object SaveHabitatBlockSettingsHandler : ServerNetworkPacketHandler<SaveHabitatBlockSettingsPacket> {
override fun handle(packet: SaveHabitatBlockSettingsPacket, server: MinecraftServer, player: ServerPlayer) {
if (!player.isCreative) {
// mf does not have permission
return
}
val world = player.serverLevel()
val blockEntity = world.getBlockEntity(packet.blockPos) as? HabitatBlockEntity ?: return // it's broken
val pre = SaveHabitatBlockSettingsEvent.Pre(
@@ -33,6 +28,11 @@ object SaveHabitatBlockSettingsHandler : ServerNetworkPacketHandler<SaveHabitatB
settings = packet.settings
)
if (!player.isCreative) {
// mf does not have permission
return
}
CobblemonEvents.HABITAT_SETTINGS_SAVED_PRE.postThen(pre) {
blockEntity.applySettings(habitatSettingsDTO = packet.settings)
val post = SaveHabitatBlockSettingsEvent.Post(
@@ -391,19 +391,15 @@ open class Pokemon : ShowdownIdentifiable {
*/
var friendship = this.form.baseFriendship
private set(value) {
val earned = this.friendshipEarned
this.friendshipEarned = false
if (!this.isPossibleFriendship(value)) {
return
}
FRIENDSHIP_UPDATED.post(FriendshipUpdatedEvent(this, value, earned)) {
FRIENDSHIP_UPDATED.post(FriendshipUpdatedEvent(this, value)) {
field = it.newFriendship
onChange(FriendshipUpdatePacket({ this }, it.newFriendship))
}
}
private var friendshipEarned = false
var currentFullness = 0
set(value) {
val clamped = value.coerceIn(0, getMaxFullness())
@@ -599,7 +595,7 @@ open class Pokemon : ShowdownIdentifiable {
var scaleModifier: Float = 1F
set(value) {
if (field != value) {
field = value.coerceAtLeast(0.05F)
field = value
onChange(ScaleModifierUpdatePacket({ this }, value))
}
}
@@ -1605,7 +1601,6 @@ open class Pokemon : ShowdownIdentifiable {
val sanitizedAmount = if (coerceSafe) amount.absoluteValue.coerceAtMost(Cobblemon.config.maxPokemonFriendship - this.friendship) else amount.absoluteValue
val newValue = this.friendship + sanitizedAmount
if (this.isPossibleFriendship(newValue)) {
this.friendshipEarned = true
this.friendship = newValue
}
return this.friendship == newValue
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.pokemon.requirements
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
import com.cobblemon.mod.common.api.pokemon.stats.Stat
import com.cobblemon.mod.common.api.pokemon.stats.Stats
import com.cobblemon.mod.common.pokemon.Pokemon
@@ -18,13 +17,10 @@ class StatCompareRequirement : Requirement {
const val ADAPTER_VARIANT = "stat_compare"
}
val highStat = Stats.ATTACK.identifier.path
val lowStat = Stats.DEFENCE.identifier.path
val highStat = Stats.ATTACK.name
val lowStat = Stats.DEFENCE.name
override fun check(pokemon: Pokemon): Boolean {
val high = Stats.getStat(highStat)
val low = Stats.getStat(lowStat)
if (high.type != Stat.Type.PERMANENT || low.type != Stat.Type.PERMANENT) return false
return pokemon.getStat(high) > pokemon.getStat(low)
return pokemon.getStat(Stats.getStat(highStat)) > pokemon.getStat(Stats.getStat(lowStat))
}
}
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.pokemon.requirements
import com.cobblemon.mod.common.api.pokemon.requirement.Requirement
import com.cobblemon.mod.common.api.pokemon.stats.Stat
import com.cobblemon.mod.common.api.pokemon.stats.Stats
import com.cobblemon.mod.common.pokemon.Pokemon
@@ -18,13 +17,10 @@ class StatEqualRequirement : Requirement {
const val ADAPTER_VARIANT = "stat_equal"
}
val statOne = Stats.ATTACK.identifier.path
val statTwo = Stats.DEFENCE.identifier.path
val statOne = Stats.ATTACK.name
val statTwo = Stats.DEFENCE.name
override fun check(pokemon: Pokemon): Boolean {
val one = Stats.getStat(statOne)
val two = Stats.getStat(statTwo)
if (one.type != Stat.Type.PERMANENT || two.type != Stat.Type.PERMANENT) return false
return pokemon.getStat(one) == pokemon.getStat(two)
return pokemon.getStat(Stats.getStat(statOne)) == pokemon.getStat(Stats.getStat(statTwo))
}
}
@@ -8,11 +8,16 @@
package com.cobblemon.mod.common.world.feature
import com.cobblemon.mod.common.CobblemonBlocks
import com.cobblemon.mod.common.CobblemonBlocks.TYPE_GEM_CORE
import com.cobblemon.mod.common.CobblemonBlocks.typeGemBlocks
import com.cobblemon.mod.common.CobblemonBlocks.typeGemClusters
import com.cobblemon.mod.common.block.TypeGemClusterBlock
import com.cobblemon.mod.common.block.TypeGemCoreBlock
import com.cobblemon.mod.common.util.random
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.BlockTags
import net.minecraft.world.level.WorldGenLevel
import net.minecraft.world.level.block.Block.UPDATE_ALL
@@ -42,12 +47,9 @@ class TypeGemFeature : Feature<BlockStateConfiguration>(BlockStateConfiguration.
val gemState = gemBlock.defaultBlockState()
val coreState = TYPE_GEM_CORE.defaultBlockState()
// Place the gem first then make sure it placed before placing the core.
worldGenLevel.setBlock(origin, coreState, UPDATE_ALL)
if (!worldGenLevel.getBlockState(chosenPos).`is`(gemBlock)) {
return false
}
// Place core and initial gem
worldGenLevel.setBlock(origin, coreState, UPDATE_ALL)
worldGenLevel.setBlock(chosenPos, gemState, UPDATE_ALL)
// Trigger forced growth with clusters
val coreBlock = coreState.block as TypeGemCoreBlock
@@ -70,4 +72,4 @@ class TypeGemFeature : Feature<BlockStateConfiguration>(BlockStateConfiguration.
return airBlocks
}
}
}
@@ -592,7 +592,7 @@
},
"sound_effects": {
"0.0": {
"effect": "pokemon.raticate_alolan.cry"
"effect": "pokemon.raticate_alolan.alola.cry"
}
}
},
@@ -1155,6 +1155,14 @@
"position": [0, 0.5, 0]
}
},
"sound_effects": {
"0.0417": {
"effect": "animation.plumage_wing_flap_1"
},
"0.5417": {
"effect": "animation.plumage_wing_flap_3"
}
},
"timeline": {
"0.0417": "q.has_entity ? { q.sound('animation.plumage.wing_flap.small'); };",
"0.5417": "q.has_entity ? { q.sound('animation.plumage.wing_flap.small'); };"
@@ -1967,6 +1967,14 @@
"position": [0, 0, -1]
}
},
"sound_effects": {
"0.0417": {
"effect": "animation.plumage_wing_flap_medium_8"
},
"1.375": {
"effect": "animation.plumage_wing_flap_medium_2"
}
},
"timeline": {
"0.0417": "q.has_entity ? { q.sound('animation.plumage.wing_flap.medium'); };",
"1.375": "q.has_entity ? { q.sound('animation.plumage.wing_flap.medium'); };"
@@ -2220,6 +2228,20 @@
"position": [0, 0, 2]
}
},
"sound_effects": {
"0.7083": {
"effect": "animation.plumage_wing_flap_medium_2"
},
"1.6667": {
"effect": "animation.plumage_wing_flap_medium_8"
},
"2.7083": {
"effect": "animation.plumage_wing_flap_medium_2"
},
"3.6667": {
"effect": "animation.plumage_wing_flap_medium_8"
}
},
"timeline": {
"0.7083": "q.has_entity ? { q.sound('animation.plumage.wing_flap.medium'); };",
"1.6667": "q.has_entity ? { q.sound('animation.plumage.wing_flap.medium'); };",
@@ -2544,6 +2544,20 @@
"rotation": [7.5, 0, "math.sin(q.anim_time*90-90)*3"]
}
},
"sound_effects": {
"0.7083": {
"effect": "animation.plumage_wing_flap_medium_2"
},
"1.6667": {
"effect": "animation.plumage_wing_flap_medium_8"
},
"2.7083": {
"effect": "animation.plumage_wing_flap_medium_2"
},
"3.6667": {
"effect": "animation.plumage_wing_flap_medium_8"
}
},
"timeline": {
"0.7083": "q.has_entity ? { q.sound('animation.plumage.wing_flap.medium'); };",
"1.6667": "q.has_entity ? { q.sound('animation.plumage.wing_flap.medium'); };",
@@ -5,8 +5,8 @@
"loop": true,
"bones": {
"body": {
"rotation": ["35+math.sin(q.anim_time*90*8-0)*2", 0, "0-math.sin(q.anim_time*90*4-60)*1"],
"position": ["-0+math.sin(q.anim_time*90*4-30)*0.5", "-1-math.sin(q.anim_time*90*8-60)*1", 0]
"rotation": [35, 0, 0],
"position": [0, -1, 0]
},
"neck": {
"rotation": [2.5, 0, 0]
@@ -18,16 +18,16 @@
"rotation": [-20, 0, 0]
},
"tail": {
"rotation": ["-42.5+math.sin(q.anim_time*90*8-30)*2", 0, "0-math.sin(q.anim_time*90*4-90)*1"]
"rotation": [-42.5, 0, 0]
},
"tail2": {
"rotation": ["-55+math.sin(q.anim_time*90*8-60)*0.5", 0, "0-math.sin(q.anim_time*90*8-120)*1"]
"rotation": [-55, 0, 0]
},
"tail3": {
"rotation": ["-25+math.sin(q.anim_time*90*8-90)*1", 0, 0]
"rotation": [-25, 0, 0]
},
"tail4": {
"rotation": ["-32.5+math.sin(q.anim_time*90*8-120)*1", 0, 0]
"rotation": [-32.5, 0, 0]
},
"apple_bottom": {
"rotation": [75, 0, 0]
@@ -36,19 +36,19 @@
"rotation": [0, 30, 0]
},
"arm_left": {
"rotation": ["-7.5+math.sin(q.anim_time*90*8+60)*-15", "-0+math.sin(q.anim_time*90*8+60)*-50", 17.5]
"rotation": [-7.5, -50, 17.5]
},
"elbow": {
"rotation": [0, -15, "-32.5-math.sin(q.anim_time*90*8+30)*15"]
"rotation": [0, -15, -32.5]
},
"head": {
"rotation": ["-17.5+math.sin(q.anim_time*90*8-60)*2", 0, "0-math.sin(q.anim_time*90*4-30)*1"]
"rotation": [-17.5, 0, 0]
},
"eye_left": {
"rotation": [-5, 42.5, "17.5-math.sin(q.anim_time*90*8-90)*1"]
"rotation": [-5, 42.5, 17.5]
},
"eye_left2": {
"rotation": [0, 0, "-17.5-math.sin(q.anim_time*90*8-120)*1"]
"rotation": [0, 0, -17.5]
},
"hat": {
"rotation": [10, 0, 0]
@@ -66,10 +66,10 @@
"rotation": [-25, 0, 0]
},
"eye_right": {
"rotation": [-5, -42.5, "-17.5+math.sin(q.anim_time*90*8-90)*1"]
"rotation": [-5, -42.5, -17.5]
},
"eye_right2": {
"rotation": [0, 0, "17.5+math.sin(q.anim_time*90*8-120)*1"]
"rotation": [0, 0, 17.5]
},
"finger_middle_left2": {
"rotation": [0, 10, 0]
@@ -84,10 +84,10 @@
"rotation": [-7.5, 0, 0]
},
"arm_right": {
"rotation": ["-7.5+math.sin(q.anim_time*90*8+60)*-15", "0-math.sin(q.anim_time*90*8+60)*-50", -17.5]
"rotation": [-7.5, 50, -17.5]
},
"elbow2": {
"rotation": [0, 15, "32.5+math.sin(q.anim_time*90*8+30)*15"]
"rotation": [0, 15, 32.5]
},
"finger_top_right": {
"rotation": [7.5, 0, 0]
@@ -118,12 +118,6 @@
},
"apple_left3": {
"rotation": [0, 35, 0]
},
"horn": {
"rotation": ["-0+math.sin(q.anim_time*90*8-120)*1", 0, 0]
},
"horn2": {
"rotation": ["-0+math.sin(q.anim_time*90*8-180)*1", 0, 0]
}
}
},
@@ -133,37 +127,25 @@
"eyelid_left": {
"position": {
"0.0": [0.03, 0, 0],
"0.1667": {
"pre": [0.03, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0.03, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_left2": {
"position": {
"0.0": [0.03, 0, 0],
"0.1667": {
"pre": [0.03, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0.03, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"position": {
"0.0": [-0.03, 0, 0],
"0.1667": {
"pre": [-0.03, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [-0.03, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_right2": {
"position": {
"0.0": [-0.03, 0, 0],
"0.1667": {
"pre": [-0.03, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [-0.03, 0, 0], "post": [0, 0, 0]}
}
}
}
@@ -225,63 +207,9 @@
}
},
"animation.flapple.cry": {
"animation_length": 1,
"bones": {
"jaw": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [47.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [47.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.8333": {
"post": [10.75, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"head_ai": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.2917": {
"post": [-15, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [-19, 0, 0],
"lerp_mode": "catmullrom"
},
"0.8333": {
"post": [-2, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
},
"animation_length": 1.2,
"sound_effects": {
"0.2083": {
"0.04": {
"effect": "pokemon.flapple.cry"
}
}
@@ -5,81 +5,34 @@
"loop": true,
"bones": {
"right_ear_eye": {
"rotation": [0, 0, "-45+math.sin(q.anim_time*90*1-180)*-7"]
"rotation": [0, 0, -47.5]
},
"right_ear": {
"rotation": [0, 15, "15+math.sin(q.anim_time*90*1-210)*-5"]
"rotation": [0, 12.5, 17.5]
},
"left_ear_eye": {
"rotation": [0, 0, "45-math.sin(q.anim_time*90*1-180)*-7"]
"rotation": [0, 0, 45]
},
"left_ear": {
"rotation": [0, -15, "-15-math.sin(q.anim_time*90*1-210)*-5"]
"rotation": [0, -15, -15]
},
"left_leaf": {
"rotation": [0, 0, "-22.5+math.sin(q.anim_time*90*1-150)*-10"]
"rotation": [0, 0, -22.5]
},
"left_leaf_bend": {
"rotation": [0, 0, "-12.5+math.sin(q.anim_time*90*1-210)*-10"]
"rotation": [0, 0, -12.5]
},
"right_leaf": {
"rotation": [0, 0, "22.5-math.sin(q.anim_time*90*1-150)*-10"]
"rotation": [0, 0, 22.5]
},
"right_leaf_bend": {
"rotation": [0, 0, "12.5-math.sin(q.anim_time*90*1-210)*-10"]
"rotation": [0, 0, 12.5]
},
"tail2": {
"rotation": ["7.5+math.sin(q.anim_time*90*1-120)*-5", "-0+math.sin(q.anim_time*90*0.5-180)*15", 0]
"rotation": [7.5, 0, 0]
},
"tail3": {
"rotation": ["10+math.sin(q.anim_time*90*1-180)*-7.5", "-0+math.sin(q.anim_time*90*0.5-240)*15", 0]
},
"torso": {
"rotation": ["-0+math.sin(q.anim_time*90*1-60)*1", 0, "0-math.sin(q.anim_time*90*0.5-90)*1"],
"position": [0, "0-math.sin(q.anim_time*90*1-90)*-0.2", 0]
},
"neck": {
"rotation": ["-1+math.sin(q.anim_time*90*1-120)*1", 0, 0]
},
"head": {
"rotation": ["-0+math.sin(q.anim_time*90*1-150)*1.5", 0, "0-math.sin(q.anim_time*90*1-180)*1"]
},
"jaw": {
"rotation": ["5+math.sin(q.anim_time*90*1-60)*-5", 0, 0]
},
"left_front_leg": {
"rotation": ["-0+math.sin(q.anim_time*90*1-90)*2", 0, 0],
"position": [0, "0-math.sin(q.anim_time*90*1-90)*0.02", "0-math.sin(q.anim_time*90*1-90)*0.11"]
},
"left_front_paw": {
"rotation": ["-0+math.sin(q.anim_time*90*1-90)*-2", 0, 0]
},
"right_front_leg": {
"rotation": ["-0+math.sin(q.anim_time*90*1-90)*2", 0, 0],
"position": [0, "0-math.sin(q.anim_time*90*1-90)*0.02", "0-math.sin(q.anim_time*90*1-90)*0.11"]
},
"right_front_paw": {
"rotation": ["-0+math.sin(q.anim_time*90*1-90)*-2", 0, 0]
},
"right_leg": {
"rotation": ["-0+math.sin(q.anim_time*90*1-90)*-2", 0, 0],
"position": [0, "0-math.sin(q.anim_time*90*1-90)*0.01", "0-math.sin(q.anim_time*90*1-90)*-0.15"]
},
"right_paw": {
"rotation": ["-0+math.sin(q.anim_time*90*1-90)*2", 0, 0]
},
"left_leg": {
"rotation": ["-0+math.sin(q.anim_time*90*1-90)*-2", 0, 0],
"position": [0, "0-math.sin(q.anim_time*90*1-90)*0.01", "0-math.sin(q.anim_time*90*1-90)*-0.15"]
},
"left_paw": {
"rotation": ["-0+math.sin(q.anim_time*90*1-90)*2", 0, 0]
},
"tail": {
"rotation": ["-0+math.sin(q.anim_time*90*1-60)*-5", "-0+math.sin(q.anim_time*90*0.5-120)*15", 0]
},
"pie": {
"rotation": ["-0+math.sin(q.anim_time*90*1-120)*-1", 0, 0]
"rotation": [10, 0, 0]
}
}
},
@@ -88,22 +41,22 @@
"bones": {
"right_eye": {
"position": {
"0.0": [0.25, 0, 0],
"0.1667": {"pre": [0.25, 0, 0], "post": [0, 0, 0]}
"0.0": [0, 0, 0.25],
"0.1667": {"pre": [0, 0, 0.25], "post": [0, 0, 0]}
},
"scale": {
"0.0": [0.5, 1, 1],
"0.1667": {"pre": [0.5, 1, 1], "post": [1, 1, 1]}
"0.0": [1, 1, 0.5],
"0.1667": {"pre": [1, 1, 0.5], "post": [1, 1, 1]}
}
},
"left_eye": {
"position": {
"0.0": [-0.25, 0, 0],
"0.1667": {"pre": [-0.25, 0, 0], "post": [0, 0, 0]}
"0.0": [0, 0, 0.25],
"0.1667": {"pre": [0, 0, 0.25], "post": [0, 0, 0]}
},
"scale": {
"0.0": [0.5, 1, 1],
"0.1667": {"pre": [0.5, 1, 1], "post": [1, 1, 1]}
"0.0": [1, 1, 0.5],
"0.1667": {"pre": [1, 1, 0.5], "post": [1, 1, 1]}
}
}
}
@@ -145,7 +98,7 @@
"rotation": [0, 35, 0],
"position": [0, 4, 0]
},
"torso": {
"body": {
"rotation": [10.1577, -2.55868, -7.05239]
},
"neck": {
@@ -197,237 +150,9 @@
}
},
"animation.appletun.cry": {
"animation_length": 3,
"bones": {
"neck": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [-1.53, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [-10, 0, 0],
"lerp_mode": "catmullrom"
},
"1.9167": {
"post": [-13.5, 0, 0],
"lerp_mode": "catmullrom"
},
"2.25": {
"post": [-3.22, 0, 0],
"lerp_mode": "catmullrom"
},
"2.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"head": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.25": {
"post": [-1.94, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [-15, 0, 0],
"lerp_mode": "catmullrom"
},
"1.7083": {
"post": [-20, 0, 0],
"lerp_mode": "catmullrom"
},
"2.25": {
"post": [-3.07, 0, 0],
"lerp_mode": "catmullrom"
},
"2.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"jaw": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [57.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.3333": {
"post": [25, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [25, 0, 0],
"lerp_mode": "catmullrom"
},
"2.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"left_leaf": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [0, 0, -5.59],
"lerp_mode": "catmullrom"
},
"0.5417": {
"post": [0, 0, -25],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [0, 0, 6],
"lerp_mode": "catmullrom"
},
"0.9583": {
"post": [0, 0, -25],
"lerp_mode": "catmullrom"
},
"1.1667": {
"post": [0, 0, 3],
"lerp_mode": "catmullrom"
},
"1.875": {
"post": [0, 0, -2.25],
"lerp_mode": "catmullrom"
},
"2.5833": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"left_leaf_bend": {
"rotation": {
"0.125": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0, -5.59],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [0, 0, -25],
"lerp_mode": "catmullrom"
},
"0.875": {
"post": [0, 0, 6],
"lerp_mode": "catmullrom"
},
"1.0833": {
"post": [0, 0, -25],
"lerp_mode": "catmullrom"
},
"1.2917": {
"post": [0, 0, 3],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, -2.25],
"lerp_mode": "catmullrom"
},
"2.5833": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"right_leaf": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [0, 0, 5.59],
"lerp_mode": "catmullrom"
},
"0.5417": {
"post": [0, 0, 25],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [0, 0, -6],
"lerp_mode": "catmullrom"
},
"0.9583": {
"post": [0, 0, 25],
"lerp_mode": "catmullrom"
},
"1.1667": {
"post": [0, 0, -3],
"lerp_mode": "catmullrom"
},
"1.875": {
"post": [0, 0, 2.25],
"lerp_mode": "catmullrom"
},
"2.5833": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"right_leaf_bend": {
"rotation": {
"0.125": {
"pre": [0, 0, 0],
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [0, 0, 5.59],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [0, 0, 25],
"lerp_mode": "catmullrom"
},
"0.875": {
"post": [0, 0, -6],
"lerp_mode": "catmullrom"
},
"1.0833": {
"post": [0, 0, 25],
"lerp_mode": "catmullrom"
},
"1.2917": {
"post": [0, 0, -3],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 2.25],
"lerp_mode": "catmullrom"
},
"2.5833": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
},
"animation_length": 1.2,
"sound_effects": {
"0.0": {
"0.04": {
"effect": "pokemon.appletun.cry"
}
}
@@ -5,43 +5,25 @@
"loop": true,
"bones": {
"eye_left": {
"rotation": ["5+math.sin(q.anim_time*90*2-90)*2", 0, 12.5]
"rotation": [5, 0, 12.5]
},
"eye_right": {
"rotation": ["5+math.sin(q.anim_time*90*2-90)*2", 0, -12.5]
"rotation": [7.5, 0, -15]
},
"eye_left2": {
"rotation": ["2.5+math.sin(q.anim_time*90*2-120)*0.5", 0, 0]
"rotation": [2.5, 0, 0]
},
"stem": {
"rotation": ["-2.5+math.sin(q.anim_time*90*2-120)*1", 0, 0]
"rotation": [-2.5, 0, 0]
},
"stem_end": {
"rotation": ["-5+math.sin(q.anim_time*90*2-180)*4", 0, 0]
"rotation": [-5, 0, 0]
},
"stem_bend": {
"rotation": ["-5+math.sin(q.anim_time*90*2-150)*2", 0, 0]
"rotation": [-5, 0, 0]
},
"tail": {
"rotation": ["-0+math.sin(q.anim_time*90*2-60)*-1", "12.5+math.sin(q.anim_time*90*1-120)*1", 0]
},
"apple_top": {
"rotation": ["-0+math.sin(q.anim_time*90*2-60)*0.25", 0, 0]
},
"eye_right2": {
"rotation": ["2.5+math.sin(q.anim_time*90*2-120)*0.5", 0, 0]
},
"tail2": {
"rotation": ["-0+math.sin(q.anim_time*90*2-90)*1", 0, 0]
},
"tail_leaves": {
"rotation": [0, "-0+math.sin(q.anim_time*90*1-30)*3", 0]
},
"bottom": {
"scale": ["1-math.sin(q.anim_time*90*2)*-0.01", 1, "1-math.sin(q.anim_time*90*2)*-0.01"]
},
"apple": {
"rotation": ["-0+math.sin(q.anim_time*90*2-30)*0.5", 0, "0-math.sin(q.anim_time*90*1-60)*0.5"]
"rotation": [0, 12.5, 0]
}
}
},
@@ -51,186 +33,40 @@
"pupil_left": {
"scale": {
"0.0": [0, 0, 0],
"0.1667": {
"pre": [0, 0, 0],
"post": [1, 1, 1]
}
"0.1667": {"pre": [0, 0, 0], "post": [1, 1, 1]}
}
},
"pupil_right": {
"scale": {
"0.0": [0, 0, 0],
"0.1667": {
"pre": [0, 0, 0],
"post": [1, 1, 1]
}
"0.1667": {"pre": [0, 0, 0], "post": [1, 1, 1]}
}
},
"eye_right_closed": {
"position": {
"0.0": [0, 0, -0.02],
"0.1667": {
"pre": [0, 0, -0.02],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, -0.02], "post": [0, 0, 0]}
}
},
"eye_right_closed2": {
"position": {
"0.0": [0, 0, -0.02],
"0.1667": {
"pre": [0, 0, -0.02],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, -0.02], "post": [0, 0, 0]}
}
},
"eye_left_closed2": {
"position": {
"0.0": [0, 0, -0.02],
"0.1667": {
"pre": [0, 0, -0.02],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, -0.02], "post": [0, 0, 0]}
}
},
"eye_left_closed": {
"position": {
"0.0": [0, 0, -0.02],
"0.1667": {
"pre": [0, 0, -0.02],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, -0.02], "post": [0, 0, 0]}
}
}
}
},
"animation.dipplin.cry": {
"animation_length": 1.5,
"bones": {
"pupil_left": {
"scale": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [1, 1, 1]
}
}
},
"pupil_right": {
"scale": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [1, 1, 1]
}
}
},
"tail": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": ["2.5-math.sin(q.anim_time*90*50-180)*-0.5", 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [-2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"eye_right_closed": {
"position": {
"0.0": [0, 0, -0.02],
"0.25": {
"pre": [0, 0, -0.02],
"post": [0, 0, 0]
}
}
},
"eye_right_closed2": {
"position": {
"0.0": [0, 0, -0.02],
"0.25": {
"pre": [0, 0, -0.02],
"post": [0, 0, 0]
}
}
},
"eye_left_closed2": {
"position": {
"0.0": [0, 0, -0.02],
"0.25": {
"pre": [0, 0, -0.02],
"post": [0, 0, 0]
}
}
},
"eye_left_closed": {
"position": {
"0.0": [0, 0, -0.02],
"0.25": {
"pre": [0, 0, -0.02],
"post": [0, 0, 0]
}
}
},
"apple": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": ["-2.5+math.sin(q.anim_time*90*50-180)*-0.5", 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
}
},
"sound_effects": {
"0.0": {
"effect": "pokemon.dipplin.cry"
}
}
}
}
}
@@ -4,50 +4,41 @@
"animation.hydrapple.ground_idle": {
"loop": true,
"bones": {
"bottom": {
"scale": ["1-math.sin(q.anim_time*90*2)*-0.01", 1, "1-math.sin(q.anim_time*90*2)*-0.01"]
},
"apple_top": {
"rotation": ["-0+math.sin(q.anim_time*90*2-30)*0.5", 0, "0-math.sin(q.anim_time*90*1-60)*0.5"]
},
"main_head_neck_base": {
"rotation": ["-7.5+math.sin(q.anim_time*90*2-30)*0.5", 0, "0-math.sin(q.anim_time*90*1-60)*1"]
"rotation": [-7.5, 0, 0]
},
"main_head_neck_base_bend": {
"rotation": ["-19.954911595+math.sin(q.anim_time*90*2-60)*0.5", 3.04775, "8.132083803-math.sin(q.anim_time*90*1-90)*0.5"]
"rotation": [-19.95491, 3.04775, 8.13208]
},
"main_head_neck_mid": {
"rotation": ["-10+math.sin(q.anim_time*90*2-90)*0.5", 0, "0-math.sin(q.anim_time*90*1-120)*1"]
"rotation": [-10, 0, 0]
},
"main_head_neck_mid_bend": {
"rotation": ["29.408423889+math.sin(q.anim_time*90*2-120)*1", 6.21271, "-10.868150118-math.sin(q.anim_time*90*1-150)*0.5"]
"rotation": [29.40842, 6.21271, -10.86815]
},
"main_head_neck_end": {
"rotation": ["27.5+math.sin(q.anim_time*90*2-150)*1", 0, "0-math.sin(q.anim_time*90*1-180)*1"]
"rotation": [27.5, 0, 0]
},
"main_head_neck_end_bend": {
"rotation": ["35+math.sin(q.anim_time*90*2-180)*1", 0, "0-math.sin(q.anim_time*90*1-210)*1"]
"rotation": [35, 0, 0]
},
"main_head_neck_tip": {
"rotation": ["42.391212146+math.sin(q.anim_time*90*2-210)*1", -3.37562, "3.690660194-math.sin(q.anim_time*90*1-240)*1"]
"rotation": [42.39121, -3.37562, 3.69066]
},
"main_head_head": {
"rotation": ["-0+math.sin(q.anim_time*90*2-210)*-2", "2.5+math.sin(q.anim_time*90*1-60)*1.5", "-2.5-math.sin(q.anim_time*90*1-300)*1"]
"rotation": [0, 2.5, -2.5]
},
"main_head_eye_left": {
"rotation": ["18.533664677+math.sin(q.anim_time*90*2-30)*1", -34.044, -64.8734]
"rotation": [18.53366, -34.044, -64.8734]
},
"main_head_eye_left_bend": {
"rotation": ["-22.5+math.sin(q.anim_time*90*2-60)*1", 0, 0]
"rotation": [-22.5, 0, 0]
},
"main_head_eye_right": {
"rotation": ["18.533664677+math.sin(q.anim_time*90*2-30)*1", 34.044, 64.8734]
"rotation": [18.53366, 34.044, 64.8734]
},
"main_head_eye_right_bend": {
"rotation": ["-22.5+math.sin(q.anim_time*90*2-60)*1", 0, 0]
},
"main_head_tip": {
"position": [0, 0, -0.75]
"rotation": [-22.5, 0, 0]
},
"front_right_head_neck_base": {
"scale": 0
@@ -62,10 +53,10 @@
"scale": 0
},
"tail_right_base": {
"rotation": ["-7.5+math.sin(q.anim_time*90*2-60)*-1", "10+math.sin(q.anim_time*90*1-120)*1", 0]
"rotation": [-7.5, 10, 0]
},
"tail_right_bend": {
"rotation": ["-37.5+math.sin(q.anim_time*90*2-90)*1", 0, 0]
"rotation": [-37.5, 0, 0]
},
"tail_right_end": {
"rotation": [32.5, 0, 0]
@@ -73,115 +64,17 @@
"tail_right_tip": {
"rotation": [15, 0, 0]
},
"tail_leaves_right": {
"rotation": [0, "-0+math.sin(q.anim_time*90*1-30)*3", 0]
},
"tail_left_base": {
"rotation": ["-7.5+math.sin(q.anim_time*90*2-60)*-1", "-10-math.sin(q.anim_time*90*1-120)*1", 0]
"rotation": [-7.5, -10, 0]
},
"tail_left_bend": {
"rotation": ["-37.5+math.sin(q.anim_time*90*2-90)*1", 0, 0]
"rotation": [-37.5, 0, 0]
},
"tail_left_end": {
"rotation": [32.5, 0, 0]
},
"tail_left_tip": {
"rotation": [15, 0, 0]
},
"tail_leaves_left": {
"rotation": [0, "0-math.sin(q.anim_time*90*1-30)*3", 0]
}
}
},
"animation.hydrapple.battle_idle": {
"loop": true,
"bones": {
"bottom": {
"scale": ["1-math.sin(q.anim_time*90*2)*-0.01", 1, "1-math.sin(q.anim_time*90*2)*-0.01"]
},
"apple_top": {
"rotation": ["-0+math.sin(q.anim_time*90*2-30)*0.75", 0, "0-math.sin(q.anim_time*90*1-60)*0.75"]
},
"main_head_neck_base": {
"rotation": ["-7.5+math.sin(q.anim_time*90*2-30)*1", 0, "0-math.sin(q.anim_time*90*1-60)*1"]
},
"main_head_neck_base_bend": {
"rotation": ["-32.4549+math.sin(q.anim_time*90*2-60)*1", 3.04775, "8.1321-math.sin(q.anim_time*90*1-90)*2"]
},
"main_head_neck_mid": {
"rotation": ["-20+math.sin(q.anim_time*90*2-90)*1", 0, "-math.sin(q.anim_time*90*1-120)*2"]
},
"main_head_neck_mid_bend": {
"rotation": ["34.4084+math.sin(q.anim_time*90*2-120)*2", 6.21271, "-10.8682-math.sin(q.anim_time*90*1-150)*2"]
},
"main_head_neck_end": {
"rotation": ["35+math.sin(q.anim_time*90*2-150)*2", 0, "-math.sin(q.anim_time*90*1-180)*2"]
},
"main_head_neck_end_bend": {
"rotation": ["40+math.sin(q.anim_time*90*2-180)*2", 0, "-math.sin(q.anim_time*90*1-210)*2"]
},
"main_head_neck_tip": {
"rotation": ["47.3912+math.sin(q.anim_time*90*2-210)*2", -3.37562, "3.6907-math.sin(q.anim_time*90*1-240)*2"]
},
"main_head_head": {
"rotation": ["7.5+math.sin(q.anim_time*90*2-210)*-4", "2.5+math.sin(q.anim_time*90*1-60)*3", "-2.5-math.sin(q.anim_time*90*1-300)*2"]
},
"main_head_eye_left": {
"rotation": ["18.533664677+math.sin(q.anim_time*90*2-30)*2", -34.044, -64.8734]
},
"main_head_eye_left_bend": {
"rotation": ["-22.5+math.sin(q.anim_time*90*2-60)*2", 0, 0]
},
"main_head_eye_right": {
"rotation": ["18.533664677+math.sin(q.anim_time*90*2-30)*2", 34.044, 64.8734]
},
"main_head_eye_right_bend": {
"rotation": ["-22.5+math.sin(q.anim_time*90*2-60)*2", 0, 0]
},
"main_head_tip": {
"position": [0, 0, -0.75]
},
"front_right_head_neck_base": {
"scale": 0
},
"front_left_head_neck_base": {
"scale": 0
},
"back_left_head_neck_base": {
"scale": 0
},
"back_right_head_neck_base": {
"scale": 0
},
"tail_right_base": {
"rotation": ["-7.5+math.sin(q.anim_time*90*2-60)*-1", "10+math.sin(q.anim_time*90*1-120)*1", 0]
},
"tail_right_bend": {
"rotation": ["-37.5+math.sin(q.anim_time*90*2-90)*1", 0, 0]
},
"tail_right_end": {
"rotation": [32.5, 0, 0]
},
"tail_right_tip": {
"rotation": [15, 0, 0]
},
"tail_leaves_right": {
"rotation": [0, "-0+math.sin(q.anim_time*90*1-30)*3", 0]
},
"tail_left_base": {
"rotation": ["-7.5+math.sin(q.anim_time*90*2-60)*-1", "-10-math.sin(q.anim_time*90*1-120)*1", 0]
},
"tail_left_bend": {
"rotation": ["-37.5+math.sin(q.anim_time*90*2-90)*1", 0, 0]
},
"tail_left_end": {
"rotation": [32.5, 0, 0]
},
"tail_left_tip": {
"rotation": [15, 0, 0]
},
"tail_leaves_left": {
"rotation": [0, "0-math.sin(q.anim_time*90*1-30)*3", 0]
}
}
},
@@ -628,333 +521,9 @@
}
},
"animation.hydrapple.cry": {
"animation_length": 2.1667,
"bones": {
"main_head_neck_base": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.0833": {
"post": [1.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": [-2, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5833": {
"post": [1, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7917": {
"post": [1, 0, 0],
"lerp_mode": "catmullrom"
},
"1.0833": {
"post": [-1, 0, 0],
"lerp_mode": "catmullrom"
},
"1.4583": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.7083": {
"post": [-1.25, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"main_head_neck_base_bend": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [1.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": [-2, 0, 0],
"lerp_mode": "catmullrom"
},
"0.6667": {
"post": [1, 0, 0],
"lerp_mode": "catmullrom"
},
"0.875": {
"post": [1, 0, 0],
"lerp_mode": "catmullrom"
},
"1.1667": {
"post": [-1, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5833": {
"post": [-2, 0, 0],
"lerp_mode": "catmullrom"
},
"1.875": {
"post": [-1.25, 0, 0],
"lerp_mode": "catmullrom"
},
"2.125": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"main_head_head": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.125": {
"post": [7.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.3333": {
"post": ["-15+math.sin(q.anim_time*90*50-180)*-1", 0, 0],
"lerp_mode": "catmullrom"
},
"0.625": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.8333": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.125": {
"post": [-8, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5": {
"post": ["-12+math.sin(q.anim_time*90*50-180)*-1", 0, 0],
"lerp_mode": "catmullrom"
},
"1.75": {
"post": [-3.25, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"main_head_eye_left_closed": {
"position": {
"0.0": [0, 0, -0.03],
"0.1667": {
"pre": [0, 0, -0.03],
"post": [0, 0, 0]
},
"0.8333": {
"pre": [0, 0, 0],
"post": [0, 0, -0.03]
},
"1.1667": {
"pre": [0, 0, -0.03],
"post": [0, 0, 0]
}
}
},
"main_head_eye_left_bend_closed": {
"position": {
"0.0": [0, 0, -0.03],
"0.1667": {
"pre": [0, 0, -0.03],
"post": [0, 0, 0]
},
"0.8333": {
"pre": [0, 0, 0],
"post": [0, 0, -0.03]
},
"1.1667": {
"pre": [0, 0, -0.03],
"post": [0, 0, 0]
}
}
},
"main_head_eye_right_closed": {
"position": {
"0.0": [0, 0, -0.03],
"0.1667": {
"pre": [0, 0, -0.03],
"post": [0, 0, 0]
},
"0.8333": {
"pre": [0, 0, 0],
"post": [0, 0, -0.03]
},
"1.1667": {
"pre": [0, 0, -0.03],
"post": [0, 0, 0]
}
}
},
"main_head_eye_right_bend_closed": {
"position": {
"0.0": [0, 0, -0.03],
"0.1667": {
"pre": [0, 0, -0.03],
"post": [0, 0, 0]
},
"0.8333": {
"pre": [0, 0, 0],
"post": [0, 0, -0.03]
},
"1.1667": {
"pre": [0, 0, -0.03],
"post": [0, 0, 0]
}
}
},
"main_head_jaw": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": [40, 0, 0],
"lerp_mode": "catmullrom"
},
"0.7917": {
"post": [10, 0, 0],
"lerp_mode": "catmullrom"
},
"1.25": {
"post": [10, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5": {
"post": [40, 0, 0],
"lerp_mode": "catmullrom"
},
"1.9167": {
"post": [4.3, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0833": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"main_head_tongue": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.5": {
"post": ["-17.5+math.sin(q.anim_time*90*50-210)*-2", 0, 0],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.2083": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5833": {
"post": [-12.5, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"main_head_tongue_bend": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.1667": {
"post": [1.43, 0, 0],
"lerp_mode": "catmullrom"
},
"0.375": {
"post": ["-12.5+math.sin(q.anim_time*90*50-240)*-2", 0, 0],
"lerp_mode": "catmullrom"
},
"0.7083": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"1.2917": {
"post": [-2.71, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5": {
"post": ["-15+math.sin(q.anim_time*90*50-240)*-2", 0, 0],
"lerp_mode": "catmullrom"
},
"1.9583": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
}
},
"main_head_tip": {
"rotation": {
"0.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
},
"0.125": {
"post": [12.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.4167": {
"post": [2.5, 0, 0],
"lerp_mode": "catmullrom"
},
"0.75": {
"post": [10, 0, 0],
"lerp_mode": "catmullrom"
},
"1.2917": {
"post": [22.5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.5417": {
"post": [-5, 0, 0],
"lerp_mode": "catmullrom"
},
"1.8333": {
"post": [35, 0, 0],
"lerp_mode": "catmullrom"
},
"2.0": {
"post": [0, 0, 0],
"lerp_mode": "catmullrom"
}
},
"position": {
"0.0": [0, 0, 0],
"0.25": [0, 0, 0.75],
"1.8333": [0, 0, 0.75],
"2.0": [0, 0, 0]
}
}
},
"animation_length": 1.2,
"sound_effects": {
"0.0417": {
"0.04": {
"effect": "pokemon.hydrapple.cry"
}
}
@@ -226,14 +226,6 @@
{"origin": [3.51, 36.5, -2], "size": [0, 2, 2], "uv": [0, -2]}
]
},
{
"name": "locator_eye_left",
"parent": "eye_left",
"pivot": [3.51, 37.5, -1],
"locators": {
"eye2": [3.51, 37.5, -1]
}
},
{
"name": "pupil_left",
"parent": "eye_left",
@@ -242,14 +234,6 @@
{"origin": [3.52, 37.5, -2], "size": [0, 1, 1], "uv": [8, -1]}
]
},
{
"name": "locator_eye_right",
"parent": "pupil_left",
"pivot": [-3.51, 37.5, -1],
"locators": {
"eye1": [-3.51, 37.5, -1]
}
},
{
"name": "eyelid_left",
"parent": "eye_left",
@@ -18,19 +18,14 @@
{
"name": "body",
"parent": "appletun",
"pivot": [0, 9.25, 0]
},
{
"name": "torso",
"parent": "body",
"pivot": [0, 4.25, 0],
"pivot": [0, 9.25, 0],
"cubes": [
{"origin": [-7.5, 1.35, -7.75], "size": [15, 5, 15], "uv": [0, 31]}
]
},
{
"name": "neck",
"parent": "torso",
"parent": "body",
"pivot": [0, 1.5, -7.75],
"cubes": [
{"origin": [-2.5, 1.5, -10.75], "size": [5, 4, 3], "uv": [43, 62]}
@@ -143,9 +138,93 @@
{"origin": [-1.5, 1.5, -17.75], "size": [3, 1, 2], "uv": [54, 39]}
]
},
{
"name": "left_front_leg",
"parent": "body",
"pivot": [8.75, 5.5, -3.5],
"rotation": [-7.5, 0, 0],
"cubes": [
{"origin": [7, 1.25, -5.5], "size": [3, 5, 4], "uv": [0, 31]}
]
},
{
"name": "left_front_paw",
"parent": "left_front_leg",
"pivot": [8, 1.75, -2.25],
"rotation": [7.5, 0, 0],
"cubes": [
{"origin": [7, 0.25, -5], "size": [2, 2, 3], "uv": [10, 71]}
]
},
{
"name": "left_front_paw_bend",
"parent": "left_front_paw",
"pivot": [8, 2.25, -5],
"cubes": [
{"origin": [7, 0.25, -7], "size": [2, 2, 2], "inflate": 0.01, "uv": [65, 62]}
]
},
{
"name": "right_front_leg",
"parent": "body",
"pivot": [-8.75, 5.5, -3.5],
"rotation": [-7.5, 0, 0],
"cubes": [
{"origin": [-10, 1.25, -5.5], "size": [3, 5, 4], "uv": [0, 8]}
]
},
{
"name": "right_front_paw",
"parent": "right_front_leg",
"pivot": [-8, 1.75, -2.25],
"rotation": [7.5, 0, 0],
"cubes": [
{"origin": [-9, 0.25, -5], "size": [2, 2, 3], "uv": [0, 71]}
]
},
{
"name": "right_front_paw_bend",
"parent": "right_front_paw",
"pivot": [-8, 2.25, -5],
"cubes": [
{"origin": [-9, 0.25, -7], "size": [2, 2, 2], "inflate": 0.01, "uv": [48, 42]}
]
},
{
"name": "right_leg",
"parent": "body",
"pivot": [-7.25, 5.25, 5.75],
"cubes": [
{"origin": [-10, 1, 2.25], "size": [4, 6, 6], "uv": [20, 59]}
]
},
{
"name": "right_paw",
"parent": "right_leg",
"pivot": [-8, 1, 5.75],
"cubes": [
{"origin": [-9.5, 0, 3], "size": [3, 2, 4], "uv": [58, 66]}
]
},
{
"name": "left_leg",
"parent": "body",
"pivot": [7.25, 5.25, 5.75],
"cubes": [
{"origin": [6, 1, 2.25], "size": [4, 6, 6], "uv": [0, 59]}
]
},
{
"name": "left_paw",
"parent": "left_leg",
"pivot": [8, 1, 5.75],
"cubes": [
{"origin": [6.5, 0, 3], "size": [3, 2, 4], "uv": [0, 40]}
]
},
{
"name": "tail",
"parent": "torso",
"parent": "body",
"pivot": [0, 2.75, 7.25],
"cubes": [
{"origin": [-2.5, 1.25, 7.25], "size": [5, 5, 3], "uv": [0, 0]}
@@ -169,7 +248,7 @@
},
{
"name": "pie",
"parent": "torso",
"parent": "body",
"pivot": [0, 6.25, 0],
"cubes": [
{"origin": [-9, 6.25, -9], "size": [18, 13, 18], "uv": [0, 0]}
@@ -246,90 +325,6 @@
"cubes": [
{"origin": [-8.5, 15, 0], "size": [22, 5, 3], "pivot": [2.5, 18.25, 1.5], "rotation": [0, 0, -2.5], "uv": [50, 51]}
]
},
{
"name": "left_front_leg",
"parent": "body",
"pivot": [8.75, 5.5, -3.5],
"rotation": [-7.5, 0, 0],
"cubes": [
{"origin": [7, 1.25, -5.5], "size": [3, 5, 4], "uv": [0, 31]}
]
},
{
"name": "left_front_paw",
"parent": "left_front_leg",
"pivot": [8, 1.75, -2.25],
"rotation": [7.5, 0, 0],
"cubes": [
{"origin": [7, 0.25, -5], "size": [2, 2, 3], "uv": [10, 71]}
]
},
{
"name": "left_front_paw_bend",
"parent": "left_front_paw",
"pivot": [8, 0.25, -5],
"cubes": [
{"origin": [7, 0.25, -7], "size": [2, 2, 2], "inflate": 0.01, "uv": [65, 62]}
]
},
{
"name": "right_front_leg",
"parent": "body",
"pivot": [-8.75, 5.5, -3.5],
"rotation": [-7.5, 0, 0],
"cubes": [
{"origin": [-10, 1.25, -5.5], "size": [3, 5, 4], "uv": [0, 8]}
]
},
{
"name": "right_front_paw",
"parent": "right_front_leg",
"pivot": [-8, 1.75, -2.25],
"rotation": [7.5, 0, 0],
"cubes": [
{"origin": [-9, 0.25, -5], "size": [2, 2, 3], "uv": [0, 71]}
]
},
{
"name": "right_front_paw_bend",
"parent": "right_front_paw",
"pivot": [-8, 0.25, -5],
"cubes": [
{"origin": [-9, 0.25, -7], "size": [2, 2, 2], "inflate": 0.01, "uv": [48, 42]}
]
},
{
"name": "right_leg",
"parent": "body",
"pivot": [-7.25, 5.25, 5.75],
"cubes": [
{"origin": [-10, 1, 2.25], "size": [4, 6, 6], "uv": [20, 59]}
]
},
{
"name": "right_paw",
"parent": "right_leg",
"pivot": [-8, 1, 5.75],
"cubes": [
{"origin": [-9.5, 0, 3], "size": [3, 2, 4], "uv": [58, 66]}
]
},
{
"name": "left_leg",
"parent": "body",
"pivot": [7.25, 5.25, 5.75],
"cubes": [
{"origin": [6, 1, 2.25], "size": [4, 6, 6], "uv": [0, 59]}
]
},
{
"name": "left_paw",
"parent": "left_leg",
"pivot": [8, 1, 5.75],
"cubes": [
{"origin": [6.5, 0, 3], "size": [3, 2, 4], "uv": [0, 40]}
]
}
]
}
@@ -18,20 +18,17 @@
{
"name": "body",
"parent": "dipplin",
"pivot": [0, 3, 0]
},
{
"name": "apple",
"parent": "body",
"pivot": [0, 2, 0],
"pivot": [0, 3, 0],
"cubes": [
{"origin": [-4, 2, -4], "size": [8, 6, 8], "uv": [0, 10]},
{"origin": [-3, 2.5, 4], "size": [2, 2, 0], "inflate": 0.01, "uv": [0, 42]}
{"origin": [-3, 2.5, 4], "size": [2, 2, 0], "inflate": 0.01, "uv": [0, 42]},
{"origin": [-3, 0.01, -3], "size": [6, 2, 6], "uv": [24, 4]},
{"origin": [-5, 0, -5], "size": [10, 0, 10], "uv": [0, 0]}
]
},
{
"name": "apple_top",
"parent": "apple",
"parent": "body",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [-4, 5, -4.5], "size": [8, 1, 0], "uv": [24, 13]},
@@ -48,7 +45,7 @@
},
{
"name": "worminside",
"parent": "apple",
"parent": "body",
"pivot": [0, 6.25, 0.75]
},
{
@@ -238,15 +235,6 @@
{"origin": [0.5, -1.5, 5.75], "size": [1, 0, 2], "pivot": [1.5, -1.5, 5.75], "rotation": [0, -32.5, 0], "uv": [6, 0]},
{"origin": [1.5, -1.5, 5.75], "size": [1, 0, 2], "pivot": [1.5, -1.5, 5.75], "rotation": [0, 35, 0], "uv": [4, 0]}
]
},
{
"name": "bottom",
"parent": "body",
"pivot": [0, 0, 0],
"cubes": [
{"origin": [-3, 0.01, -3], "size": [6, 2, 6], "uv": [24, 4]},
{"origin": [-5, 0, -5], "size": [10, 0, 10], "uv": [0, 0]}
]
}
]
}
@@ -325,12 +325,7 @@
"name": "head",
"parent": "torso2",
"pivot": [0, 40, 3],
"rotation": [47.5, 0, 0]
},
{
"name": "head_ai",
"parent": "head",
"pivot": [0, 40, 0],
"rotation": [47.5, 0, 0],
"cubes": [
{"origin": [-2.5, 41, 0.99], "size": [5, 3, 1], "uv": [0, 0]},
{"origin": [0.5, 41, 1.98], "size": [2, 3, 2], "inflate": 0.01, "uv": [12, 0]},
@@ -339,7 +334,7 @@
},
{
"name": "locator_item",
"parent": "head_ai",
"parent": "head",
"pivot": [-0.25, 42.75, 3.5],
"rotation": [0, -135, 90],
"locators": {
@@ -348,7 +343,7 @@
},
{
"name": "head_wheel",
"parent": "head_ai",
"parent": "head",
"pivot": [0, 40.25, 2],
"cubes": [
{"origin": [-0.5, 38.75, 1.85], "size": [1, 2, 2], "inflate": -0.15, "uv": [23, 14]}
@@ -356,7 +351,7 @@
},
{
"name": "head2",
"parent": "head_ai",
"parent": "head",
"pivot": [0, 41, 2],
"cubes": [
{"origin": [-2.5, 41, -1], "size": [5, 3, 2], "uv": [24, 0]},
@@ -626,7 +621,7 @@
]
},
{
"name": "seat_1_locator",
"name": "locator_seat_1",
"parent": "torso_back",
"pivot": [0, 11, 14],
"locators": {
@@ -5,7 +5,6 @@
"profileTranslation": [0.0, 0.35, 0],
"rootBone": "diglett",
"animations": {
"faint": "q.bedrock_primary('diglett', 'faint', q.curve('one'))",
"cry": "q.bedrock_stateful('diglett', 'cry')",
"recoil": "q.bedrock_stateful('diglett', 'recoil')",
"physical": "q.bedrock_primary('diglett', 'physical', q.curve('symmetrical'))"
@@ -5,7 +5,6 @@
"profileTranslation": [0.0, 0.29, 0],
"rootBone": "dugtrio",
"animations": {
"faint": "q.bedrock_primary('dugtrio', 'faint', q.curve('one'))",
"cry": "q.bedrock_stateful('dugtrio', 'cry')",
"recoil": "q.bedrock_stateful('dugtrio', 'recoil')",
"physical": "q.bedrock_primary('dugtrio', 'physical', q.curve('symmetrical'))"
@@ -16,7 +16,8 @@
"seat_1_reverse": [0, 0.4, 0]
},
"animations": {
"cry": "q.bedrock_stateful('mantine', 'cry')"
"cry": "q.bedrock_stateful('mantine', 'cry')",
"recoil": "q.bedrock_stateful('mantine', 'recoil')"
},
"poses": {
"jump": {
@@ -41,10 +41,16 @@
],
"animations": [
"q.look('head')",
"q.bedrock('sableye', 'shoulder_left')"
"q.bedrock('sableye', 'ground_idle')"
],
"quirks": [
"q.bedrock_quirk('sableye', 'blink')"
],
"transformedParts": [
{
"part": "body",
"position": [5, 0, 0]
}
]
},
"shoulder_right": {
@@ -54,10 +60,16 @@
],
"animations": [
"q.look('head')",
"q.bedrock('sableye', 'shoulder_right')"
"q.bedrock('sableye', 'ground_idle')"
],
"quirks": [
"q.bedrock_quirk('sableye', 'blink')"
],
"transformedParts": [
{
"part": "body",
"position": [-5, 0, 0]
}
]
}
}
@@ -13,9 +13,7 @@
"isBattle": true,
"animations": [
"q.look('head')",
"q.bedrock('lucario', 'battle_idle')",
"q.bedrock('lucario', 'battle_idle_aura_left')",
"q.bedrock('lucario', 'battle_idle_aura_right')"
"q.bedrock('lucario', 'battle_idle')"
],
"quirks": ["q.bedrock_quirk('lucario', 'blink')", "q.bedrock_quirk('lucario', 'battle_quirk')"]
},
@@ -5,7 +5,8 @@
"profileTranslation": [-0.01, 0.52, 0],
"rootBone": "mantyke",
"animations": {
"cry": "q.bedrock_stateful('mantyke', 'cry')"
"cry": "q.bedrock_stateful('mantyke', 'cry')",
"recoil": "q.bedrock_stateful('mantyke', 'recoil')"
},
"poses": {
"standing": {
@@ -16,8 +16,9 @@
"PORTRAIT",
"PROFILE"
],
"isBattle": true,
"animations": [
"q.look('head_ai', 1, 1, 25, -25, 40, -40)",
"q.look('head')",
"q.bedrock('lycanroc_dusk', 'ground_idle')"
]
},
@@ -27,7 +28,7 @@
"SWIM"
],
"animations": [
"q.look('head_ai', 1, 1, 25, -25, 40, -40)",
"q.look('head')",
"q.bedrock('lycanroc_dusk', 'ground_idle')",
"q.quadruped_walk(1, 1, 'leg_front_left', 'leg_front_right', 'leg_back_left', 'leg_back_right')"
]
@@ -16,8 +16,9 @@
"PORTRAIT",
"PROFILE"
],
"isBattle": true,
"animations": [
"q.look('head_ai', 1, 1, 25, -25, 40, -40)",
"q.look('head')",
"q.bedrock('lycanroc_midday', 'ground_idle')"
]
},
@@ -27,7 +28,7 @@
"SWIM"
],
"animations": [
"q.look('head_ai', 1, 1, 25, -25, 40, -40)",
"q.look('head')",
"q.bedrock('lycanroc_midday', 'ground_idle')",
"q.quadruped_walk(1, 1, 'leg_front_left', 'leg_front_right', 'leg_back_left', 'leg_back_right')"
]
@@ -16,8 +16,9 @@
"PORTRAIT",
"PROFILE"
],
"isBattle": true,
"animations": [
"q.look('head_ai')",
"q.look('head')",
"q.bedrock('lycanroc_midnight', 'ground_idle')"
]
},
@@ -27,7 +28,7 @@
"SWIM"
],
"animations": [
"q.look('head_ai')",
"q.look('head')",
"q.bedrock('lycanroc_midnight', 'ground_idle')",
"q.biped_walk(1, 1, 'leg_left', 'leg_right')"
]
@@ -65,17 +65,6 @@
"quirks": [
"q.bedrock_quirk('flapple', 'blink')"
]
},
"sleep": {
"poseTypes": [
"SLEEP"
],
"animations": [
"q.bedrock('flapple', 'closed_test')"
],
"quirks": [
],
"namedAnimations": {"cry": "q.bedrock_stateful('dummy', 'cry')"}
}
}
}
@@ -4,9 +4,6 @@
"profileScale": 0.68,
"profileTranslation": [0.00, 0.63, 0],
"rootBone": "appletun",
"animations": {
"cry": "q.bedrock_stateful('appletun', 'cry')"
},
"poses": {
"battle-standing": {
"poseTypes": ["STAND"],
@@ -100,13 +100,6 @@
],
"transformTicks": 5,
"transformToTicks": 5
},
"sleep": {
"poseTypes": ["SLEEP"],
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
},
"animations": ["q.bedrock('duraludon', 'sleep')"]
}
}
}
@@ -14,6 +14,7 @@
],
"animations": {
"cry": "q.bedrock_stateful('quaxly', 'cry')",
"recoil": "q.bedrock_stateful('quaxly', 'recoil')",
"faint": "q.bedrock_primary('quaxly', 'faint', q.curve('one'))"
},
"poses": {
@@ -18,7 +18,8 @@
"poseTypes": ["WALK"],
"animations": [
"q.look('head')",
"q.bedrock('kingambit', 'ground_idle')"
"q.bedrock('kingambit', 'ground_idle')",
"q.biped_walk(1, 1, 'leg_left', 'leg_right')"
],
"quirks": ["q.bedrock_quirk('kingambit', 'blink')"]
}
@@ -4,9 +4,6 @@
"profileScale": 0.88,
"profileTranslation": [0.00, 0.39, 0],
"rootBone": "dipplin",
"animations": {
"cry": "q.bedrock_stateful('dipplin', 'cry')"
},
"poses": {
"battle-standing": {
"poseTypes": ["STAND"],
@@ -24,7 +24,6 @@
"isBattle": false,
"condition": "!q.in_air",
"animations": [
"q.look('head_ai', 1, 1, 12.5, -12.5, 15, -15)",
"q.bedrock('archaludon', 'ground_idle')",
{
"condition": "q.is_ridden && q.has_entity",
@@ -43,7 +42,6 @@
"isBattle": true,
"condition": "!q.in_air",
"animations": [
"q.look('head_ai', 1, 1, 12.5, -12.5, 15, -15)",
"q.bedrock('archaludon', 'battle_idle')"
],
"namedAnimations": {
@@ -60,7 +58,6 @@
],
"condition": "!q.in_air && !q.is_sprinting",
"animations": [
"q.look('head_ai', 1, 1, 12.5, -12.5, 15, -15)",
"q.bedrock('archaludon', 'ground_walk')",
{
"condition": "q.is_ridden && q.has_entity",
@@ -78,7 +75,6 @@
],
"condition": "!q.in_air && q.is_sprinting",
"animations": [
"q.look('head_ai', 1, 1, 12.5, -12.5, 15, -15)",
"q.bedrock('archaludon', 'ground_run')",
{
"condition": "q.is_ridden && q.has_entity",
@@ -93,7 +89,6 @@
"poseTypes": ["STAND", "WALK"],
"condition": "q.in_air",
"animations": [
"q.look('head_ai', 1, 1, 12.5, -12.5, 15, -15)",
"q.bedrock('archaludon', 'ride_jump')",
{
"condition": "q.is_ridden",
@@ -105,13 +100,6 @@
],
"transformTicks": 5,
"transformToTicks": 5
},
"sleep": {
"poseTypes": ["SLEEP"],
"namedAnimations": {
"cry": "q.bedrock_stateful('dummy', 'cry')"
},
"animations": ["q.bedrock('archaludon', 'sleep')"]
}
}
}
@@ -15,7 +15,7 @@
"q.look('main_head_neck_end_bend', 1, 1, 5, -5, 15, -15)",
"q.look('main_head_neck_tip', 1, 1, 5, -5, 15, -15)",
"q.look('head_ai', 1, -1, 15, -15, 15, -15)",
"q.bedrock('hydrapple', 'battle_idle')"
"q.bedrock('hydrapple', 'ground_idle')"
],
"quirks": [
"q.bedrock_quirk('hydrapple', 'blink')"
@@ -25,30 +25,6 @@
"emissive": true
}
]
},
{
"aspects": [
"color-lime",
"hisuian"
],
"layers": [
{
"name": "lime",
"texture": "cobblemon:textures/pokemon/0101_electrode/electrode_watermelon_blank.png"
}
]
},
{
"aspects": [
"color-green",
"hisuian"
],
"layers": [
{
"name": "green",
"texture": "cobblemon:textures/pokemon/0101_electrode/electrode_watermelon_blank.png"
}
]
}
]
}
@@ -2878,7 +2878,6 @@
"cobblemon.battle.activate.disguise": "Its disguise served it as a decoy!",
"cobblemon.battle.activate.electricterrain": "%1$s surrounds itself with electrified terrain!",
"cobblemon.battle.activate.endure": "%1$s endured the hit!",
"cobblemon.battle.activate.ficklebeam": "%1$s is going all out for this attack!",
"cobblemon.battle.activate.firespin": "%1$s became trapped in the fiery vortex!",
"cobblemon.battle.activate.focusband": "%1$s hung on using its Focus Band!",
"cobblemon.battle.activate.forewarn": "%2$s's %3$s was revealed!",
@@ -5957,8 +5957,8 @@
"item.cobblemon.galarica_nuts": "ガラナツのナッツ",
"cobblemon.pokerod.apply": "右クリックでエサを付ける",
"item.cobblemon.npc_editor": "NPCのトレーナーカード",
"item.cobblemon.link_cable.tooltip": "なにかしらのつながりを感じさせる 不思議なエネルギーを秘めているヒモ。 ポケモン交換で進化するポケモンを進化させる。",
"item.cobblemon.dragon_scale.tooltip": "硬くて 丈夫な ウロコ。 シードラに持たせてポケモン交換すると キングドラに進化する。",
"item.cobblemon.link_cable.tooltip": "なにかしらのつながりを感じさせる 不思議なエネルギーを秘めているヒモ。ポケモン交換で進化するポケモンを進化させる。",
"item.cobblemon.dragon_scale.tooltip": "硬くて 丈夫な ウロコ。シードラに持たせてポケモン交換すると キングドラに進化する。",
"item.cobblemon.kings_rock.tooltip_1": "持たせると 攻撃して ダメージを 与えたときに 相手を ひるませることが ある。",
"item.cobblemon.metal_coat.tooltip_1": "特殊な金属の 膜。 持たせると はがねタイプの 技の威力が 上がる。",
"item.cobblemon.metal_coat.tooltip_2": "イワーク・ストライクに持たせてポケモン交換すると それぞれハガネール・ハッサムに進化する。",
@@ -5968,45 +5968,45 @@
"item.cobblemon.deep_sea_scale.tooltip_2": "パールルに持たせてポケモン交換すると サクラビスに進化する。",
"item.cobblemon.deep_sea_tooth.tooltip_1": "パールルに 持たせると 特攻が あがる キバ。",
"item.cobblemon.deep_sea_tooth.tooltip_2": "パールルに持たせてポケモン交換すると ハンテールに進化する。",
"item.cobblemon.electirizer.tooltip": "とてつもない 電気の エネルギーが 蓄えられている 箱。 エレブーに持たせてポケモン交換すると エレキブルに進化する。",
"item.cobblemon.electirizer.tooltip": "とてつもない 電気の エネルギーが 蓄えられている 箱。エレブーに持たせてポケモン交換すると エレキブルに進化する。",
"item.cobblemon.magmarizer.tooltip": "とてつもない マグマの エネルギーが 蓄えられている 箱。 ブーバーに持たせてポケモン交換すると ブーバーンに進化する。",
"item.cobblemon.oval_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 たまのように まるい。",
"item.cobblemon.reaper_cloth.tooltip": "おそろしく 強い霊力が こめられている 布。 サマヨールに持たせてポケモン交換すると ヨノワールに進化する。",
"item.cobblemon.sachet.tooltip": "ちょっと きつめの 香りをだす 香料を 詰めた 袋。 シュシュプに持たせてポケモン交換すると フレフワンに進化する。",
"item.cobblemon.strawberry_sweet.tooltip": "いちごの形をした アメ細工。 マホミルに使うと いちごのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.berry_sweet.tooltip": "ベリーの形をした アメ細工。 マホミルに使うと ベリーのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.clover_sweet.tooltip": "よつばの形をした アメ細工。 マホミルに使うと よつばのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.star_sweet.tooltip": "スターの形をした アメ細工。 マホミルに使うと スターのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.sweet_apple.tooltip": "とにかく 甘い 不思議なりんご。 カジッチュに使うと タルップルに進化する。",
"item.cobblemon.cracked_pot.tooltip": "割れている 不思議なポット。 がんさくフォルムのヤバチャに使うと ポットデスに進化する。",
"item.cobblemon.chipped_pot.tooltip": "欠けている 不思議なポット。 しんさくフォルムのヤバチャに使うと ポットデスに進化する。",
"item.cobblemon.tart_apple.tooltip": "とにかく 酸っぱい 不思議なりんご。 カジッチュに使うと アップリューに進化する。",
"item.cobblemon.reaper_cloth.tooltip": "おそろしく 強い霊力が こめられている 布。サマヨールに持たせてポケモン交換すると ヨノワールに進化する。",
"item.cobblemon.sachet.tooltip": "ちょっと きつめの 香りをだす 香料を 詰めた 袋。シュシュプに持たせてポケモン交換すると フレフワンに進化する。",
"item.cobblemon.strawberry_sweet.tooltip": "いちごの形をした アメ細工。マホミルに使うと いちごのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.berry_sweet.tooltip": "ベリーの形をした アメ細工。マホミルに使うと ベリーのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.clover_sweet.tooltip": "よつばの形をした アメ細工。マホミルに使うと よつばのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.star_sweet.tooltip": "スターの形をした アメ細工。マホミルに使うと スターのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.sweet_apple.tooltip": "とにかく 甘い 不思議なりんご。カジッチュに使うと タルップルに進化する。",
"item.cobblemon.cracked_pot.tooltip": "割れている 不思議なポット。がんさくフォルムのヤバチャに使うと ポットデスに進化する。",
"item.cobblemon.chipped_pot.tooltip": "欠けている 不思議なポット。しんさくフォルムのヤバチャに使うと ポットデスに進化する。",
"item.cobblemon.tart_apple.tooltip": "とにかく 酸っぱい 不思議なりんご。カジッチュに使うと アップリューに進化する。",
"item.cobblemon.galarica_wreath.tooltip": "ガラナツのナッツを 編み込んだ 冠。 ガラルのすがたのヤドンに使うと ヤドキングに進化する。",
"item.cobblemon.black_augurite.tooltip": "割ると鋭い切れ味を持つ ガラスに似た性質の黒い石。 ストライクに使うと バサギリに進化する。",
"item.cobblemon.peat_block.tooltip": "泥のような石炭のかたまり。 満月の夜に リングマに使うと ガチグマに進化する。",
"item.cobblemon.dawn_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 ひとみのように まばゆい。",
"item.cobblemon.black_augurite.tooltip": "割ると鋭い切れ味を持つ ガラスに似た性質の黒い石。ストライクに使うと バサギリに進化する。",
"item.cobblemon.peat_block.tooltip": "泥のような石炭のかたまり。満月の夜に リングマに使うと ガチグマに進化する。",
"item.cobblemon.dawn_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。ひとみのように まばゆい。",
"item.cobblemon.dusk_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。やみのように 暗い。",
"item.cobblemon.fire_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 だいだい色を している。",
"item.cobblemon.ice_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 雪の模様が ある。",
"item.cobblemon.leaf_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 葉っぱの模様が ある。",
"item.cobblemon.shiny_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 ひかりのように まぶしい。",
"item.cobblemon.thunder_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 稲妻の模様が ある。",
"item.cobblemon.water_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 澄んだ水色を している。",
"item.cobblemon.fire_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。だいだい色を している。",
"item.cobblemon.ice_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。雪の模様が ある。",
"item.cobblemon.leaf_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。葉っぱの模様が ある。",
"item.cobblemon.shiny_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。ひかりのように まぶしい。",
"item.cobblemon.thunder_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。稲妻の模様が ある。",
"item.cobblemon.water_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。澄んだ水色を している。",
"item.cobblemon.exp_candy_xs.tooltip": "エネルギーの つまった アメ。 与えると ポケモン 1匹の 経験値が 100 増える。",
"item.cobblemon.exp_candy_m.tooltip": "エネルギーの つまった アメ。 与えると ポケモン 1匹の 経験値が 3000 増える。",
"item.cobblemon.exp_candy_l.tooltip": "ネルギーの つまった アメ。 与えると ポケモン 1匹の 経験値が 10000 増える。",
"item.cobblemon.iron.tooltip": "ポケモンの 栄養ドリンク。 ポケモン 1匹の 防御の 基礎ポイントを 10 あげる。",
"item.cobblemon.carbos.tooltip": "ポケモンの 栄養ドリンク。 ポケモン 1匹の 素早さの 基礎ポイントを 10 あげる。",
"item.cobblemon.calcium.tooltip": "ポケモンの 栄養ドリンク。 ポケモン 1匹の 特攻の 基礎ポイントを 10 あげる。",
"item.cobblemon.protein.tooltip": "ポケモンの 栄養ドリンク。 ポケモン 1匹の 攻撃の 基礎ポイントを 10 あげる。",
"item.cobblemon.potion.tooltip": "スプレー式の キズぐすり。 ポケモン 1匹の HPを 60だけ 回復する。",
"item.cobblemon.super_potion.tooltip": "スプレー式の キズぐすり。 ポケモン 1匹の HPを 100だけ 回復する。",
"item.cobblemon.max_potion.tooltip": "スプレー式の キズぐすり。 ポケモン 1匹の HPを すべて 回復する。",
"item.cobblemon.full_restore.tooltip": "スプレー式の キズぐすり。 ポケモン 1匹の HPと 状態異常を すべて 回復する。",
"item.cobblemon.iron.tooltip": "ポケモンの 栄養ドリンク。ポケモン 1匹の 防御の 基礎ポイントを 10 あげる。",
"item.cobblemon.carbos.tooltip": "ポケモンの 栄養ドリンク。ポケモン 1匹の 素早さの 基礎ポイントを 10 あげる。",
"item.cobblemon.calcium.tooltip": "ポケモンの 栄養ドリンク。ポケモン 1匹の 特攻の 基礎ポイントを 10 あげる。",
"item.cobblemon.protein.tooltip": "ポケモンの 栄養ドリンク。ポケモン 1匹の 攻撃の 基礎ポイントを 10 あげる。",
"item.cobblemon.potion.tooltip": "スプレー式の キズぐすり。ポケモン 1匹の HPを 60だけ 回復する。",
"item.cobblemon.super_potion.tooltip": "スプレー式の キズぐすり。ポケモン 1匹の HPを 100だけ 回復する。",
"item.cobblemon.max_potion.tooltip": "スプレー式の キズぐすり。ポケモン 1匹の HPを すべて 回復する。",
"item.cobblemon.full_restore.tooltip": "スプレー式の キズぐすり。ポケモン 1匹の HPと 状態異常を すべて 回復する。",
"item.cobblemon.health_feather.tooltip": "ポケモンに 使う 道具。 ポケモン 1匹の HPの 基礎ポイントを ちょっと あげる。",
"item.cobblemon.muscle_feather.tooltip": "ポケモンに 使う 道具。 ポケモン 1匹の 攻撃の 基礎ポイントを ちょっと あげる。",
"item.cobblemon.genius_feather.tooltip": "ポケモンに 使う 道具。 ポケモン 1匹の 特攻の 基礎ポイントを ちょっと あげる。",
"item.cobblemon.clever_feather.tooltip": "ポケモンに 使う 道具。 ポケモン 1匹の 特防の 基礎ポイントを ちょっと あげる。",
"item.cobblemon.clever_feather.tooltip": "ポケモンに 使う 道具。ポケモン 1匹の 特防の 基礎ポイントを ちょっと あげる。",
"item.cobblemon.ability_capsule.tooltip": "2種類の特性を 持つ ポケモンに 使うと 今とは違う 特性に 変えられる カプセル。",
"item.cobblemon.adamant_mint.tooltip": "ポケモンに 香りを かがせると 攻撃が 上がりやすく なるが 特攻は 上がりにくくなる ミント。",
"item.cobblemon.brave_mint.tooltip": "ポケモンに 香りを かがせると 攻撃が 上がりやすく なるが 素早さは 上がりにくくなる ミント。",
@@ -6023,7 +6023,7 @@
"item.cobblemon.absorb_bulb.tooltip_2": "使うとなくなる。",
"item.cobblemon.air_balloon.tooltip_2": "攻撃を 受けると 割れてしまう。",
"item.cobblemon.assault_vest.tooltip": "攻撃的になる チョッキ。 持たせると 特防が あがるが 変化技を だせなくなる。",
"item.cobblemon.malicious_armor.tooltip": "呪いの感情が 秘められている 不思議なヨロイ。 カルボウに使うと ソウブレイズに進化させる。",
"item.cobblemon.malicious_armor.tooltip": "呪いの感情が 秘められている 不思議なヨロイ。カルボウに使うと ソウブレイズに進化させる。",
"item.cobblemon.black_belt.tooltip": "気が ひきしまる 帯。 持たせると かくとうタイプの 技の威力が あがる。",
"item.cobblemon.black_glasses.tooltip": "怪しく見える メガネ。 持たせると あくタイプの 技の威力が あがる。",
"item.cobblemon.blunder_policy.tooltip_2": "使うとなくなる。",
@@ -6031,7 +6031,7 @@
"item.cobblemon.eject_button.tooltip_2": "使うとなくなる。",
"item.cobblemon.eject_pack.tooltip_2": "使うとなくなる。",
"item.cobblemon.blunder_policy.tooltip_1": "命中率に よって 技が はずれたとき 素早さが ぐーんと 上がる。",
"item.cobblemon.charcoal_stick.tooltip": "少し大きな棒型の木炭。 持たせると ほのおタイプの 技の威力が あがる。",
"item.cobblemon.charcoal_stick.tooltip": "少し大きな棒型の木炭。持たせると ほのおタイプの 技の威力が あがる。",
"item.cobblemon.choice_band.tooltip": "ちょっと こだわった ハチマキ。 持たせると 攻撃は あがるが 同じ技しか だせなくなる。",
"item.cobblemon.choice_specs.tooltip": "ちょっと こだわった メガネ。 持たせると 特攻は あがるが 同じ技しか だせなくなる。",
"item.cobblemon.cleanse_tag.tooltip": "効果なし",
@@ -6052,47 +6052,47 @@
"item.cobblemon.grass_gem.tooltip_2": "使うとなくなる。",
"item.cobblemon.dragon_gem.tooltip_2": "使うとなくなる。",
"item.cobblemon.ghost_gem.tooltip_2": "使うとなくなる。",
"item.cobblemon.whipped_dream.tooltip": "ふんわり ふわふわに 泡立てた ほんのり 甘い クリーム。 ペロッパフに持たせてポケモン交換すると ペロリームに進化する。",
"item.cobblemon.sun_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 太陽のように 赤い。",
"item.cobblemon.prism_scale.tooltip": "にじ色に 輝く 不思議なウロコ。 ヒンバスに持たせてポケモン交換すると ミロカロスに進化する。",
"item.cobblemon.love_sweet.tooltip": "ハートの形をした アメ細工。 マホミルに使うと ハートのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.flower_sweet.tooltip": "おはなの形をした アメ細工。 マホミルに使うと おはなのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.whipped_dream.tooltip": "ふんわり ふわふわに 泡立てた ほんのり 甘い クリーム。ペロッパフに持たせてポケモン交換すると ペロリームに進化する。",
"item.cobblemon.sun_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。太陽のように 赤い。",
"item.cobblemon.prism_scale.tooltip": "にじ色に 輝く 不思議なウロコ。ヒンバスに持たせてポケモン交換すると ミロカロスに進化する。",
"item.cobblemon.love_sweet.tooltip": "ハートの形をした アメ細工。マホミルに使うと ハートのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.flower_sweet.tooltip": "おはなの形をした アメ細工。マホミルに使うと おはなのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.swift_feather.tooltip": "ポケモンに 使う 道具。 ポケモン 1匹の 素早さの 基礎ポイントを ちょっと あげる。",
"item.cobblemon.ability_patch.tooltip": "通常の特性を 持つ ポケモンに 使うと めずらしい 隠れ特性に 変えられる パッチ。 隠れ特性に 使うと 通常の特性に 戻る。",
"item.cobblemon.ability_patch.tooltip": "通常の特性を 持つ ポケモンに 使うと めずらしい 隠れ特性に 変えられる パッチ。",
"item.cobblemon.mild_mint.tooltip": "ポケモンに 香りを かがせると 特攻が 上がりやすく なるが 防御は 上がりにくくなる ミント。",
"item.cobblemon.jolly_mint.tooltip": "ポケモンに 香りを かがせると 素早さが 上がりやすく なるが 特攻は 上がりにくくなる ミント。",
"item.cobblemon.air_balloon.tooltip_1": "ポケモンに 持たせると ポケモンが 宙に 浮く。",
"item.cobblemon.cell_battery.tooltip_1": "持たせて でんきの技の ダメージを 受けると 攻撃が あがる。",
"item.cobblemon.protector.tooltip": "なにかの プロテクター。 とても 硬くて 重い。 サイドンに持たせてポケモン交換すると ドサイドンに進化する。",
"item.cobblemon.ribbon_sweet.tooltip": "リボンの形をした アメ細工。 マホミルに使うと リボンのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.protector.tooltip": "なにかの プロテクター。 とても 硬くて 重い。サイドンに持たせてポケモン交換すると ドサイドンに進化する。",
"item.cobblemon.ribbon_sweet.tooltip": "リボンの形をした アメ細工。マホミルに使うと リボンのアメざいくを身に付けた マホイップになる。",
"item.cobblemon.exp_candy_xl.tooltip": "エネルギーの つまった アメ。 与えると ポケモン 1匹の 経験値が 30000 増える。",
"item.cobblemon.zinc.tooltip": "ポケモンの 栄養ドリンク。 ポケモン 1匹の 特防の 基礎ポイントを 10 あげる。",
"item.cobblemon.resist_feather.tooltip": "ポケモンに 使う 道具。 ポケモン 1匹の 防御の 基礎ポイントを ちょっと あげる。",
"item.cobblemon.resist_feather.tooltip": "ポケモンに 使う 道具。ポケモン 1匹の 防御の 基礎ポイントを ちょっと あげる。",
"item.cobblemon.bold_mint.tooltip": "ポケモンに 香りを かがせると 防御が 上がりやすく なるが 攻撃は 上がりにくくなる ミント。",
"item.cobblemon.covert_cloak.tooltip": "敵の目を あざむく フード付き マント。 持たせると 体を 包み隠し 技の 追加効果を 受けなくなる。",
"item.cobblemon.unremarkable_teacup.tooltip": "割れている 不思議な茶碗。 マガイモノのすがたのチャデスに使うと ヤバソチャに進化する。",
"item.cobblemon.unremarkable_teacup.tooltip": "割れている 不思議な茶碗。マガイモノのすがたのチャデスに使うと ヤバソチャに進化する。",
"item.cobblemon.galarica_cuff.tooltip": "ガラナツのナッツを 編み込んだ ブレスレット。 ガラルのすがたのヤドンに使うと ヤドランに進化する。",
"item.cobblemon.lonely_mint.tooltip": "ポケモンに 香りを かがせると 攻撃が 上がりやすく なるが 防御は 上がりにくくなる ミント。",
"item.cobblemon.normal_gem.tooltip_2": "使うとなくなる。",
"item.cobblemon.auspicious_armor.tooltip": "祝いの感情が 秘められている 不思議なヨロイ。 カルボウに使うと グレンアルマに進化させる。",
"item.cobblemon.auspicious_armor.tooltip": "祝いの感情が 秘められている 不思議なヨロイ。カルボウに使うと グレンアルマに進化させる。",
"item.cobblemon.kings_rock.tooltip_2": "ヤドン・ニョロゾに持たせてポケモン交換すると それぞれヤドラン・ニョロトノに進化する。",
"item.cobblemon.masterpiece_teacup.tooltip": "欠けている 不思議な茶碗。 タカイモノのすがたのチャデスに使うと ヤバソチャに進化する。",
"item.cobblemon.moon_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。 夜空のように 黒い。",
"item.cobblemon.rare_candy.tooltip": "エネルギーの つまった アメ。 あたえると ポケモン 1匹の レベルが 1だけ あがる。",
"item.cobblemon.hyper_potion.tooltip": "スプレー式の キズぐすり。 ポケモン 1匹の HPを 150だけ 回復する。",
"item.cobblemon.masterpiece_teacup.tooltip": "欠けている 不思議な茶碗。タカイモノのすがたのチャデスに使うと ヤバソチャに進化する。",
"item.cobblemon.moon_stone.tooltip": "ある特定の ポケモンを 進化させる 不思議な石。夜空のように 黒い。",
"item.cobblemon.rare_candy.tooltip": "エネルギーの つまった アメ。あたえると ポケモン 1匹の レベルが 1だけ あがる。",
"item.cobblemon.hyper_potion.tooltip": "スプレー式の キズぐすり。ポケモン 1匹の HPを 150だけ 回復する。",
"item.cobblemon.naughty_mint.tooltip": "ポケモンに 香りを かがせると 攻撃が 上がりやすく なるが 特防は 上がりにくくなる ミント。",
"item.cobblemon.relaxed_mint.tooltip": "ポケモンに 香りを かがせると 防御が 上がりやすく なるが 素早さは 上がりにくくなる ミント。",
"item.cobblemon.timid_mint.tooltip": "ポケモンに 香りを かがせると 素早さが 上がりやすく なるが 攻撃は 上がりにくくなる ミント。",
"item.cobblemon.serious_mint.tooltip": "ポケモンに 香りを かがせると 攻撃 防御 素早さ 特防 特攻が 万遍なく 育つ ミント。",
"item.cobblemon.red_card.tooltip_2": "使うとなくなる。",
"item.cobblemon.black_sludge.tooltip": "持たせると どくタイプの ポケモンは 少しずつ HPを 回復する。 それ以外は HPが 減ってしまう。",
"item.cobblemon.black_sludge.tooltip": "持たせると どくタイプの ポケモンは 少しずつ HPを 回復する。それ以外は HPが 減ってしまう。",
"item.cobblemon.exp_candy_s.tooltip": "エネルギーの つまった アメ。 与えると ポケモン 1匹の 経験値が 800 増える。",
"item.cobblemon.hp_up.tooltip": "ポケモンの 栄養ドリンク。 ポケモン 1匹の HPの 基礎ポイントを 10 あげる。",
"item.cobblemon.hp_up.tooltip": "ポケモンの 栄養ドリンク。ポケモン 1匹の HPの 基礎ポイントを 10 あげる。",
"item.cobblemon.calm_mint.tooltip": "ポケモンに 香りを かがせると 特防が 上がりやすく なるが 攻撃は 上がりにくくなる ミント。",
"item.cobblemon.careful_mint.tooltip": "ポケモンに 香りを かがせると 特防が 上がりやすく なるが 特攻は 上がりにくくなる ミント。",
"item.cobblemon.hasty_mint.tooltip": "ポケモンに 香りを かがせると 素早さが 上がりやすく なるが 防御は 上がりにくくなる ミント。",
"item.cobblemon.white_herb.tooltip_2": "使うとなくなる。",
"item.cobblemon.binding_band.tooltip": "締めつける技を 補助する バンド。 持たせると 締めつける技の 威力が 強くなる。",
"item.cobblemon.binding_band.tooltip": "締めつける技を 補助する バンド。持たせると 締めつける技の 威力が 強くなる。",
"item.cobblemon.choice_scarf.tooltip": "ちょっと こだわった スカーフ。 持たせると 素早さは あがるが 同じ技しか だせなくなる。",
"item.cobblemon.electric_seed.tooltip": "ポケモンに 持たせると エレキフィールドのときに 使って 防御が あがる。",
"item.cobblemon.exp_share.tooltip": "持たせた ポケモンは 戦闘に でなくても 経験値を わけてもらえる 便利な 装置。",
@@ -6104,60 +6104,60 @@
"item.cobblemon.grassy_seed.tooltip": "ポケモンに 持たせると グラスフィールドのときに 使って 防御が あがる。",
"item.cobblemon.hard_stone.tooltip": "絶対に 割れない石。 持たせると いわタイプの 技の威力が あがる。",
"item.cobblemon.heavy_duty_boots.tooltip": "足場に しかけられた 罠などの影響を 受けなくなる。",
"item.cobblemon.iron_ball.tooltip": "持たせると 素早さが さがる。 ひこうタイプや ふゆうポケモンは じめん技が 当たってしまう。",
"item.cobblemon.iron_ball.tooltip": "持たせると 素早さが さがる。ひこうタイプや ふゆうポケモンは じめん技が 当たってしまう。",
"item.cobblemon.light_ball.tooltip": "ピカチュウに 持たせると 攻撃と 特攻が あがる 不思議な玉。",
"item.cobblemon.loaded_dice.tooltip": "いい目しか 出ない サイコロ。 持たせて 連続技を 使うと 多めに 技を 出すことが できる。",
"item.cobblemon.lucky_egg.tooltip": "しあわせが つまった タマゴ。 持たせたポケモンは もらえる 経験値が 少し増える。",
"item.cobblemon.magnet.tooltip": "強力な 磁石。 持たせると でんきタイプの 技の威力が あがる。",
"item.cobblemon.miracle_seed.tooltip": "生命が宿る タネ。 持たせると くさタイプの 技の威力が あがる。",
"item.cobblemon.muscle_band.tooltip": "ちからが わいてくる ハチマキ。 持たせると 物理技の 威力が 少し あがる。",
"item.cobblemon.never_melt_ice.tooltip": "熱を よせつけない 氷。 持たせると こおりタイプの 技の威力が あがる。",
"item.cobblemon.poison_barb.tooltip": "どくのある ちいさな ハリ。 持たせると どくタイプの 技の威力が あがる。",
"item.cobblemon.punching_glove.tooltip": "こぶしを 保護する グローブ。 持たせると パンチ技の 威力が あがり 相手に 接触しない パンチに なる。",
"item.cobblemon.quick_claw.tooltip": "軽くて 鋭い ツメ。 持たせると 相手より 先に 行動できることが ある。",
"item.cobblemon.loaded_dice.tooltip": "いい目しか 出ない サイコロ。持たせて 連続技を 使うと 多めに 技を 出すことが できる。",
"item.cobblemon.lucky_egg.tooltip": "しあわせが つまった タマゴ。持たせたポケモンは もらえる 経験値が 少し増える。",
"item.cobblemon.magnet.tooltip": "強力な 磁石。持たせると でんきタイプの 技の威力が あがる。",
"item.cobblemon.miracle_seed.tooltip": "生命が宿る タネ。持たせると くさタイプの 技の威力が あがる。",
"item.cobblemon.muscle_band.tooltip": "ちからが わいてくる ハチマキ。持たせると 物理技の 威力が 少し あがる。",
"item.cobblemon.never_melt_ice.tooltip": "熱を よせつけない 氷。持たせると こおりタイプの 技の威力が あがる。",
"item.cobblemon.poison_barb.tooltip": "どくのある ちいさな ハリ。持たせると どくタイプの 技の威力が あがる。",
"item.cobblemon.punching_glove.tooltip": "こぶしを 保護する グローブ。持たせると パンチ技の 威力が あがり 相手に 接触しない パンチに なる。",
"item.cobblemon.quick_claw.tooltip": "軽くて 鋭い ツメ。持たせると 相手より 先に 行動できることが ある。",
"item.cobblemon.razor_fang.tooltip_1": "鋭く とがった キバ。持たせると ダメージを 与えたとき ひるませることが ある。",
"item.cobblemon.razor_fang.tooltip_2": "グライガーに 持たせると、 夜にグライオンに進化する。",
"item.cobblemon.razor_fang.tooltip_2": "グライガーに持たせて夜にレベルアップさせると、グライオンに進化する。",
"item.cobblemon.red_card.tooltip_1": "不思議な ちからのある カード。 持たせると ダメージを 与えてきた 相手を 控えに 退場させることが できる。",
"item.cobblemon.rocky_helmet.tooltip": "ポケモンに 持たせると 自分に さわった相手に ダメージを 与える。",
"item.cobblemon.room_service.tooltip_1": "ポケモンに 持たせると トリックルームのときに 使って 素早さが 下がる。",
"item.cobblemon.scope_lens.tooltip": "弱点が みえる レンズ。 持たせた ポケモンの技が 急所に 当たりやすくなる。",
"item.cobblemon.sharp_beak.tooltip": "長く とがった くちばし。 持たせると ひこうタイプの 技の威力が あがる。",
"item.cobblemon.shed_shell.tooltip": "丈夫で 硬い ぬけがら。 持たせた ポケモンは 控えの ポケモンと 必ず いれかわれる。",
"item.cobblemon.silk_scarf.tooltip": "はだざわりの よい スカーフ。 持たせると ノーマルタイプの 技の 威力が あがる。",
"item.cobblemon.silver_powder.tooltip": "銀色に 輝く 粉。 持たせると むしタイプの 技の威力が あがる。",
"item.cobblemon.soothe_bell.tooltip": "心地よい 音色の鈴。 持たせたポケモンは 心が 安らぎ なかよく なりやすくなる。",
"item.cobblemon.spell_tag.tooltip": "怪しくて 不気味な お札。 持たせると ゴーストタイプの 技の威力が あがる。",
"item.cobblemon.sticky_barb.tooltip": "持たせると 毎ターン ダメージを 受ける。 自分に ふれてきた 相手に くっつくことも ある。",
"item.cobblemon.scope_lens.tooltip": "弱点が みえる レンズ。持たせた ポケモンの技が 急所に 当たりやすくなる。",
"item.cobblemon.sharp_beak.tooltip": "長く とがった くちばし。持たせると ひこうタイプの 技の威力が あがる。",
"item.cobblemon.shed_shell.tooltip": "丈夫で 硬い ぬけがら。持たせた ポケモンは 控えの ポケモンと 必ず いれかわれる。",
"item.cobblemon.silk_scarf.tooltip": "はだざわりの よい スカーフ。持たせると ノーマルタイプの 技の 威力が あがる。",
"item.cobblemon.silver_powder.tooltip": "銀色に 輝く 粉。持たせると むしタイプの 技の威力が あがる。",
"item.cobblemon.soothe_bell.tooltip": "心地よい 音色の鈴。持たせたポケモンは 心が 安らぎ なかよく なりやすくなる。",
"item.cobblemon.spell_tag.tooltip": "怪しくて 不気味な お札。持たせると ゴーストタイプの 技の威力が あがる。",
"item.cobblemon.sticky_barb.tooltip": "持たせると 毎ターン ダメージを 受ける。自分に ふれてきた 相手に くっつくことも ある。",
"item.cobblemon.terrain_extender.tooltip": "持たせたポケモンが 技や 特性で フィールドを 張ったとき いつもよりも 長く 残る。",
"item.cobblemon.throat_spray.tooltip_1": "音に 関する 技を 使うと 特攻が 上がる。",
"item.cobblemon.twisted_spoon.tooltip": "念力を こめた スプーン。 持たせると エスパータイプの 技の威力が あがる。",
"item.cobblemon.twisted_spoon.tooltip": "念力を こめた スプーン。持たせると エスパータイプの 技の威力が あがる。",
"item.cobblemon.utility_umbrella.tooltip": "持たせた ポケモンは 雨と 日差しが強いときの 影響を 受けなくなる。",
"item.cobblemon.weakness_policy.tooltip_1": "弱点を つかれたとき 攻撃と 特攻が それぞれ ぐーんと あがる。",
"item.cobblemon.wide_lens.tooltip": "ものが 大きく見える レンズ。 持たせると 技の命中率が 少し あがる。",
"item.cobblemon.wide_lens.tooltip": "ものが 大きく見える レンズ。持たせると 技の命中率が 少し あがる。",
"item.cobblemon.wise_glasses.tooltip": "ぶあつい レンズの ついた メガネ。 持たせると 特殊技の 威力が 少し あがる。",
"item.cobblemon.mental_herb.tooltip_1": "持たせたポケモンが 自由に 技を だせなくなったときに 1度だけ 回復する。",
"item.cobblemon.misty_seed.tooltip": "ポケモンに 持たせると ミストフィールドのときに 使って 特防が あがる。",
"item.cobblemon.power_herb.tooltip_1": "持たせたポケモンは 1度だけ 1ターン目に ちからを ためる技を すぐに 使うことが できる。",
"item.cobblemon.bright_powder.tooltip": "キラキラ 光る粉。 持たせると 光が 相手を 惑わして 技が 10% 命中しにくくなる。",
"item.cobblemon.metal_powder.tooltip": "メタモンに 持たせると 50% 防御が あがる 不思議な粉。 とても こまかくて 硬い。",
"item.cobblemon.quick_powder.tooltip": "メタモンに 持たせると 素早さが あがる 不思議な粉。 とても こまかくて 硬い。",
"item.cobblemon.destiny_knot.tooltip": "細くて 長い 真っ赤な糸。 持たせると メロメロに なったとき 相手も メロメロに できる。",
"item.cobblemon.metal_powder.tooltip": "メタモンに 持たせると 50% 防御が あがる 不思議な粉。とても こまかくて 硬い。",
"item.cobblemon.quick_powder.tooltip": "メタモンに 持たせると 素早さが あがる 不思議な粉。とても こまかくて 硬い。",
"item.cobblemon.destiny_knot.tooltip": "細くて 長い 真っ赤な糸。持たせると メロメロに なったとき 相手も メロメロに できる。",
"item.cobblemon.power_anklet.tooltip": "持たせると 戦闘中の 素早さが さがるが ふつうよりも ポケモンの 素早さの基礎ポイントが 8 多く 育つ。",
"item.cobblemon.power_band.tooltip": "持たせると 戦闘中の 素早さが さがるが ふつうよりも ポケモンの 特防の基礎ポイントが 8 多く 育つ。",
"item.cobblemon.power_bracer.tooltip": "持たせると 戦闘中の 素早さが さがるが ふつうよりも ポケモンの 攻撃の基礎ポイントが 8 多く 育つ。",
"item.cobblemon.power_lens.tooltip": "持たせると 戦闘中の 素早さが さがるが ふつうよりも ポケモンの 特攻の基礎ポイントが 8 多く 育つ。",
"item.cobblemon.power_weight.tooltip": "持たせると 戦闘中の 素早さが さがるが ふつうよりも ポケモンの HPの基礎ポイントが 8 多く 育つ。",
"item.cobblemon.psychic_seed.tooltip": "ポケモンに 持たせると サイコフィールドのときに 使って 特防が あがる。",
"item.cobblemon.flame_orb.tooltip": "触ると 熱をだす 不思議な玉。 持たせると 戦闘中に やけどの状態に なる。",
"item.cobblemon.flame_orb.tooltip": "触ると 熱をだす 不思議な玉。持たせると 戦闘中に やけどの状態に なる。",
"item.cobblemon.smoke_ball.tooltip": "効果なし",
"item.cobblemon.toxic_orb.tooltip": "触ると 毒をだす 不思議な玉。 持たせると 戦闘中に 猛毒の状態に なる。",
"item.cobblemon.toxic_orb.tooltip": "触ると 毒をだす 不思議な玉。持たせると 戦闘中に 猛毒の状態に なる。",
"item.cobblemon.life_orb.tooltip": "持たせると 攻撃するたびに HPが 少し 減ってしまうが 技の威力が あがる。",
"item.cobblemon.damp_rock.tooltip": "持たせた ポケモンが 天気を あめにすると いつもより あめの時間が 長くなる。",
"item.cobblemon.heat_rock.tooltip": "持たせた ポケモンが 日差しを 強くすると いつもより はれの時間が 長くなる。",
"item.cobblemon.smooth_rock.tooltip": "持たせたポケモンが すなあらしを 起こすと いつもより すなあらしの時間が 長くなる。",
"item.cobblemon.icy_rock.tooltip": "持たせたポケモンが 天気を ゆき または あられにすると いつもより 時間が 長くなる。",
"item.cobblemon.medicinal_leek.tooltip_1": "クスリチャの調合に必要となる。 世界の各地に自生しており 旅の供とも呼ばれる。",
"item.cobblemon.medicinal_leek.tooltip_2": "カモネギや カモネギ(ガラルのすがた)、 ネギガナイトに 持たせると 急所に当てる確率が 2段階 あがる。",
"item.cobblemon.medicinal_leek.tooltip_1": "クスリチャの調合に必要となる。世界の各地に自生しており 旅の供とも呼ばれる。",
"item.cobblemon.medicinal_leek.tooltip_2": "カモネギや カモネギ(ガラルのすがた)、ネギガナイトに 持たせると 急所に当てる確率が 2段階 あがる。",
"item.cobblemon.revival_herb.tooltip": "とても にがい 薬草。 ひんしの ポケモン 1匹の HPを 4分の1 回復するが なかよし度は 下がる。",
"item.cobblemon.berry_juice.tooltip": "きのみ 100%の ジュース。 ポケモンに 使ったり 持たせたりすると HPを 20だけ 回復する。",
"item.cobblemon.remedy.tooltip": "キズぐすりと同じで ポケモン1匹のHPが60回復するが 苦く なかよし度がさがる。",
@@ -6165,7 +6165,7 @@
"item.cobblemon.superb_remedy.tooltip": "すごいキズぐすりと同じで ポケモン1匹のHPが150回復するが 苦く なかよし度がさがる。",
"item.cobblemon.revive.tooltip": "ひんしになった ポケモン 1匹を 元気に したうえで HPを 半分まで 回復する。",
"item.cobblemon.max_revive.tooltip": "ひんしになった ポケモン 1匹を 元気に したうえで HPを すべて 回復する。",
"item.cobblemon.pp_up.tooltip": "ポケモンが 覚えている 技のうち 1つの PPの 最大値を 20% あげる。 上げられるのは 60%まで。",
"item.cobblemon.pp_up.tooltip": "ポケモンが 覚えている 技のうち 1つの PPの 最大値を 20% あげる。上げられるのは 60%まで。",
"item.cobblemon.pp_max.tooltip": "ポケモンが 覚えている 技のうち 1つの PPの 最大値を +60%分まで 一気に 上げる。",
"item.cobblemon.full_heal.tooltip": "スプレー式の 薬。 ポケモン 1匹の 状態の 異常を すべて 回復する。",
"item.cobblemon.antidote.tooltip": "スプレー式の 薬。 ポケモン 1匹の どくの 状態を 回復する。",
@@ -6228,33 +6228,33 @@
"cobblemon.trade.decline.sender": "%1$sはあなたの交換リクエストを拒否しました。",
"cobblemon.trade.decline.receiver": "あなたは %1$s の交換リクエストを拒否しました。",
"cobblemon.trade.error.insufficient_pokemon.other": "%1$sは交換するポケモンを持っていない!",
"item.cobblemon.metronome.tooltip": "持たせると 同じ技を 連続で 使ったとき 威力が あがる。 やめると 威力は もどる。",
"item.cobblemon.razor_claw.tooltip_1": "鋭く とがった ツメ。 持たせると 技が 急所に 当たりやすくなる。",
"item.cobblemon.metronome.tooltip": "持たせると 同じ技を 連続で 使ったとき 威力が あがる。やめると 威力は もどる。",
"item.cobblemon.razor_claw.tooltip_1": "鋭く とがった ツメ。持たせると 技が 急所に 当たりやすくなる。",
"item.cobblemon.ring_target.tooltip": "持っている ポケモンは タイプの相性で 無効だった 技が 相性に関係なく 当たるように なってしまう。",
"item.cobblemon.zoom_lens.tooltip": "持たせたポケモンが 相手よりも 行動するのが 遅いとき 技が 命中しやすくなる。",
"item.cobblemon.power_belt.tooltip": "持たせると 戦闘中の 素早さが さがるが ふつうよりも ポケモンの 防御の基礎ポイントが 8 多く 育つ。",
"item.cobblemon.max_ether.tooltip": "ポケモンが 覚えている 技のうち 1つのPPを すべて 回復する。",
"item.cobblemon.rock_gem.tooltip_1": "いわのタイプの ジュエル。 持たせると 1度だけ いわの 技の威力が 強まる。",
"item.cobblemon.soft_sand.tooltip": "さわると サラサラする砂。 持たせると じめんタイプの 技の威力が あがる。",
"item.cobblemon.soft_sand.tooltip": "さわると サラサラする砂。持たせると じめんタイプの 技の威力が あがる。",
"cobblemon.command.pc.invalid-box": "ボックス番号 %1$s が最大ボックス数 %2$s を超えています。",
"cobblemon.trade.expired.receiver": "%1$s からの交換リクエストがタイムアウトしました。",
"item.cobblemon.leftovers.tooltip": "持たせると ポケモンの HPが 戦闘のあいだ 少しずつ 回復する。",
"item.cobblemon.mystic_water.tooltip": "しずくの形の 宝石。 持たせると みずタイプの 技の威力が あがる。",
"item.cobblemon.mystic_water.tooltip": "しずくの形の 宝石。持たせると みずタイプの 技の威力が あがる。",
"item.cobblemon.shell_helmet": "カラっぽのシェルメット",
"item.cobblemon.fighting_gem.tooltip_1": "かくとうのタイプの ジュエル。 持たせると 1度だけ かくとうの 技の威力が 強まる。",
"item.cobblemon.energy_root.tooltip": "とても にがい ねっこ。 ポケモン 1匹の HPを 80回復するが なかよし度は 下がる。",
"item.cobblemon.energy_root.tooltip": "とても にがい ねっこ。ポケモン 1匹の HPを 80回復するが なかよし度は 下がる。",
"item.cobblemon.heal_powder.tooltip": "とても にがい 粉薬。 ポケモン 1匹の 状態の 異常を すべて 回復するが なかよし度は 下がる。",
"cobblemon.trade.error.insufficient_pokemon.self": "交換するポケモンがいません!",
"item.cobblemon.light_clay.tooltip": "持たせたポケモンが ひかりのかべや リフレクターを 使ったとき いつもよりも 長く 残る。",
"item.cobblemon.protective_pads.tooltip": "攻撃する 相手に さわって 受ける 効果を 受けないように する。",
"item.cobblemon.razor_claw.tooltip_2": "ニューラに持たせると 夜にマニューラ、 ニューラ(ヒスイのすがた)に持たせると 昼にオオニューラに進化する。",
"item.cobblemon.razor_claw.tooltip_2": "ニューラに持たせて夜にレベルアップさせるとマニューラ、ニューラ(ヒスイのすがた)に持たせて昼にレベルアップさせるとオオニューラに進化する。",
"item.cobblemon.mirror_herb.tooltip_1": "持たせたポケモンは 1度だけ 相手の 能力が あがったとき まねして 同じように 能力を 上げる。",
"item.cobblemon.white_herb.tooltip_1": "持たせた ポケモンの能力が さがったとき 1度だけ 元の状態に 戻す。",
"item.cobblemon.normal_gem.tooltip_1": "ノーマルのタイプの ジュエル。 持たせると 1度だけ ノーマルの 技の威力が 強まる。",
"cobblemon.trade.accept.receiver": "あなたは %1$s の交換リクエストを受け入れました!",
"item.cobblemon.safety_goggles.tooltip": "天候の ダメージだけでなく 粉を だす 技の 効果も 防げる ゴーグル。",
"item.cobblemon.shell_bell.tooltip": "持たせた ポケモンが 攻撃して 相手に ダメージを あたえたとき HPを 少し 回復できる。",
"item.cobblemon.shell_helmet.tooltip": "とあるポケモンが身に付けていた殻。 カブルモに使うと シュバルゴに進化する。",
"item.cobblemon.shell_helmet.tooltip": "とあるポケモンが身に付けていた殻。カブルモに使うと シュバルゴに進化する。",
"cobblemon.trade.expired.sender": "%1$s との交換リクエストがタイムアウトしました。",
"item.cobblemon.ground_gem.tooltip_1": "じめんのタイプの ジュエル。 持たせると 1度だけ じめんの 技の威力が 強まる。",
"item.cobblemon.x_attack.tooltip": "戦闘中の ポケモンの 攻撃を 2段階 あげる 道具。 ひっこめると 元に 戻る。",
@@ -6271,7 +6271,7 @@
"cobblemon.ui.wallpapers": "壁紙",
"cobblemon.ui.interact.ride": "ライド",
"cobblemon.ui.interact.give.cosmetic_item": "衣装アイテムの変更",
"item.cobblemon.syrupy_apple.tooltip": "とにかく 蜜入りの 不思議なりんご。 カジッチュに使うと カミッチュに進化する。",
"item.cobblemon.syrupy_apple.tooltip": "とにかく 蜜入りの 不思議なりんご。カジッチュに使うと カミッチュに進化する。",
"cobblemon.fishing.no_bite": "釣れないなぁ……",
"cobblemon.ui.interact.request_already_expired": "そのリクエストはすでに期限切れです!",
"cobblemon.ui.pokedex.info.form.alola": "アローラのすがた",
@@ -6627,37 +6627,37 @@
"item.cobblemon.saccharine_chest_boat": "チェスト付きのあまったるいボート",
"item.cobblemon.metal_alloy": "ふくごうきんぞく",
"item.cobblemon.scroll_of_darkness": "あくのかけじく",
"item.cobblemon.scroll_of_darkness.tooltip": "あくの極意が 書かれている 不思議なかけじく。 ダクマに使うと いちげきのかたの ウーラオスに進化する。",
"item.cobblemon.scroll_of_darkness.tooltip": "あくの極意が 書かれている 不思議なかけじく。ダクマに使うと いちげきのかたの ウーラオスに進化する。",
"item.cobblemon.scroll_of_waters": "みずのかけじく",
"item.cobblemon.fried_rice": "いそべやき",
"item.cobblemon.muscle_mochi": "きんりょくのもち",
"item.cobblemon.muscle_mochi.tooltip": "きのみが ねりこまれた もち。 ポケモン 1匹の 攻撃の 基礎ポイントを 4 あげる。",
"item.cobblemon.muscle_mochi.tooltip": "きのみが ねりこまれた もち。ポケモン 1匹の 攻撃の 基礎ポイントを 4 あげる。",
"item.cobblemon.resist_mochi": "ていこうのもち",
"item.cobblemon.resist_mochi.tooltip": "きのみが ねりこまれた もち。 ポケモン 1匹の 防御の 基礎ポイントを 4 あげる。",
"item.cobblemon.genius_mochi.tooltip": "きのみが ねりこまれた もち。 ポケモン 1匹の 特攻の 基礎ポイントを 4 あげる。",
"item.cobblemon.resist_mochi.tooltip": "きのみが ねりこまれた もち。ポケモン 1匹の 防御の 基礎ポイントを 4 あげる。",
"item.cobblemon.genius_mochi.tooltip": "きのみが ねりこまれた もち。ポケモン 1匹の 特攻の 基礎ポイントを 4 あげる。",
"item.cobblemon.clever_mochi": "せいしんのもち",
"item.cobblemon.swift_mochi": "しゅんぱつのもち",
"cobblemon.species.genesect-electric.desc": "電気エネルギーが 充填された カセットを 装着した 姿。 エネルギー弾を 発射する。",
"cobblemon.species.genesect-fire.desc": "炎エネルギーが 充填された カセットを 装着した 姿。 鋭い 鋼のツメを 持つ。",
"item.cobblemon.fresh_start_mochi.tooltip": "きのみが ねりこまれた もち。 ポケモンの 基礎ポイントが すべて なくなってしまう。",
"item.cobblemon.fresh_start_mochi.tooltip": "きのみが ねりこまれた もち。ポケモンの 基礎ポイントが すべて なくなってしまう。",
"block.cobblemon.potted_saccharine_sapling": "あまったるい苗木入り植木鉢",
"item.cobblemon.saccharine_boat": "あまったるいボート",
"item.cobblemon.scroll_of_waters.tooltip": "みずの極意が 書かれている 不思議なかけじく。 ダクマに使うと れんげきのかたの ウーラオスに進化する。",
"item.cobblemon.scroll_of_waters.tooltip": "みずの極意が 書かれている 不思議なかけじく。ダクマに使うと れんげきのかたの ウーラオスに進化する。",
"item.cobblemon.potato_mochi": "イモモチ",
"item.cobblemon.fresh_start_mochi": "まっさらもち",
"item.cobblemon.swift_mochi.tooltip": "きのみが ねりこまれた もち。 ポケモン 1匹の 素早さの 基礎ポイントを 4 あげる。",
"item.cobblemon.swift_mochi.tooltip": "きのみが ねりこまれた もち。ポケモン 1匹の 素早さの 基礎ポイントを 4 あげる。",
"cobblemon.species.meloetta-pirouette.desc": "長く 忘れられていた 歌を 取り戻した メロエッタは 魅惑の ステップで 誰しも 虜にする。",
"cobblemon.species.greninja-bond.desc": "忍者のように 神出鬼没。 素早い 動きで 翻弄しつつ 水の 手裏剣で 切り裂く。",
"item.cobblemon.saccharine_sapling": "あまったるい苗木",
"item.cobblemon.candied_apple": "りんごアメ",
"item.cobblemon.moomoo_milk": "モーモーミルク",
"cobblemon.species.genesect-ice.desc": "氷エネルギーが 充填された カセットを 装着した 姿。 慈悲の 心は 持っていない。",
"item.cobblemon.metal_alloy.tooltip": "いくつもの層が 重なっている 不思議な金属。 ジュラルドンに使うと ブリジュラスに進化する。",
"item.cobblemon.metal_alloy.tooltip": "いくつもの層が 重なっている 不思議な金属。ジュラルドンに使うと ブリジュラスに進化する。",
"item.cobblemon.genius_mochi": "ちりょくのもち",
"cobblemon.species.genesect-water.desc": "水エネルギーが 充填された カセットを 装着した 姿。 飛行形態で 空を飛ぶ。",
"item.cobblemon.health_mochi": "たいりょくのもち",
"item.cobblemon.health_mochi.tooltip": "きのみが ねりこまれた もち。 ポケモン 1匹の HPの 基礎ポイントを 4 あげる。",
"item.cobblemon.clever_mochi.tooltip": "きのみが ねりこまれた もち。 ポケモン 1匹の 特防の 基礎ポイントを 4 あげる。",
"item.cobblemon.health_mochi.tooltip": "きのみが ねりこまれた もち。ポケモン 1匹の HPの 基礎ポイントを 4 あげる。",
"item.cobblemon.clever_mochi.tooltip": "きのみが ねりこまれた もち。ポケモン 1匹の 特防の 基礎ポイントを 4 あげる。",
"cobblemon.species.greninja-ash.desc": "トレーナーとの キズナが 極限まで 高まったときに 見られる ゲッコウガの すがた。",
"cobblemon.ui.pokedex.info.form.greninja-ash": "サトシゲッコウガ",
"cobblemon.species.castform-sunny.desc": "暑い 日差しを 浴びていると この姿に 変わる。 火照った 身体を 触ると パサパサするぞ。",
@@ -67,7 +67,7 @@
"item.cobblemon.apricorn_chest_boat": "Bote de Azinheira com Baú",
"item.cobblemon.link_cable": "Cabo de Ligação",
"item.cobblemon.dragon_scale": "Escama de Dragão",
"item.cobblemon.kings_rock": "Pedra do Rei",
"item.cobblemon.kings_rock": "Pedra Rei",
"item.cobblemon.metal_coat": "Revestimento Metálico",
"item.cobblemon.upgrade": "Melhorador",
"item.cobblemon.dubious_disc": "Disco Dúbio",
@@ -134,15 +134,15 @@
"item.cobblemon.ability_capsule": "Cápsula de Habilidade",
"item.cobblemon.ability_patch": "Adesivo de Habilidade",
"item.cobblemon.red_mint_leaf": "Folha de Hortelã Vermelha",
"item.cobblemon.red_mint_leaf.tooltip": "Capaz de influenciar o atributo de Ataque de um Pokémon",
"item.cobblemon.red_mint_leaf.tooltip": "Capaz de influenciar o atributo de ataque de um Pokémon",
"item.cobblemon.blue_mint_leaf": "Folha de Hortelã Azul",
"item.cobblemon.blue_mint_leaf.tooltip": "Capaz de influenciar o atributo de Defesa de um Pokémon",
"item.cobblemon.cyan_mint_leaf": "Folha de Hortelã Ciano",
"item.cobblemon.cyan_mint_leaf.tooltip": "Capaz de influenciar o atributo de Ataque Especial de um Pokémon",
"item.cobblemon.pink_mint_leaf": "Folha de Hortelã Rosa",
"item.cobblemon.pink_mint_leaf.tooltip": "Capaz de influenciar o atributo de Defesa Especial de um Pokémon",
"item.cobblemon.pink_mint_leaf.tooltip": "Capaz de influenciar o atributo de defesa especial de um Pokémon",
"item.cobblemon.green_mint_leaf": "Folha de Hortelã Verde",
"item.cobblemon.green_mint_leaf.tooltip": "Capaz de influenciar o atributo de Velocidade de um Pokémon",
"item.cobblemon.green_mint_leaf.tooltip": "Capaz de influenciar o atributo de velocidade de um Pokémon",
"item.cobblemon.white_mint_leaf": "Folha de Hortelã Branca",
"item.cobblemon.white_mint_leaf.tooltip": "Capaz de neutralizar a natureza de um Pokémon",
"item.cobblemon.lonely_mint": "Hortelã Solitária",
@@ -708,7 +708,7 @@
"item.cobblemon.magost_berry": "Baga Magost",
"item.cobblemon.magost_berry.tooltip": "Não pode ser comido durante batalhas",
"item.cobblemon.maranga_berry": "Baga Maranga",
"item.cobblemon.maranga_berry.tooltip": "Aumenta a Defesa Especial do portador em 1 estágio após ser atingido por um movimento especial",
"item.cobblemon.maranga_berry.tooltip": "Aumenta a Defesa Especial do portador em 1 estágio após ser atingido por um ataque especial",
"item.cobblemon.micle_berry": "Baga Micle",
"item.cobblemon.micle_berry.tooltip": "O próximo movimento do portador tem 1.2x de precisão quando estiver com 1/4 ou menos do PV máximo",
"item.cobblemon.nanab_berry": "Baga Nanab",
@@ -3338,7 +3338,7 @@
"cobblemon.species.mudsdale.desc": "Ele pode percorrer estradas montanhosas sem descanso por três dias e três noites, enquanto arrasta uma carga de 10 toneladas.",
"cobblemon.species.goomy.desc": "Ele é coberto por uma membrana viscosa que faz com que qualquer soco ou chute deslize sem causar danos.",
"cobblemon.species.goodra.desc": "Ele ataca com chifres retráteis. Desfere um soco equivalente à força de cem boxeadores profissionais.",
"cobblemon.species.pumpkaboo.desc": "Recentemente foi descoberto que as diferentes variedades de Pumpkaboo não vairam apenas no tamanho mas também no tamanho das almas que eles coletam.",
"cobblemon.species.pumpkaboo.desc": "Diz-se que ela transporta espíritos errantes para o lugar onde pertencem, para que possam seguir em frente.",
"cobblemon.species.volcanion.desc": "Ele expele seu vapor interno dos braços em suas costas. Ele tem poder suficiente para explodir uma montanha.",
"cobblemon.species.bergmite.desc": "Usando ar de -150 graus Fahrenheit, eles congela os oponentes sólidos. Eles vivem em rebanhos acima da linha de neve nas montanhas.",
"cobblemon.species.zygarde.name": "Zygarde",
@@ -3438,7 +3438,7 @@
"cobblemon.species.trevenant.desc": "Usando suas raízes como sistema nervoso, ele controla as árvores da floresta. É gentil com os Pokémon que residem em seu corpo.",
"cobblemon.species.pumpkaboo.name": "Pumpkaboo",
"cobblemon.species.gourgeist.name": "Gourgeist",
"cobblemon.species.gourgeist.desc": "Cantando com suas vozes sinistras, vagam pelas estradas das cidades em noites de lua cheia. Qualquer um que escuta sua canção é amaldiçoado.",
"cobblemon.species.gourgeist.desc": "Ele envolve sua presa em seus braços peludos. Canta alegremente enquanto observa o sofrimento de sua presa.",
"cobblemon.species.bergmite.name": "Bergmite",
"cobblemon.species.avalugg.name": "Avalugg",
"cobblemon.species.avalugg.desc": "Usando ar de -150 graus Fahrenheit, eles congela os oponentes sólidos. Eles vivem em rebanhos acima da linha de neve nas montanhas.",
@@ -3513,7 +3513,7 @@
"cobblemon.species.pyukumuku.name": "Pyukumuku",
"cobblemon.species.pyukumuku.desc": "Seu corpo inteiro é coberto por sua própria gosma. Se você acidentalmente pisar em uma, você escorregará, e ela ficará brava e te baterá!",
"cobblemon.species.typenull.name": "Tipo: Nulo",
"cobblemon.species.silvally.desc": "Um forte vínculo de confiança entre este Pokémon e seu Treinador despertou a força escondida dentro de Silvally. Pode mudar seu tipo à vontade.",
"cobblemon.species.silvally.desc": "Através do vínculo que formou com seu Treinador, sua vontade foi fortalecida e ele foi capaz de destruir sua máscara de controle.",
"cobblemon.species.togedemaru.name": "Togedemaru",
"cobblemon.species.nihilego.name": "Nihilego",
"cobblemon.species.silvally.name": "Silvally",
@@ -3792,7 +3792,7 @@
"cobblemon.species.zacian.desc": "Conhecido como um herói lendário, este Pokémon absorve partículas de metal, transformando-as em uma arma que usa para batalhar.",
"cobblemon.species.zamazenta.name": "Zamazenta",
"cobblemon.species.eternatus.name": "Eternatus",
"cobblemon.species.eternatus.desc": "Estava dentro de um meteorito que caiu há 20.000 anos. Parece haver uma conexão entre esse Pokémon e o fenômeno Dynamax.",
"cobblemon.species.eternatus.desc": "O núcleo em seu peito absorve a energia que emana das terras da região de Galar. Essa energia é o que permite que Eternatus permaneça ativo.",
"cobblemon.species.kubfu.name": "Kubfu",
"cobblemon.species.urshifu.name": "Urshifu",
"cobblemon.species.urshifu.desc": "Esta forma de Urshifu acredita firmemente no nocaute com um golpe. Sua estratégia é saltar para perto dos inimigos e desferir um golpe devastador com o punho firme.",
@@ -3927,7 +3927,7 @@
"cobblemon.species.veluza.desc": "Quando Veluza descarta carne desnecessária, sua mente se torna afiada e seu poder psíquico aumenta. A carne sobrante tem um sabor suave, mas delicioso.",
"cobblemon.species.milcery.desc": "Este Pokémon nasceu de partículas de cheiro doce no ar. Seu corpo é feito de creme.",
"cobblemon.species.falinks.desc": "Cinco deles são soldados, e um é o chefe. As ordens do chefe são absolutas.",
"cobblemon.species.zamazenta.desc": "Esse Pokémon dormiu por eras em sua forma de estátua. Dormiu por tanto tempo que as pessoas equeceram que uma vez existiu.",
"cobblemon.species.zamazenta.desc": "No passado, ele trabalhou em conjunto com um rei do povo para salvar a região de Galar. Ele absorve metal e o usa em batalha.",
"cobblemon.species.spectrier.desc": "Ele sonda os arredores com todos os seus sentidos, exceto um — não usa a visão. Dizem que os chutes do Spectrier separam a alma do corpo.",
"cobblemon.species.sneasler.desc": "Devido ao veneno virulento e à descomunal destreza física de Sneasler, nenhuma outra espécie poderia vencê-lo nas terras altas congeladas. Preferindo a solidão, esta espécie não forma matilhas.",
"cobblemon.species.pawmi.desc": "Ele tem bolsas elétricas subdesenvolvidas em suas bochechas. Essas bolsas podem produzir eletricidade somente se Pawmi as esfregar furiosamente com as almofadas de suas patas dianteiras.",
@@ -5224,27 +5224,27 @@
"cobblemon.move.gmaxvoltcrash": "Trovoada G-Max",
"entity.cobblemon.poke_bobber": "Pokéboia",
"entity.cobblemon.boat": "Barco",
"cobblemon.ui.pokedex.info.form.venusaur-mega": "Mega Venusaur",
"cobblemon.ui.pokedex.info.form.venusaur-mega": "Mega",
"cobblemon.species.venusaur-mega.desc": "Para sustentar sua flor, que cresceu devido à Mega Evolução, suas costas e pernas ficaram mais fortes.",
"cobblemon.ui.pokedex.info.form.charizard-megay": "Mega Charizard Y",
"cobblemon.ui.pokedex.info.form.charizard-megay": "Mega Y",
"cobblemon.species.raticate-alola.desc": "Ele comanda um ninho de Rattata. Ninhos diferentes não se dão bem, o que gera brigas acirradas por áreas de alimentação.",
"cobblemon.ui.pokedex.info.form.sandshrew-alola": "Aloliano",
"cobblemon.battle.enditem.shucaberry": "A Baga Shuca enfraqueceu o dano de %1$s",
"cobblemon.battle.enditem.payapaberry": "A Baga Payapa enfraqueceu o dano de %1$s",
"cobblemon.ui.pokedex.info.form.muk-alola": "Aloliano",
"cobblemon.ui.pokedex.info.form.gengar-mega": "Mega Gengar",
"cobblemon.ui.pokedex.info.form.gengar-mega": "Mega",
"cobblemon.ui.pokedex.info.form.gengar-gmax": "Gigantamax",
"cobblemon.species.kingler-gmax.desc": "O fluxo de energia Gigantamax fez com que a pinça esquerda deste Pokémon crescesse até um tamanho enorme. Essa garra pode pulverizar qualquer coisa.",
"cobblemon.ui.pokedex.info.form.voltorb-hisui": "Hisuiano",
"cobblemon.species.voltorb-hisui.desc": "Um Pokémon enigmático que se parece com uma Pokébola. Quando excitado, ele descarrega a corrente elétrica armazenada em sua barriga e solta uma gargalhada estrondosa.",
"cobblemon.ui.pokedex.info.form.weezing-galar": "Galariano",
"cobblemon.ui.pokedex.info.form.kangaskhan-mega": "Mega Kangaskhan",
"cobblemon.ui.pokedex.info.form.kangaskhan-mega": "Mega",
"cobblemon.ui.pokedex.info.form.mrmime-galar": "Galariano",
"cobblemon.species.mrmime-galar.desc": "Seu talento é sapateado. Ele também pode manipular temperaturas para criar um piso de gelo, que este Pokémon pode levantar para usar como barreira.",
"cobblemon.ui.pokedex.info.form.lapras-gmax": "Gigantamax",
"cobblemon.ui.pokedex.info.form.aerodactyl-mega": "Mega Aerodactyl",
"cobblemon.ui.pokedex.info.form.aerodactyl-mega": "Mega",
"cobblemon.ui.pokedex.info.form.snorlax-gmax": "Gigantamax",
"cobblemon.ui.pokedex.info.form.mewtwo-megax": "Mega Mewtwo X",
"cobblemon.ui.pokedex.info.form.mewtwo-megax": "Mega X",
"cobblemon.ui.pokedex.info.form.typhlosion-hisui": "Hisuiano",
"cobblemon.move.boomburst": "Rajada Explosiva",
"cobblemon.move.bouncybubble": "Eevaporabolhas",
@@ -5271,7 +5271,7 @@
"cobblemon.ui.pokedex.info.form.gastrodon-east": "Mar do Leste",
"cobblemon.species.lopunny-mega.desc": "A Mega Evolução desperta seus instintos combativos. Ela se livrou de qualquer pelo que atrapalhasse seus ataques.",
"cobblemon.move.electroball": "Bola Elétrica",
"cobblemon.species.gallade-mega.desc": "Recebe seu poder do vínculo que tem com seu Treinador. A Mega Evolução o concedeu placas para fatiar inimigos e uma capa para proteger seu corpo.",
"cobblemon.species.gallade-mega.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.palkia-origin": "Forma de Origem",
"cobblemon.ui.pokedex.info.form.darmanitan-zen": "Modo Zen",
"cobblemon.species.darmanitan-galar.desc": "Em dias de nevasca, ele se resume a onde as pessoas vivem. Ele guarda comida na bola de neve em sua cabeça e a leva para casa para mais tarde.",
@@ -5289,7 +5289,7 @@
"cobblemon.ui.pokedex.info.form.xerneas-active": "Modo Ativo",
"cobblemon.ui.pokedex.info.form.zygarde": "Forma 50%",
"cobblemon.move.ember": "Brasa",
"cobblemon.ui.pokedex.info.form.diancie-mega": "Mega Diancie",
"cobblemon.ui.pokedex.info.form.diancie-mega": "Mega",
"cobblemon.ui.pokedex.info.form.hoopa-unbound": "Hoopa Libertado",
"cobblemon.ui.pokedex.info.form.oricorio-pompom": "Estilo Pom-Pom",
"cobblemon.ui.pokedex.info.form.lycanroc": "Forma do Meio-Dia",
@@ -5351,7 +5351,7 @@
"item.cobblemon.mild_mint.tooltip": "Altera os atributos de um Pokémon para uma natureza Mansa",
"cobblemon.snapshots.warning.description": "Você está usando uma snapshot %s do Cobblemon. Os recursos nesta versão ainda estão em desenvolvimento e podem não ser seguros para usar em seus mundos. Deseja continuar ciente desses riscos?",
"item.cobblemon.npc_editor": "Cartão de Treinador NPC",
"item.cobblemon.link_cable.tooltip": "Permite a evolução de um Pokémon que requer troca",
"item.cobblemon.link_cable.tooltip": "Evolui Pokémon que exigem troca",
"item.cobblemon.dragon_scale.tooltip": "Evolui Seadra para Kingdra quando segurado durante a troca",
"item.cobblemon.kings_rock.tooltip_1": "Quando o portador inflige dano com sucesso, o alvo pode hesitar",
"item.cobblemon.kings_rock.tooltip_2": "Evolui Poliwhirl para Politoed e Slowpoke para Slowking quando segurado durante a troca",
@@ -5505,7 +5505,7 @@
"item.cobblemon.weakness_policy.tooltip_1": "Aumenta o Ataque e o Ataque Especial do portador quando atingido por um movimento supereficaz",
"item.cobblemon.weakness_policy.tooltip_2": "Consumido após o uso",
"item.cobblemon.wide_lens.tooltip": "Aumenta a Precisão do portador",
"item.cobblemon.wise_glasses.tooltip": "Aumenta o poder de movimentos Especiais",
"item.cobblemon.wise_glasses.tooltip": "Aumenta o poder dos movimentos especiais",
"item.cobblemon.mental_herb.tooltip_1": "Cura o portador da paixão e de outros efeitos mentais",
"item.cobblemon.mental_herb.tooltip_2": "Consumido após o uso",
"item.cobblemon.mirror_herb.tooltip_1": "Permite que o portador espelhe os aumentos de atributo do oponente para aumentar seus próprios atributos",
@@ -5513,7 +5513,7 @@
"item.cobblemon.misty_seed.tooltip": "Aumenta a Defesa Especial do portador em terrenos Enevoados",
"item.cobblemon.power_herb.tooltip_1": "Permite que o portador use imediatamente um movimento que normalmente requer a troca de turno para ser carregado",
"item.cobblemon.power_herb.tooltip_2": "Consumido após o uso",
"item.cobblemon.bright_powder.tooltip": "Reduz a Precisão dos movimentos dos Pokémon inimigos em 10%",
"item.cobblemon.bright_powder.tooltip": "Reduz a Precisão dos movimentos dos pokémon inimigos em 10%",
"item.cobblemon.metal_powder.tooltip": "Aumenta a Defesa e a Defesa Especial de um Ditto não transformado em 50%",
"item.cobblemon.quick_powder.tooltip": "Duplica a Velocidade de um Ditto não transformado",
"item.cobblemon.destiny_knot.tooltip": "Se o portador ficar apaixonado, o Pokémon pelo qual o portador está atraído também ficará apaixonado",
@@ -5821,12 +5821,12 @@
"cobblemon.mark.ribbon_contest_super_master_cleverness.title": "%1$s o Gênio Histórico",
"cobblemon.mark.ribbon_contest_super_star_twinkling.title": "%1$s a Estrela Cintilante",
"cobblemon.mark.ribbon_contest_super_star_twinkling.desc": "Uma Fita concedida a um Pokémon que tenha personificado perfeitamente o brilho radiante em Shows de Super Concurso.",
"cobblemon.mark.ribbon_day_alert.title": "%1$s o Vigilante",
"cobblemon.mark.ribbon_day_alert.title": "%1$s o Outrora Vigilante",
"cobblemon.mark.ribbon_day_alert.desc": "Uma Fita para relembrar um evento revigorante que gerou energia vital.",
"cobblemon.mark.ribbon_day_careless": "Fita Descuidada",
"cobblemon.mark.ribbon_day_careless.title": "%1$s o Imperfeito",
"cobblemon.mark.ribbon_day_careless.title": "%1$s o Outrora Imperfeito",
"cobblemon.mark.ribbon_effort": "Fita do Esforço",
"cobblemon.mark.ribbon_effort.title": "%1$s o Preparado",
"cobblemon.mark.ribbon_effort.title": "%1$s o Outrora Preparado",
"cobblemon.mark.ribbon_event.title": "%1$s o Festivo",
"cobblemon.mark.ribbon_event.desc": "Uma Fita concedida por participar de um evento especial.",
"cobblemon.mark.ribbon_event_birthday": "Fita de Aniversário",
@@ -5861,7 +5861,7 @@
"cobblemon.mark.ribbon_syndicate_gorgeous.desc": "Uma fita extraordinariamente linda e extravagante.",
"cobblemon.mark.ribbon_training.title": "%1$s o Posto à Prova",
"cobblemon.mark.mark_alpha": "Marca Alfa",
"cobblemon.mark.mark_alpha.title": "%1$s o Alfa",
"cobblemon.mark.mark_alpha.title": "%1$s o Antigo Alfa",
"cobblemon.mark.mark_itemfinder.title": "%1$s o Caçador de Tesouros",
"cobblemon.mark.mark_itemfinder.desc": "Uma marca para um Pokémon que gosta de pegar coisas.",
"cobblemon.mark.mark_mightiest": "Marca Mais Poderosa",
@@ -5879,8 +5879,8 @@
"cobblemon.mark.mark_revival.title": "%1$s o Ressuscitado",
"cobblemon.mark.mark_revival.desc": "Uma marca para um Pokémon ressuscitado.",
"cobblemon.mark.mark_titan": "Marca do Titã",
"cobblemon.mark.mark_titan.title": "%1$s o Titã",
"cobblemon.mark.mark_titan.desc": "Uma marca para um Pokémon que é um Titã.",
"cobblemon.mark.mark_titan.title": "%1$s o Antigo Titã",
"cobblemon.mark.mark_titan.desc": "Uma marca para um Pokémon que era um Titã.",
"cobblemon.mark.mark_uncommon": "Marca Incomum",
"cobblemon.mark.mark_uncommon.title": "%1$s o Sociável",
"cobblemon.mark.mark_uncommon.desc": "Uma marca para um Pokémon sociável.",
@@ -7499,7 +7499,7 @@
"cobblemon.species.charizard-megax.desc": "O poder avassalador que preenche todo o seu corpo faz com que ele fique preto e crie intensas chamas azuis.",
"cobblemon.species.charizard-megay.desc": "Seu vínculo com seu Treinador é a fonte de seu poder. Ele ostenta velocidade e manobrabilidade maiores que as de um caça a jato.",
"cobblemon.ui.pokedex.info.form.charizard-gmax": "Gigantamax",
"cobblemon.ui.pokedex.info.form.blastoise-mega": "Mega Blastoise",
"cobblemon.ui.pokedex.info.form.blastoise-mega": "Mega",
"cobblemon.species.blastoise-mega.desc": "O canhão em suas costas é tão poderoso quanto um canhão de tanque. Suas pernas e costas robustas permitem que ele resista ao recuo do disparo do canhão.",
"cobblemon.ui.pokedex.info.form.blastoise-gmax": "Gigantamax",
"cobblemon.species.blastoise-gmax.desc": "Ele não é muito bom em tiros de precisão. Ao atacar, ele simplesmente dispara seus 31 canhões repetidamente.",
@@ -7572,12 +7572,12 @@
"cobblemon.species.golem-alola.desc": "Ele atira grandes pedras carregadas de eletricidade. Choques elétricos tremendos são lançados por toda a área de impacto.",
"cobblemon.species.ponyta-galar.desc": "Seu pequeno chifre esconde um poder de cura. Com algumas esfregadas no chifre deste Pokémon, qualquer ferimento leve que você tenha será curado.",
"cobblemon.species.slowpoke-galar.desc": "Embora este Pokémon normalmente fique distraído, sua expressão se intensifica abruptamente de vez em quando. A causa disso parece estar na dieta do Slowpoke.",
"cobblemon.ui.pokedex.info.form.slowbro-mega": "Mega Slowbro",
"cobblemon.ui.pokedex.info.form.slowbro-mega": "Mega",
"cobblemon.species.slowbro-mega.desc": "Depois de ter sido engolido por inteiro por Shellder, Slowbro agora tem uma defesa de ferro. É bem confortável lá dentro também.",
"cobblemon.species.slowbro-galar.desc": "A mordida de Shellder desencadeou uma reação química com as especiarias dentro do corpo de Slowbro, fazendo com que Slowbro se tornasse um Pokémon do tipo Venenoso.",
"cobblemon.species.farfetchd-galar.desc": "Carregar um alho-poró grande e pesado fortaleceu seu corpo. Em batalha, aposta tudo em um único golpe destrutivo.",
"cobblemon.species.farfetchd-galar.desc": "Os talos do alho-poró são mais grossos e longos na região de Galar. O Farfetch'd que se adaptou a esses talos assumiu uma forma única.",
"cobblemon.ui.pokedex.info.form.grimer-alola": "Aloliano",
"cobblemon.species.grimer-alola.desc": "Os cristais no corpo de Grimer são protuberâncias feitas de toxinas. Se uma se desprender, começa a liberar veneno.",
"cobblemon.species.grimer-alola.desc": "Trazido para Alola para resolver o problema do lixo, Grimer parece gostar de todo e qualquer tipo de lixo.",
"cobblemon.species.muk-alola.desc": "O que parecem presas e garras são, na verdade, veneno cristalizado que pode afligir você com um simples toque, então não chegue muito perto.",
"cobblemon.species.gengar-mega.desc": "A Mega Evolução possibilitou que Gengar acessasse outras dimensões. Seu corpo inteiro está repleto de um poder estranho.",
"cobblemon.species.gengar-gmax.desc": "Dizem que sua boca gigantesca não leva ao seu corpo, cheio de energia amaldiçoada, mas diretamente à vida após a morte.",
@@ -7596,10 +7596,10 @@
"cobblemon.move.sludgewave": "Onda de Lama",
"cobblemon.move.reflecttype": "Clonatipo",
"cobblemon.species.pinsir-mega.desc": "Ele voa a velocidades estonteantes, procurando uma abertura para espetar seu oponente com suas pinças gigantes.",
"cobblemon.ui.pokedex.info.form.tauros-paldeacombat": "Paldeano (Raça de Combate)",
"cobblemon.ui.pokedex.info.form.tauros-paldeacombat": "Raça de Combate (Paldean)",
"cobblemon.species.tauros-paldeacombat.desc": "Este Pokémon tem um corpo musculoso e é excelente em combate corpo a corpo. Ele usa seus chifres curtos para atingir os pontos fracos do oponente.",
"cobblemon.species.tauros-paldeablaze.desc": "Quando aquecidos pela energia do fogo, seus chifres podem atingir temperaturas superiores a 1.800 graus Fahrenheit. Aqueles que forem atingidos por eles sofrerão ferimentos e queimaduras.",
"cobblemon.ui.pokedex.info.form.tauros-paldeaaqua": "Paldeano (Raça da Água)",
"cobblemon.ui.pokedex.info.form.tauros-paldeaaqua": "Raça da Água (Paldean)",
"cobblemon.species.tauros-paldeaaqua.desc": "Este Pokémon lança água por buracos nas pontas dos seus chifres — os jatos de alta pressão perfuram os inimigos de Tauros.",
"cobblemon.species.lapras-gmax.desc": "Mais de 5.000 pessoas podem andar em sua estrutura ao mesmo tempo. E é um passeio muito confortável, sem o menor tremor ou balanço.",
"cobblemon.ui.pokedex.info.form.eevee-gmax": "Gigantamax",
@@ -7643,15 +7643,15 @@
"cobblemon.species.unown-y.desc": "Este Pokémon tem o formato de uma escrita antiga. É um mistério o que surgiu primeiro, as escritas antigas ou os vários Unown. Pesquisas sobre este tópico estão em andamento, mas nada se sabe.",
"cobblemon.species.unown-!.desc": "Este punho tem forma como uma escrita antiga. É um mistério qual veio primeiro, os escritos antigos ou os vários Unown. A investigação sobre este tema está em curso, mas nada é conhecido.",
"cobblemon.ui.pokedex.info.form.unown-?": "Forma",
"cobblemon.ui.pokedex.info.form.steelix-mega": "Mega Steelix",
"cobblemon.species.steelix-mega.desc": "Para se proteger dos ataques de seus oponentes, usa magnetismo para controlar peças que se desprenderam de sua carapaça exterior.",
"cobblemon.ui.pokedex.info.form.steelix-mega": "Mega",
"cobblemon.species.steelix-mega.desc": "Ecologia em estudo.",
"cobblemon.species.corsola-galar.desc": "Cuidado com os passos ao vagar por áreas que antes eram cobertas por oceanos. O que parece uma pedra pode ser este Pokémon, e ele vai te amaldiçoar se você chutá-lo.",
"cobblemon.move.sandsearstorm.desc": "O usuário ataca envolvendo os Pokémon oponentes em ventos fortes e areia escaldante. Isso também pode deixá-los com uma queimadura.",
"cobblemon.move.lunarblessing": "Bênção Lunar",
"cobblemon.species.houndoom-mega.desc": "Todo o corpo de Houndoom gera calor quando ele Mega Evolui. Seu temível sopro de fogo transforma seus oponentes em cinzas.",
"cobblemon.move.icespinner": "Girador de Gelo",
"cobblemon.ui.pokedex.info.form.sceptile-mega": "Mega Sceptile",
"cobblemon.species.sceptile-mega.desc": "As sementes em suas costas contém energia da Mega Evolução. O Pokémon detona essas sementes para disparar a ponta de sua cauda.",
"cobblemon.ui.pokedex.info.form.sceptile-mega": "Mega",
"cobblemon.species.sceptile-mega.desc": "Ecologia em estudo.",
"cobblemon.species.linoone-galar.desc": "Ele usa sua longa língua para provocar os oponentes. Quando o oponente fica enfurecido, este Pokémon se lança contra ele, derrubando-o com força.",
"cobblemon.move.ragingbull": "Investida Furiosa",
"cobblemon.move.tidyup": "Arrumar",
@@ -7664,7 +7664,7 @@
"cobblemon.move.gmaxdepletion": "Esgotamento G-Max",
"cobblemon.move.gmaxdrumsolo": "Solo de Tambores G-Max",
"cobblemon.move.gmaxfinale": "Grande Final G-Max",
"cobblemon.species.camerupt-mega.desc": "Quando a fúria deste Pokémon atinge o ponto de ebulição, o enorme vulcão na corcunda em suas costas entra em erupção de forma violenta, lançando lava para o alto.",
"cobblemon.species.camerupt-mega.desc": "Ecologia em estudo.",
"cobblemon.move.gmaxgoldrush": "Corrida do Ouro G-Max",
"cobblemon.move.gmaxgravitas": "Seriedade G-Max",
"cobblemon.move.gmaxmeltdown": "Colapso do G-Max",
@@ -7681,7 +7681,7 @@
"cobblemon.species.absol-mega.desc": "Ele converte a energia da Mega Evolução em uma aura intimidadora. Pessoas medrosas morrem de choque ao vê-lo.",
"cobblemon.species.glalie-mega.desc": "O poder da Mega Evolução era tão forte que esmagou o maxilar de Glalie. Sua incapacidade de comer direito o deixa irritado.",
"cobblemon.species.salamence-mega.desc": "Ele coloca as patas dianteiras dentro da carapaça para se tornar aerodinâmico durante o voo. O salamence voa em alta velocidade sobre todos os tipos de acidentes topográficos.",
"cobblemon.ui.pokedex.info.form.metagross-mega": "Mega Metagross",
"cobblemon.ui.pokedex.info.form.metagross-mega": "Mega",
"cobblemon.species.rayquaza-mega.desc": "Ele voa eternamente pela camada de ozônio, consumindo meteoroides para se sustentar. Os muitos meteoroides em seu corpo fornecem a energia necessária para sua Mega Evolução.",
"cobblemon.ui.pokedex.info.form.meowth-galar": "Galariano",
"cobblemon.species.wormadam-sandy.desc": "Sua pele de terra é razoavelmente dura — pelo menos não tem problema em repelir as bicadas de um Starly.",
@@ -7690,8 +7690,8 @@
"cobblemon.ui.pokedex.info.form.shellos": "Mar do Oeste",
"cobblemon.species.shellos-east.desc": "Cientistas interessados em suas grandes capacidades regenerativas estão atualmente analisando os materiais dos quais suas células são feitas.",
"cobblemon.species.gastrodon-east.desc": "Parente de Shellder e Cloyster, esse habitante do oceano às vezes vem à terra em busca de alimento.",
"cobblemon.ui.pokedex.info.form.abomasnow-mega": "Mega Abomasnow",
"cobblemon.species.abomasnow-mega.desc": "Os botões em suas costas geraram sincelos impressionantes que podem iniciar nevascas imensas de -30 graus Celsius.",
"cobblemon.ui.pokedex.info.form.abomasnow-mega": "Mega",
"cobblemon.species.abomasnow-mega.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.machamp-gmax": "Gigantamax",
"cobblemon.ui.pokedex.info.form.rotom-heat": "Rotom Calor",
"cobblemon.species.rotom-heat.desc": "Este Rotom possui um forno de micro-ondas de convecção que utiliza um motor especial. Ele também tem um talento especial para manipular chamas.",
@@ -7727,13 +7727,13 @@
"cobblemon.ui.pokedex.info.form.arceus-fairy": "Arceus",
"cobblemon.species.arceus-fairy.desc": "Diz a mitologia que este Pokémon nasceu antes mesmo do universo existir.",
"cobblemon.species.samurott-hisui.desc": "De coração duro e hábil com a lâmina, esta forma rara de Samurott é um produto da evolução dos Pokémon na região de Hisui. Seus golpes turbulentos atingem os inimigos como ondas incessantes.",
"cobblemon.species.audino-mega.desc": "Qualquer um que toque nas antenas secundárias que brotaram da base de sua garganta cairão em um sono profundo.",
"cobblemon.species.audino-mega.desc": "Ecologia em estudo.",
"cobblemon.species.basculin-white.desc": "Eles vivem em mares gelados, formando cardumes e compartilhando comida entre si. Quando chega a hora, retornam ao rio onde nasceram.",
"cobblemon.species.darumaka-galar.desc": "Ele viveu em áreas nevadas por tanto tempo que sua bolsa de fogo esfriou e atrofiou. Agora, ele tem um órgão que gera frio.",
"cobblemon.ui.pokedex.info.form.darmanitan": "Modo Padrão",
"cobblemon.species.darmanitan-zen.desc": "Por meio da meditação, ele acalma seu espírito furioso e aprimora seus poderes psíquicos.",
"cobblemon.ui.pokedex.info.form.darmanitan-galar": "Galariano (Modo Padrão)",
"cobblemon.ui.pokedex.info.form.darmanitan-galarzen": "Galariano (Modo Zen)",
"cobblemon.ui.pokedex.info.form.darmanitan-galar": "Modo Padrão (Galariano)",
"cobblemon.ui.pokedex.info.form.darmanitan-galarzen": "Modo Zen (Galariano)",
"cobblemon.species.darmanitan-galarzen.desc": "A raiva reacendeu sua bolsa de chamas atrofiada. Este Pokémon cospe fogo por toda parte enquanto ataca indiscriminadamente.",
"cobblemon.species.zoroark-hisui.desc": "Com sua pelagem branca e desgrenhada, parece a personificação da morte. Despreocupado com sua própria segurança, Zoroark ataca seus inimigos com uma energia amarga tão intensa que dilacera seu próprio corpo.",
"cobblemon.ui.pokedex.info.form.deerling": "Forma de Primavera",
@@ -7790,21 +7790,21 @@
"cobblemon.species.meowstic-f.desc": "As fêmeas são um pouco mais egoístas e agressivas que os machos. Se não conseguirem o que querem, elas vão atormentar você com suas habilidades psíquicas.",
"cobblemon.ui.pokedex.info.form.aegislash": "Forma de Escudo",
"cobblemon.ui.pokedex.info.form.sliggoo-hisui": "Hisuiano",
"cobblemon.species.sliggoo-hisui.desc": "O ferro na água que Sliggoo bebe deu a consistência metálica de seu casco. O Pokémon não sai do seu casco em dias ensolarados.",
"cobblemon.species.sliggoo-hisui.desc": "Uma criatura propensa à melancolia. Suspeito que sua carapaça metálica se desenvolveu como resultado da reação do muco em sua pele com o ferro presente na água de Hisui.",
"cobblemon.species.goodra-hisui.desc": "Capaz de controlar livremente a dureza de sua carapaça metálica. Ele detesta a solidão e é extremamente apegado — ele ficará furioso e enfurecido se aqueles que lhe são mais queridos o abandonarem.",
"cobblemon.ui.pokedex.info.form.pumpkaboo": "Variedade Mediana",
"cobblemon.ui.pokedex.info.form.pumpkaboo-small": "Variedade Pequena",
"cobblemon.species.pumpkaboo-small.desc": "Fazendo juz ao tamanho de seu corpo, essa variedade de Pumpkaboo leva os pequenos espíritos de crianças para o pós-vida.",
"cobblemon.species.pumpkaboo-large.desc": "Fazendo juz ao tamanho de seu corpo, essa variedade de Pumpkaboo leva os grandes espíritos de adultos para o pós-vida.",
"cobblemon.ui.pokedex.info.form.pumpkaboo-super": "Variedade Enorme",
"cobblemon.species.pumpkaboo-super.desc": "Fazendo jus ao tamanho de seu corpo, essa variedade de Pumpkaboo leva espíritos enormes para o pós-vida.",
"cobblemon.ui.pokedex.info.form.gourgeist": "Variedade Mediana",
"cobblemon.ui.pokedex.info.form.gourgeist-small": "Variedade Pequena",
"cobblemon.ui.pokedex.info.form.pumpkaboo": "Tamanho Médio",
"cobblemon.ui.pokedex.info.form.pumpkaboo-small": "Tamanho Pequeno",
"cobblemon.species.pumpkaboo-small.desc": "Ao levar espíritos para a vida após a morte, os pequenos Pumpkaboo preferem os espíritos de crianças aos de adultos.",
"cobblemon.species.pumpkaboo-large.desc": "Ao levar espíritos para a vida após a morte, os Pumpkaboo grandes preferem os espíritos de adultos aos de crianças.",
"cobblemon.ui.pokedex.info.form.pumpkaboo-super": "Tamanho Enorme",
"cobblemon.species.pumpkaboo-super.desc": "Pumpkaboos gigantescos são muito apegados aos espíritos de pessoas que possuem proporções igualmente superiores.",
"cobblemon.ui.pokedex.info.form.gourgeist": "Tamanho Médio",
"cobblemon.ui.pokedex.info.form.gourgeist-small": "Tamanho Pequeno",
"cobblemon.species.gourgeist-small.desc": "Pequenos Gourgeistas fingem ser crianças para enganar adultos. Qualquer um que caia nessa farsa é levado para o além.",
"cobblemon.ui.pokedex.info.form.gourgeist-large": "Variedade Grande",
"cobblemon.ui.pokedex.info.form.gourgeist-large": "Tamanho Grande",
"cobblemon.species.gourgeist-large.desc": "Grandes Gourgeist assumem o disfarce de adultos, pegando nas mãos de crianças para guiá-las para a vida após a morte.",
"cobblemon.ui.pokedex.info.form.gourgeist-super": "Variedade Enorme",
"cobblemon.species.gourgeist-super.desc": "Gourgeist enormes não são meticulosos. Eles arrastam qualquer um à força para a vida após a morte.",
"cobblemon.ui.pokedex.info.form.gourgeist-super": "Tamanho Enorme",
"cobblemon.species.gourgeist-super.desc": "Gourgeist gigantes não são exigentes. Eles arrastam qualquer um à força para a vida após a morte.",
"cobblemon.species.avalugg-hisui.desc": "A armadura de gelo que cobre sua mandíbula inferior supera o aço e pode quebrar pedras com facilidade. Este Pokémon avança por trilhas íngremes nas montanhas, cortando a neve profunda.",
"cobblemon.species.xerneas-active.desc": "Quando os chifres em sua cabeça brilham em sete cores, diz-se que ele compartilha a vida eterna.",
"cobblemon.ui.pokedex.info.form.zygarde-10": "Forma 10%",
@@ -7815,7 +7815,7 @@
"cobblemon.species.zygarde-50c.desc": "Alguns dizem que ele pode se transformar em uma forma ainda mais poderosa ao lutar contra aqueles que ameaçam o ecossistema.",
"cobblemon.ui.pokedex.info.form.zygarde-complete": "Forma Completa",
"cobblemon.species.zygarde-complete.desc": "Nascido quando todas as células de Zygarde foram reunidas, ele usa a força para neutralizar aqueles que prejudicam o ecossistema.",
"cobblemon.species.diancie-mega.desc": "Esse Pokémon também é conhecido como a Princesa Rosa Real. O diamante deslumbrante e cintilante em sua testa tem impressionantes 2.000 quilates.",
"cobblemon.species.diancie-mega.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.hoopa": "Hoopa Confinado",
"cobblemon.species.hoopa-unbound.desc": "Em sua verdadeira forma, ele possui uma quantidade enorme de poder. Lendas sobre sua avareza contam como ele certa vez roubou um castelo inteiro para obter o tesouro escondido nele.",
"cobblemon.species.decidueye-hisui.desc": "O ar armazenado dentro das ráquis das penas de Decidueye isola o Pokémon do frio extremo de Hisui. Esta é uma prova cabal de que a evolução pode ser influenciada pelo ambiente.",
@@ -7834,20 +7834,20 @@
"cobblemon.ui.pokedex.info.form.wishiwashi": "Forma Solo",
"cobblemon.species.wishiwashi-school.desc": "Chamados de \"demônios do mar\" por alguns, quando os Wishiwashi são feridos em batalha e seus números diminuem, eles se tornam uma escola regular.",
"cobblemon.ui.pokedex.info.form.silvally-rock": "Tipo: Pedra",
"cobblemon.species.silvally-rock.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Pedra para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-rock.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-bug": "Tipo: Inseto",
"cobblemon.species.silvally-grass.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Grama para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-electric.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Elétrico para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-grass.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.species.silvally-electric.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-psychic": "Tipo: Psíquico",
"cobblemon.species.silvally-psychic.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Psíquico para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-psychic.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-ice": "Tipo: Gelo",
"cobblemon.species.silvally-ice.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Gelo para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-ice.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-dragon": "Tipo: Dragão",
"cobblemon.species.silvally-dragon.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Dragão para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-dragon.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-dark": "Tipo: Escuro",
"cobblemon.species.silvally-dark.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Sombrio para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-dark.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-fairy": "Tipo: Fada",
"cobblemon.species.silvally-fairy.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Fada para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-fairy.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.minior": "Núcleo",
"cobblemon.species.minior-indigo.desc": "Esta é a sua forma quando a casca cai. A cor do seu núcleo depende dos materiais que compunham o alimento que consumia.",
"cobblemon.ui.pokedex.info.form.minior-violet": "Núcleo Violeta",
@@ -7884,7 +7884,7 @@
"cobblemon.ui.pokedex.info.form.rapidash-galar": "Galariano",
"cobblemon.species.hatterene-gmax.desc": "Este Pokémon consegue ler as emoções de criaturas a mais de 48 quilômetros de distância. No minuto em que sente hostilidade, parte para o ataque.",
"cobblemon.ui.pokedex.info.form.hatterene-gmax": "Gigantamax",
"cobblemon.species.grimmsnarl-gmax.desc": "Energia Gigantamax fez com que mais cabelo surgisse por todo seu corpo. Com a força adquirida, pode saltar por cima do prédio mais alto do mundo.",
"cobblemon.species.grimmsnarl-gmax.desc": "Ao transformar os pelos das pernas, este Pokémon desfere chutes poderosos que podem abrir buracos enormes no terreno de Galar.",
"cobblemon.species.alcremie-rubycream.desc": "No momento em que evoluiu, adquiriu um sabor doce e ácido. Isso se deve à forma como suas células se modificaram espontaneamente durante a evolução.",
"cobblemon.species.alcremie-matchacream.desc": "No momento em que evoluiu, adquiriu um sabor aromático. Isso se deve à forma como suas células se modificaram espontaneamente durante a evolução.",
"cobblemon.species.alcremie-mintcream.desc": "No momento em que evoluiu, adquiriu um sabor refrescante. Isso se deve à forma como suas células se transformaram espontaneamente durante a evolução.",
@@ -7906,7 +7906,7 @@
"cobblemon.species.zacian-crowned.desc": "Agora armado com uma arma que usava nos tempos antigos, este Pokémon precisa de apenas um único golpe para derrubar até mesmo Pokémon Gigantamax.",
"cobblemon.ui.pokedex.info.form.zamazenta-crowned": "Escudo Coroado",
"cobblemon.species.zamazenta-crowned.desc": "Sua capacidade de desviar de qualquer ataque o levou a ser conhecido como o Escudo do Mestre Lutador. Era temido e respeitado por todos.",
"cobblemon.species.eternatus-eternamax.desc": "Quantidades infinitas de energia são produzidas pelo núcleo aumentado deste Pokémon, distorcendo o espaço-tempo ao seu redor.",
"cobblemon.species.eternatus-eternamax.desc": "Como resultado da intromissão de Rose, Eternatus absorveu toda a energia da região de Galar. Agora está em um estado de sobrecarga de energia.",
"cobblemon.ui.pokedex.info.form.urshifu": "Estilo de Golpe Único",
"cobblemon.ui.pokedex.info.form.urshifu-rapidstrike": "Estilo de Ataque Rápido",
"cobblemon.species.urshifu-rapidstrike.desc": "Acredita-se que este Pokémon modelou seu estilo de luta no fluxo de um rio — às vezes rápido, às vezes calmo.",
@@ -7915,7 +7915,7 @@
"cobblemon.species.zarude-dada.desc": "Este Zarude deixou sua matilha para criar uma criança humana. O pano com que Zarude envolvia a criança tinha um aroma reconfortante que acalmava o choro da criança.",
"cobblemon.ui.pokedex.info.form.calyrex-ice": "Cavaleiro de Gelo",
"cobblemon.ui.pokedex.info.form.calyrex-shadow": "Cavaleiro das Sombras",
"cobblemon.species.calyrex-shadow.desc": "Reza a lenda de que, ao usar seus poderes para ver todos os eventos do passado e do futuro, esse Pokémon salvou as criaturas de uma floresta do impacto de um meteorito.",
"cobblemon.species.calyrex-shadow.desc": "Diz-se que Calyrex e um Pokémon que se uniu a ele correram por toda a região de Galar para trazer verde às terras devastadas.",
"cobblemon.species.calyrex-ice.desc": "De acordo com a tradição, este Pokémon não demonstrava misericórdia para com aqueles que cruzavam seu caminho, mas ainda assim curava os ferimentos de seus oponentes após a batalha.",
"cobblemon.species.ursaluna-bloodmoon.desc": "Ele cruzou o mar e chegou à costa em uma nova terra. A sobrevivência neste lugar o levou a assumir uma aparência única e a ganhar poderes especiais.",
"cobblemon.ui.pokedex.info.form.enamorus-therian": "Forma Therian",
@@ -8014,13 +8014,13 @@
"cobblemon.ui.pokedex.info.form.unown-t": "Forma",
"cobblemon.ui.pokedex.info.form.unown-u": "Forma",
"cobblemon.ui.pokedex.info.form.unown-v": "Forma",
"cobblemon.ui.pokedex.info.form.blaziken-mega": "Mega Blaziken",
"cobblemon.species.blaziken-mega.desc": "Sangue fervendo corre por todo seu corpo, duplicando a precisão de seus movimentos. Subjuga seus oponentes com um piscar de olhos.",
"cobblemon.ui.pokedex.info.form.medicham-mega": "Mega Medicham",
"cobblemon.ui.pokedex.info.form.absol-mega": "Mega Absol",
"cobblemon.ui.pokedex.info.form.blaziken-mega": "Mega",
"cobblemon.species.blaziken-mega.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.medicham-mega": "Mega",
"cobblemon.ui.pokedex.info.form.absol-mega": "Mega",
"cobblemon.ui.pokedex.info.form.rotom-wash": "Rotom Lavagem",
"cobblemon.ui.pokedex.info.form.darumaka-galar": "Galariano",
"cobblemon.ui.pokedex.info.form.genesect-water": "Disco Hídrico",
"cobblemon.ui.pokedex.info.form.genesect-water": "Genesect",
"cobblemon.ui.pokedex.info.form.flabebe-white": "Flor Branca",
"cobblemon.ui.pokedex.info.form.minior-red": "Núcleo Vermelho",
"cobblemon.ui.pokedex.info.form.alcremie-matchacream": "Creme de Matcha",
@@ -8246,9 +8246,9 @@
"painting.cobblemon.altar.title": "Altar",
"cobblemon.move.leer": "Encarar",
"cobblemon.move.mistball": "Bola de Névoa",
"cobblemon.ui.pokedex.info.form.charizard-megax": "Mega Charizard X",
"cobblemon.ui.pokedex.info.form.charizard-megax": "Mega X",
"cobblemon.ui.pokedex.info.form.butterfree-gmax": "Gigantamax",
"cobblemon.ui.pokedex.info.form.pidgeot-mega": "Mega Pidgeot",
"cobblemon.ui.pokedex.info.form.pidgeot-mega": "Mega",
"cobblemon.ui.pokedex.info.form.rattata-alola": "Aloliano",
"cobblemon.species.rattata-alola.desc": "Noite após noite, eles esgueiram nas casas das pessoas à procura de comida. Um surto maciço delas tornou-se uma questão de preocupação pública.",
"cobblemon.ui.pokedex.info.form.pikachu-original": "Boné original",
@@ -8278,35 +8278,35 @@
"cobblemon.ui.pokedex.info.form.unown-z": "Forma",
"cobblemon.species.unown-z.desc": "Este Pokémon tem o formato de uma escrita antiga. É um mistério o que surgiu primeiro, as escritas antigas ou os vários Unown. Pesquisas sobre este tópico estão em andamento, mas nada se sabe.",
"cobblemon.ui.pokedex.info.form.unown-!": "Forma",
"cobblemon.ui.pokedex.info.form.heracross-mega": "Mega Heracross",
"cobblemon.ui.pokedex.info.form.heracross-mega": "Mega",
"cobblemon.ui.pokedex.info.form.sneasel-hisui": "Hisuiano",
"cobblemon.species.sneasel-hisui.desc": "Suas fortes garras curvadas são ideais para escalar penhascos íngremes. Das pontas dessas garras escorre um veneno que se infiltra nos nervos de qualquer presa capturada por Sneasel.",
"cobblemon.ui.pokedex.info.form.corsola-galar": "Galariano",
"cobblemon.ui.pokedex.info.form.swampert-mega": "Mega Swampert",
"cobblemon.species.swampert-mega.desc": "Usando os mesmos princípios de uma bomba hidráulica, a água dentro de seu corpo fortalece ainda mais seus músculos já avantajados.",
"cobblemon.ui.pokedex.info.form.swampert-mega": "Mega",
"cobblemon.species.swampert-mega.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.zigzagoon-galar": "Galariano",
"cobblemon.ui.pokedex.info.form.linoone-galar": "Galariano",
"cobblemon.species.gardevoir-mega.desc": "Quando abre a placa avermelhada em seu peito e revela seu coração, seu poder psíquico mais forte é liberado.",
"cobblemon.species.gardevoir-mega.desc": "Ecologia em estudo.",
"cobblemon.species.sableye-mega.desc": "Ele bloqueia todo e qualquer ataque com sua pedra preciosa gigante. No entanto, a pedra é um fardo pesado e limita os movimentos do Mega Sableye.",
"cobblemon.species.mawile-mega.desc": "Seus dois pares de mandíbulas se debatem violentamente como se cada um tivesse vontade própria. Um único ranger pode transformar uma pedra em pó.",
"cobblemon.species.medicham-mega.desc": "Graças à Mega Evolução, seu poder mental é ilimitado. Conjura braços imbuidos com malícia para derrotar seus inimigos.",
"cobblemon.ui.pokedex.info.form.manectric-mega": "Mega Manectric",
"cobblemon.ui.pokedex.info.form.sharpedo-mega": "Mega Sharpedo",
"cobblemon.ui.pokedex.info.form.altaria-mega": "Mega Altaria",
"cobblemon.species.altaria-mega.desc": "Sua plumagem é tão suave que a faz parecer sensível ao mais simples toque. Mas na realidade seus fios são fortes o suficente para içar um caminhão.",
"cobblemon.ui.pokedex.info.form.latios-mega": "Mega Latios",
"cobblemon.species.latios-mega.desc": "Voa em velocidades superiores a Mach 4. Está entre a elite dos Pokémon em termos de capacidade de combate aéreo.",
"cobblemon.ui.pokedex.info.form.rayquaza-mega": "Mega Rayquaza",
"cobblemon.species.medicham-mega.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.manectric-mega": "Mega",
"cobblemon.ui.pokedex.info.form.sharpedo-mega": "Mega",
"cobblemon.ui.pokedex.info.form.altaria-mega": "Mega",
"cobblemon.species.altaria-mega.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.latios-mega": "Mega",
"cobblemon.species.latios-mega.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.rayquaza-mega": "Mega",
"cobblemon.ui.pokedex.info.form.wormadam": "Manto de Planta",
"cobblemon.species.cherrim-sunshine.desc": "Após absorver bastante luz solar, Cherrim assume esta forma. Ela é cheia de energia enquanto está assim, e sua vivacidade perdura até o pôr do sol.",
"cobblemon.ui.pokedex.info.form.garchomp-mega": "Mega Garchomp",
"cobblemon.ui.pokedex.info.form.garchomp-mega": "Mega",
"cobblemon.species.garchomp-mega.desc": "Sua disposição está mais cruel do que antes de sua Mega Evolução. Garchomp retalha seus oponentes com as foices em ambos os braços.",
"cobblemon.ui.pokedex.info.form.lucario-mega": "Mega Lucario",
"cobblemon.ui.pokedex.info.form.lucario-mega": "Mega",
"cobblemon.species.lucario-mega.desc": "Banhado em energia explosiva, seus instintos combativos despertaram. Para seus inimigos, ele não tem misericórdia alguma.",
"cobblemon.ui.pokedex.info.form.arceus-ghost": "Arceus",
"cobblemon.species.arceus-ghost.desc": "Diz a mitologia que este Pokémon nasceu antes mesmo do universo existir.",
"cobblemon.ui.pokedex.info.form.arceus-ice": "Arceus",
"cobblemon.ui.pokedex.info.form.audino-mega": "Mega Audino",
"cobblemon.ui.pokedex.info.form.audino-mega": "Mega",
"cobblemon.species.basculin-bluestriped.desc": "Esses Pokémon formam cardumes com outros da mesma cor. O maior inimigo de um cardume de Basculin azuis é um cardume de Basculin vermelhos.",
"cobblemon.ui.pokedex.info.form.basculin-white": "Forma de Lista Branca",
"cobblemon.ui.pokedex.info.form.yamask-galar": "Galariano",
@@ -8322,7 +8322,7 @@
"cobblemon.ui.pokedex.info.form.florges-yellow": "Flor Amarela",
"cobblemon.ui.pokedex.info.form.furfrou": "Forma Natural",
"cobblemon.ui.pokedex.info.form.aegislash-blade": "Forma da Lâmina",
"cobblemon.ui.pokedex.info.form.pumpkaboo-large": "Variedade Grande",
"cobblemon.ui.pokedex.info.form.pumpkaboo-large": "Tamanho Grande",
"cobblemon.ui.pokedex.info.form.silvally-electric": "Tipo: Elétrico",
"cobblemon.ui.pokedex.info.form.minior-blue": "Núcleo Azul",
"cobblemon.species.cramorant-gorging.desc": "Este Cramorant acidentalmente prendeu um Pikachu na garganta. Ele está se engasgando um pouco, mas não está nem um pouco incomodado.",
@@ -8370,9 +8370,9 @@
"cobblemon.move.ragingfury": "Ira Furiosa",
"cobblemon.move.takeheart": "Ânimo Revigorado",
"cobblemon.move.doodle": "Decalque",
"cobblemon.ui.pokedex.info.form.pinsir-mega": "Mega Pinsir",
"cobblemon.ui.pokedex.info.form.banette-mega": "Mega Banette",
"cobblemon.ui.pokedex.info.form.groudon-primal": "Groudon Primal",
"cobblemon.ui.pokedex.info.form.pinsir-mega": "Mega",
"cobblemon.ui.pokedex.info.form.banette-mega": "Mega",
"cobblemon.ui.pokedex.info.form.groudon-primal": "Reversão Primal",
"block.cobblemon.stripped_saccharine_wood": "Madeira de Sacarina Descascada",
"block.cobblemon.hearty_grain_bale": "Fardo de Grãos Saudáveis",
"block.cobblemon.tatami_block": "Tatame",
@@ -8471,32 +8471,32 @@
"cobblemon.mark.ribbon_contest_super_master_beauty.title": "%1$s a Beleza Vintage",
"cobblemon.mark.ribbon_contest_super_master_cleverness.desc": "Uma Fita concedida a um Pokémon que demonstrou perfeitamente a Inteligência em Concursos Pokémon.",
"cobblemon.mark.ribbon_contest_super_master_coolness": "Fita Mestre da Frieza",
"cobblemon.mark.ribbon_contest_super_master_coolness.title": "%1$s a Estrela",
"cobblemon.mark.ribbon_contest_super_master_coolness.title": "%1$s a Antiga Estrela",
"cobblemon.mark.ribbon_contest_super_master_coolness.desc": "Uma Fita concedida a um Pokémon que demonstrou perfeitamente a Frieza em Concursos Pokémon.",
"cobblemon.mark.ribbon_contest_super_master_cuteness": "Fita Mestre da Fofura",
"cobblemon.mark.ribbon_contest_super_master_cuteness.title": "%1$s o Ídolo",
"cobblemon.mark.ribbon_contest_super_master_cuteness.title": "%1$s o Antigo Ídolo",
"cobblemon.mark.ribbon_contest_super_master_cuteness.desc": "Uma Fita concedida a um Pokémon que demonstrou perfeitamente a Fofura em Concursos Pokémon.",
"cobblemon.mark.ribbon_contest_super_master_toughness": "Fita Mestre da Força",
"cobblemon.mark.ribbon_contest_super_master_toughness.title": "%1$s o Fortão",
"cobblemon.mark.ribbon_contest_super_master_toughness.title": "%1$s o Antigo Fortão",
"cobblemon.mark.ribbon_contest_super_master_toughness.desc": "Uma Fita concedida a um Pokémon que demonstrou perfeitamente a Força em Concursos Pokémon.",
"cobblemon.mark.ribbon_contest_super_star": "Fita Estrela do Concurso",
"cobblemon.mark.ribbon_contest_super_star.title": "%1$s a Estrela Brilhante",
"cobblemon.mark.ribbon_contest_super_star.desc": "Uma Fita concedida a um Pokémon que teve um desempenho excelente em todos os tipos de concurso.",
"cobblemon.mark.ribbon_contest_super_star_twinkling": "Fita Estrela Cintilante",
"cobblemon.mark.ribbon_day_downcast": "Fita Abatida",
"cobblemon.mark.ribbon_day_downcast.title": "%1$s o Abatido",
"cobblemon.mark.ribbon_day_downcast.title": "%1$s o Outrora Abatido",
"cobblemon.mark.ribbon_day_downcast.desc": "Uma Fita para relembrar sentimentos de tristeza que adicionaram tempero à vida.",
"cobblemon.mark.ribbon_day_relax": "Fita Relaxante",
"cobblemon.mark.ribbon_day_relax.title": "%1$s o Descansado",
"cobblemon.mark.ribbon_day_relax.title": "%1$s o Outrora Descansado",
"cobblemon.mark.ribbon_day_relax.desc": "Uma Fita para relembrar um evento revigorante que deu um toque especial à vida.",
"cobblemon.mark.ribbon_day_shock": "Fita Chocante",
"cobblemon.mark.ribbon_day_shock.title": "%1$s o Acovardado",
"cobblemon.mark.ribbon_day_shock.title": "%1$s o Outrora Acovardado",
"cobblemon.mark.ribbon_day_shock.desc": "Uma Fita para relembrar um evento arrepiante que tornou a vida mais emocionante.",
"cobblemon.mark.ribbon_day_smile": "Fita do Sorriso",
"cobblemon.mark.ribbon_day_smile.title": "%1$s o Alegre",
"cobblemon.mark.ribbon_day_smile.title": "%1$s o Outrora Alegre",
"cobblemon.mark.ribbon_day_smile.desc": "Uma Fita para lembrar que os sorrisos enriquecem a qualidade de vida.",
"cobblemon.mark.ribbon_day_snooze": "Fita da Soneca",
"cobblemon.mark.ribbon_day_snooze.title": "%1$s o Sonolento",
"cobblemon.mark.ribbon_day_snooze.title": "%1$s o Outrora Sonolento",
"cobblemon.mark.ribbon_day_snooze.desc": "Uma Fita para relembrar um sono profundo que tornou a vida relaxante.",
"cobblemon.mark.ribbon_event_birthday.desc": "Uma Fita que comemora um aniversário.",
"cobblemon.mark.ribbon_event_champion_battle": "Fita de Campeão de Batalha",
@@ -8552,7 +8552,7 @@
"cobblemon.mark.ribbon_once-in-a-lifetime.title": "%1$s o Um em um Milhão",
"cobblemon.mark.ribbon_once-in-a-lifetime.desc": "Uma Fita rara encontrada com pouquíssima frequência em Pokémon.",
"cobblemon.mark.ribbon_partner": "Fita de Parceiro",
"cobblemon.mark.ribbon_partner.desc": "Uma Fita especial concedida a um Pokémon que é parceiro de um grande Treinador.",
"cobblemon.mark.ribbon_partner.desc": "Uma Fita especial concedida a um Pokémon que já foi parceiro de outro grande Treinador.",
"cobblemon.mark.ribbon_record.title": "%1$s o Detentor do Recorde",
"cobblemon.mark.ribbon_record.desc": "Uma Fita concedida por estabelecer um recorde incrível.",
"cobblemon.mark.ribbon_syndicate_royal": "Fita Real",
@@ -8561,7 +8561,7 @@
"cobblemon.mark.ribbon_syndicate_gorgeous_royal.title": "%1$s a Realeza Maravilhosa",
"cobblemon.mark.ribbon_syndicate_gorgeous_royal.desc": "Uma Fita linda e majestosa que é o ápice do fabuloso.",
"cobblemon.mark.ribbon_training": "Fita de Treinamento",
"cobblemon.mark.mark_alpha.desc": "Uma marca para um Pokémon alfa.",
"cobblemon.mark.mark_alpha.desc": "Uma marca para um Pokémon que era um alfa.",
"cobblemon.mark.mark_curry": "Marca de Curry",
"cobblemon.mark.mark_curry.title": "%1$s o Especialista em Curry",
"cobblemon.mark.mark_curry.desc": "Uma marca para um Pokémon conhecedor de curry.",
@@ -8649,14 +8649,14 @@
"cobblemon.move.gmaxmalodor": "Pestilência G-Max",
"cobblemon.move.gmaxvinelash": "Chicotada G-Max",
"cobblemon.move.gmaxvolcalith": "Rocha Vulcânica G-Max",
"cobblemon.ui.pokedex.info.form.beedrill-mega": "Mega Beedrill",
"cobblemon.ui.pokedex.info.form.beedrill-mega": "Mega",
"cobblemon.species.pikachu-original.desc": "Este Pikachu está usando seu boné de Treinador. Como o boné não é do tamanho certo, o ajuste está um pouco folgado.",
"cobblemon.ui.pokedex.info.form.graveler-alola": "Aloliano",
"cobblemon.ui.pokedex.info.form.slowbro-galar": "Galariano",
"cobblemon.ui.pokedex.info.form.tauros-paldeablaze": "Paldeano (Raça da Chama)",
"cobblemon.ui.pokedex.info.form.mewtwo-megay": "Mega Mewtwo Y",
"cobblemon.ui.pokedex.info.form.tauros-paldeablaze": "Raça da Chama (Paldean)",
"cobblemon.ui.pokedex.info.form.mewtwo-megay": "Mega Y",
"cobblemon.species.mewtwo-megay.desc": "Apesar do tamanho reduzido, seu poder mental cresceu fenomenalmente. Com um simples pensamento, ele pode destruir um arranha-céu em pedacinhos.",
"cobblemon.ui.pokedex.info.form.ampharos-mega": "Mega Ampharos",
"cobblemon.ui.pokedex.info.form.ampharos-mega": "Mega",
"cobblemon.species.ampharos-mega.desc": "Grandes quantidades de energia estimularam intensamente as células de Ampharos, aparentemente despertando seu sangue de dragão adormecido.",
"cobblemon.ui.pokedex.info.form.wooper-paldea": "Paldeano",
"cobblemon.ui.pokedex.info.form.slowking-galar": "Galariano",
@@ -8684,44 +8684,44 @@
"cobblemon.species.unown-x.desc": "Este Pokémon tem o formato de uma escrita antiga. É um mistério o que surgiu primeiro, as escritas antigas ou os vários Unown. Pesquisas sobre este tópico estão em andamento, mas nada se sabe.",
"cobblemon.ui.pokedex.info.form.qwilfish-hisui": "Hisuiano",
"cobblemon.species.qwilfish-hisui.desc": "Ele vive próximo à costa, em partes frias do mundo. Seus espinhos venenosos são mais grossos e curtos do que os dos Qwilfish de outras regiões.",
"cobblemon.ui.pokedex.info.form.scizor-mega": "Mega Scizor",
"cobblemon.ui.pokedex.info.form.scizor-mega": "Mega",
"cobblemon.species.scizor-mega.desc": "Ele é melhor em bater em objetos do que em agarrá-los. Quando luta por muito tempo, o peso de suas pinças se torna insuportável.",
"cobblemon.species.heracross-mega.desc": "Um tremendo influxo de energia o desenvolve, mas quando a Mega Evolução termina, Heracross fica incomodado com uma dor terrível nos músculos.",
"cobblemon.ui.pokedex.info.form.houndoom-mega": "Mega Houndoom",
"cobblemon.ui.pokedex.info.form.tyranitar-mega": "Mega Tyranitar",
"cobblemon.ui.pokedex.info.form.houndoom-mega": "Mega",
"cobblemon.ui.pokedex.info.form.tyranitar-mega": "Mega",
"cobblemon.species.tyranitar-mega.desc": "Os efeitos da Mega Evolução o tornam mais feroz do que nunca. Não se sabe se ele consegue ouvir as ordens de seu Treinador.",
"cobblemon.species.zigzagoon-galar.desc": "Sua inquietação o faz correr constantemente. Se vir outro Pokémon, ele irá esbarrar nele de propósito para começar uma briga.",
"cobblemon.ui.pokedex.info.form.gardevoir-mega": "Mega Gardevoir",
"cobblemon.ui.pokedex.info.form.sableye-mega": "Mega Sableye",
"cobblemon.ui.pokedex.info.form.mawile-mega": "Mega Mawile",
"cobblemon.ui.pokedex.info.form.aggron-mega": "Mega Aggron",
"cobblemon.species.aggron-mega.desc": "Energia da Mega Evolução transformou o ferro dentro deste Pokémon em uma armadura de aço que cobre o corpo inteiro de Mega Aggron.",
"cobblemon.ui.pokedex.info.form.gardevoir-mega": "Mega",
"cobblemon.ui.pokedex.info.form.sableye-mega": "Mega",
"cobblemon.ui.pokedex.info.form.mawile-mega": "Mega",
"cobblemon.ui.pokedex.info.form.aggron-mega": "Mega",
"cobblemon.species.aggron-mega.desc": "Ecologia em estudo.",
"cobblemon.species.manectric-mega.desc": "Muita eletricidade se acumulou em seu corpo, irritando Manectric. Sua velocidade explosiva é igual à de um raio.",
"cobblemon.ui.pokedex.info.form.camerupt-mega": "Mega Camerupt",
"cobblemon.ui.pokedex.info.form.camerupt-mega": "Mega",
"cobblemon.ui.pokedex.info.form.castform": "Normal",
"cobblemon.ui.pokedex.info.form.glalie-mega": "Mega Glalie",
"cobblemon.ui.pokedex.info.form.salamence-mega": "Mega Salamence",
"cobblemon.ui.pokedex.info.form.glalie-mega": "Mega",
"cobblemon.ui.pokedex.info.form.salamence-mega": "Mega",
"cobblemon.species.metagross-mega.desc": "Quando sabe que não pode vencer, ele crava as garras das pernas no oponente e inicia a contagem regressiva para uma grande explosão.",
"cobblemon.ui.pokedex.info.form.latias-mega": "Mega Latias",
"cobblemon.species.latias-mega.desc": "Tanto sua habilidade de voo quanto seu poder de ataque foram elevados. Dispersa sua plumagem transparente para confundir seus inimigos.",
"cobblemon.ui.pokedex.info.form.latias-mega": "Mega",
"cobblemon.species.latias-mega.desc": "Ecologia em estudo.",
"cobblemon.species.groudon-primal.desc": "Por meio da Reversão Primordial e com todo o poder da natureza, ele retomará sua verdadeira forma. Pode causar a erupção de magma e expandir a massa terrestre do mundo.",
"cobblemon.ui.pokedex.info.form.kyogre-primal": "Kyogre Primal",
"cobblemon.ui.pokedex.info.form.kyogre-primal": "Reversão Primal",
"cobblemon.species.kyogre-primal.desc": "Por meio da Reversão Primordial e com todo o poder da natureza, ele retomará sua verdadeira forma. Pode invocar tempestades que fazem o nível do mar subir.",
"cobblemon.ui.pokedex.info.form.deoxys": "Forma Normal",
"cobblemon.ui.pokedex.info.form.deoxys-attack": "Forma de Ataque",
"cobblemon.species.deoxys-attack.desc": "Esse Deoxys assumiu sua forma agressiva. Pode confundir inimigos ao alterar sua aparência.",
"cobblemon.species.deoxys-attack.desc": "Você está certo",
"cobblemon.ui.pokedex.info.form.deoxys-defense": "Forma de Defesa",
"cobblemon.species.deoxys-defense.desc": "Quando muda de forma, uma aurora aparece. Absorve ataques ao alterar sua estrutura celular.",
"cobblemon.species.deoxys-defense.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.deoxys-speed": "Forma de Velocidade",
"cobblemon.species.deoxys-speed.desc": "Um Pokémon vírus extraterrestre que mutou depois de ser exposto à um raio laser. Seu corpo é configurado para agilidade e velocidade melhoradas.",
"cobblemon.species.deoxys-speed.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.burmy": "Manto de Planta",
"cobblemon.ui.pokedex.info.form.burmy-sandy": "Manto de Areia",
"cobblemon.species.burmy-sandy.desc": "Ele cria uma capa entrelaçando areia, lama e seda que cuspiu. Essa capa de terra é destruída pelo vento e pela chuva, então o Pokémon se esconde em cavernas e outros lugares semelhantes.",
"cobblemon.ui.pokedex.info.form.burmy-trash": "Manto de Lixo",
"cobblemon.species.burmy-trash.desc": "Quando confrontado pela falta de outros materiais, Burmy criará sua capa usando pó e lixo. A capa parece ser mais confortável do que se poderia imaginar.",
"cobblemon.ui.pokedex.info.form.wormadam-sandy": "Manto de Areia",
"cobblemon.ui.pokedex.info.form.lopunny-mega": "Mega Lopunny",
"cobblemon.ui.pokedex.info.form.gallade-mega": "Mega Gallade",
"cobblemon.ui.pokedex.info.form.lopunny-mega": "Mega",
"cobblemon.ui.pokedex.info.form.gallade-mega": "Mega",
"cobblemon.ui.pokedex.info.form.dialga-origin": "Formato de origem",
"cobblemon.species.dialga-origin.desc": "Uma luz radiante fez com que Dialga assumisse uma forma com uma semelhança impressionante com o Pokémon criador. Dialga agora possui uma força tão colossal que é preciso concluir que esta é sua verdadeira forma.",
"cobblemon.ui.pokedex.info.form.giratina": "Forma Alterada",
@@ -8763,14 +8763,14 @@
"cobblemon.ui.pokedex.info.form.kyurem-black": "Kyurem Negro",
"cobblemon.species.kyurem-black.desc": "Diz-se que este Pokémon luta para proteger o mundo ideal que existirá no futuro para pessoas e Pokémon.",
"cobblemon.ui.pokedex.info.form.meloetta-pirouette": "Forma de Pirueta",
"cobblemon.species.meloetta-pirouette.desc": "Agora que relembrou uma antiga canção esquecida, Meloetta cativa todos com seus movimentos de dança encantadores.",
"cobblemon.species.genesect-water.desc": "Genesect assume sua configuração de voo para planar pelos céus. Sua forma atual é equipada com um cassete carregado de energia aquática.",
"cobblemon.ui.pokedex.info.form.genesect-electric": "Disco Elétrico",
"cobblemon.species.genesect-electric.desc": "Genesect dispara rajadas de projéteis de energia. Sua forma atual é equipada com um cassete carregado de energia elétrica.",
"cobblemon.ui.pokedex.info.form.genesect-fire": "Disco Incendiante",
"cobblemon.species.genesect-fire.desc": "Genesect produz garras de metal afiadas. Sua forma atual é equipada com um cassete carregado de energia de fogo.",
"cobblemon.ui.pokedex.info.form.genesect-ice": "Disco Congelante",
"cobblemon.species.genesect-ice.desc": "Genesect não tem piedade. Sua forma atual é equipada com um cassete carregado de energia gélida.",
"cobblemon.species.meloetta-pirouette.desc": "Ecologia em estudo.",
"cobblemon.species.genesect-water.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.genesect-electric": "Genesect",
"cobblemon.species.genesect-electric.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.genesect-fire": "Genesect",
"cobblemon.species.genesect-fire.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.genesect-ice": "Genesect",
"cobblemon.species.genesect-ice.desc": "Ecologia em estudo.",
"cobblemon.species.greninja-bond.desc": "Ecologia em estudo.",
"cobblemon.species.greninja-ash.desc": "Ecologia em estudo.",
"cobblemon.ui.pokedex.info.form.vivillon-icysnow": "Padrão de Neve Gelada",
@@ -8818,22 +8818,22 @@
"cobblemon.ui.pokedex.info.form.decidueye-hisui": "Hisuiano",
"cobblemon.ui.pokedex.info.form.silvally": "Tipo: Normal",
"cobblemon.ui.pokedex.info.form.silvally-fighting": "Tipo: Lutador",
"cobblemon.species.silvally-fighting.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Lutador para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-fighting.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-flying": "Tipo: Voador",
"cobblemon.species.silvally-flying.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Voador para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-flying.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-poison": "Tipo: Veneno",
"cobblemon.species.silvally-poison.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Venenoso para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-poison.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-ground": "Tipo: Solo",
"cobblemon.species.silvally-ground.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Terrestre para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-bug.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Inseto para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-ground.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.species.silvally-bug.desc": "Sua capacidade de mudar de tipo desencadeada, ela brilha prata devido à energia que surgiu de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-ghost": "Tipo: Fantasma",
"cobblemon.species.silvally-ghost.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Fantasma para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-ghost.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-steel": "Tipo: Aço",
"cobblemon.species.silvally-steel.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Aço para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-steel.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-fire": "Tipo: Fogo",
"cobblemon.species.silvally-fire.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Fogo para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-fire.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.silvally-water": "Tipo: Água",
"cobblemon.species.silvally-water.desc": "Graças aos seus poderes despertados, pode mudar para o tipo Água para se assemelhar à memória que tem equipada.",
"cobblemon.species.silvally-water.desc": "Com sua capacidade de mudar de tipo liberada, ele brilha prateado devido à energia que brota de dentro.",
"cobblemon.ui.pokedex.info.form.minior-meteor": "Forma de Meteoro",
"cobblemon.species.minior-meteor.desc": "Este Pokémon nasce na camada de ozônio. Ele cai no chão quando a casca externa que envolve seu núcleo fica pesada.",
"cobblemon.ui.pokedex.info.form.minior-orange": "Núcleo Laranja",
@@ -8884,7 +8884,7 @@
"cobblemon.move.overdrive": "Sobrecarga",
"cobblemon.move.thundercage": "Prisão Elétrica",
"cobblemon.move.dragonenergy": "Energia Dracônica",
"cobblemon.ui.pokedex.info.form.gyarados-mega": "Mega Gyarados",
"cobblemon.ui.pokedex.info.form.gyarados-mega": "Mega",
"cobblemon.species.gyarados-mega.desc": "Ele sai da água a velocidades Mach. Até mesmo navios grandes pegos em seu caminho são divididos em dois!",
"tag.item.cobblemon.berries.colour.green": "Bagas Verdes",
"stat.cobblemon.battles_fled": "Fugas em Batalhas Pokémon",
@@ -9016,7 +9016,7 @@
"block.cobblemon.fighting_gem_block": "Bloco de Gema do Lutador",
"block.cobblemon.poison_gem_block": "Bloco de Gema Venenosa",
"block.cobblemon.ground_gem_block": "Bloco de Gema Terrestre",
"block.cobblemon.flying_gem_block": "Bloco de Gema Voadora",
"block.cobblemon.flying_gem_block": "Bloco de Gema do Voador",
"block.cobblemon.psychic_gem_block": "Bloco de Gema Psíquica",
"block.cobblemon.bug_gem_block": "Bloco de Gema do Inseto",
"block.cobblemon.rock_gem_block": "Bloco de Gema da Pedra",
@@ -9031,7 +9031,7 @@
"block.cobblemon.fighting_gem_cluster": "Agregado de Gema do Lutador",
"block.cobblemon.poison_gem_cluster": "Agregado de Gema Venenosa",
"block.cobblemon.ground_gem_cluster": "Agregado de Gema Terrestre",
"block.cobblemon.flying_gem_cluster": "Agregado de Gema Voadora",
"block.cobblemon.flying_gem_cluster": "Agregado de Gema do Voador",
"block.cobblemon.psychic_gem_cluster": "Agregado de Gema Psíquica",
"block.cobblemon.bug_gem_cluster": "Agregado de Gema do Inseto",
"block.cobblemon.rock_gem_cluster": "Agregado de Gema da Pedra",
@@ -9103,7 +9103,7 @@
"cobblemon.ui.edit.habitat.validation.species": "Espécie deve ser um nome de Pokémon válido.",
"cobblemon.ui.edit.habitat.validation.weight": "Peso deve ser maior que 0.",
"cobblemon.ui.edit.habitat.validation.modifiers": "Formato dos modificadores é inválido.",
"cobblemon.ui.edit.habitat.validation.phases_list": "Fases devem usar um formato válido de números inteiros (0-7), e.g. 1-3 ou 1, 3-5, 6.",
"cobblemon.ui.edit.habitat.validation.phases_list": "Fases deve usar fases da lua válidas (0-7), e.g. 1-3 ou 1, 3-5, 6.",
"cobblemon.ui.edit.habitat.validation.min_light": "Luz Mínima deve estar entre 0 e 15.",
"cobblemon.ui.edit.habitat.validation.max_light": "Luz Máxima deve estar entre 0 e 15.",
"cobblemon.ui.moves.learnset.tm.discovered": "Descoberto",
@@ -9182,7 +9182,7 @@
"cobblemon.habitat.warped_fungal_dwelling.name": "Morada Fúngica Distorcida",
"cobblemon.habitat.zen_garden.name": "Jardim Zen",
"cobblemon.subtitle.tm.use": "Máquina Técnica usada",
"cobblemon.subtitle.block.tm_machine.craft": "Máquina de TM finaliza gravação de TM",
"cobblemon.subtitle.block.tm_machine.craft": "Máquina de TM grava TM",
"cobblemon.subtitle.block.tm_machine.off": "Máquina de TM desativa",
"cobblemon.subtitle.block.tm_machine.on": "Máquina de TM ativa",
"cobblemon.subtitle.block.tm_machine.open": "Tampa da Máquina de TM abre",
@@ -9331,87 +9331,5 @@
"cobblemon.config.ui.world_spawning_blocklist": "Permissões de Geração em Mundos",
"cobblemon.config.ui.world_spawning_blocklist.tooltip": "Mundos nos quais desabilitar a geração de Pokémon.",
"advancements.cobblemon.obtain_tm.description": "Encontrar ou gravar um TM",
"advancements.cobblemon.obtain_tm": "Olha esses movimentos!",
"cobblemon.species.glimmora-mega.desc": "As pétalas de Glimmora — agora maiores e separadas de seu corpo — rodam ao seu redor para servir de proteção ao espalhar fragmentos venenosos.",
"cobblemon.ui.pokedex.info.form.raichu-megax": "Mega Raichu X",
"cobblemon.ui.pokedex.info.form.raichu-megay": "Mega Raichu Y",
"cobblemon.species.raichu-megay.desc": "Dispara rajadas de eletricidade da ponta de sua cauda e dos tufos de pelo pontudos que crescem em suas têmporas. Essa eletricidade tem o formato da letra Y.",
"cobblemon.ui.pokedex.info.form.chimecho-mega": "Mega Chimecho",
"cobblemon.species.chimecho-mega.desc": "Vibra seu corpo inteiro para atacar em todas as direções usando ondas sonoras. Qualquer um que ouça essas vibrações ficam confusos e esquecem quem são.",
"cobblemon.ui.pokedex.info.form.absol-megaz": "Mega Absol Z",
"cobblemon.species.absol-megaz.desc": "Usando pelos moldados no formato de garras afiadas, corta seus oponentes com um único golpe. Faz isso como um ato de bondade para que não sofram além do necessário.",
"cobblemon.ui.pokedex.info.form.staraptor-mega": "Mega Staraptor",
"cobblemon.species.staraptor-mega.desc": "Mega Staraptor está no auge da habilidade de voo. Pode facilmente planar pelos céus enquanto carrega um Steelix pesando mais de 400 kg.",
"cobblemon.ui.pokedex.info.form.garchomp-megaz": "Mega Garchomp Z",
"cobblemon.species.garchomp-megaz.desc": "Garchomp ganhou uma nova forma Mega Evoluída. Voa ao redor de oponentes a velocidades altíssimas e os despedaça com seus esporões sinistros.",
"cobblemon.ui.pokedex.info.form.lucario-megaz": "Mega Lucario Z",
"cobblemon.species.lucario-megaz.desc": "Ao se envolver completamente com sua aura, Mega Lucario Z pode aparar qualquer tipo de ataque, batalhando como se estivesse dançando graciosamente.",
"cobblemon.ui.pokedex.info.form.froslass-mega": "Mega Froslass",
"cobblemon.species.froslass-mega.desc": "Esse Pokémon pode usar vento gelado imbuído com energia fantasmagórica para congelar até mesmo coisas insubstanciais, como chamas ou ar.",
"cobblemon.ui.pokedex.info.form.heatran-mega": "Mega Heatran",
"cobblemon.species.heatran-mega.desc": "É dito que se der o seu máximo, pode aquecer seu corpo a temperaturas acima de 1 milhão de graus Celsius. Esse calor afasta os inimigos.",
"cobblemon.ui.pokedex.info.form.darkrai-mega": "Mega Darkrai",
"cobblemon.species.darkrai-mega.desc": "Seu poder sombrio bloqueia o sol, lançando seus arredores em uma profunda escuridão. Não há escapatória de seu olho maligno.",
"cobblemon.ui.pokedex.info.form.emboar-mega": "Mega Emboar",
"cobblemon.species.emboar-mega.desc": "Brandindo uma chama ardente no meu de uma lança curvada, corajosamente resgata aliados em perigo.",
"cobblemon.ui.pokedex.info.form.excadrill-mega": "Mega Excadrill",
"cobblemon.species.excadrill-mega.desc": "Se esse Pokémon juntar seus braços a sua cabeça em uma única forma e girar a velocidades elevadas, pode destruir qualquer coisa.",
"cobblemon.ui.pokedex.info.form.scolipede-mega": "Mega Scolipede",
"cobblemon.species.scolipede-mega.desc": "Sua peçonha mortal produz um certo brilho. A peçonha afeta a mente de Scolipede, agravando sua crueldade.",
"cobblemon.ui.pokedex.info.form.basculin-whitestriped": "Forma de Listras Brancas",
"cobblemon.species.basculin-whitestriped.desc": "Vivem em mares gelados, formando cardumes e compartilhando alimento entre si. Quando o momento certo chega, retornam ao rio onde nasceram.",
"cobblemon.ui.pokedex.info.form.scrafty-mega": "Mega Scrafty",
"cobblemon.species.scrafty-mega.desc": "A Mega Evolução fez com que a pele trocada de Scrafty se esbranquiçasse, se tornando resistente e maleável. Esse Pokémon está mais abusado do que nunca.",
"cobblemon.ui.pokedex.info.form.eelektross-mega": "Mega Eelektross",
"cobblemon.species.eelektross-mega.desc": "Agora gera 10 vezes mais eletricidade comparado a antes da Mega Evolução. Descarrega essa eletricidade de seus Eelektrik falsos feitos de muco.",
"cobblemon.ui.pokedex.info.form.chandelure-mega": "Mega Chandelure",
"cobblemon.species.chandelure-mega.desc": "Um de seus olhos é uma janela ligando nosso mundo ao pós-vida. Esse Pokémon absorve ódio e o transformador em poder.",
"cobblemon.ui.pokedex.info.form.golurk-mega": "Mega Golurj",
"cobblemon.species.golurk-mega.desc": "A energia dentro de Golurk foi estimulada pela Mega Evolução. Esse Pokémon pode explodir a qualquer momento.",
"cobblemon.ui.pokedex.info.form.chesnaught-mega": "Mega Chesnaught",
"cobblemon.species.chesnaught-mega.desc": "Tem uma armadura fortificada e um desejo de defender a todo custo. Ambos absurdamente fortes.",
"cobblemon.ui.pokedex.info.form.delphox-mega": "Mega Delphox",
"cobblemon.species.delphox-mega.desc": "Porta galhos flamejantes para deslumbrar seus oponentes antes de incinerá-los com uma enorme bola de fogo.",
"cobblemon.species.greninja-mega.desc": "Esse Pokémon gira um shuriken gigante a altas velocidades para fazê-lo flutuar e então se prende a ele de cabeça para baixo para surpreender oponentes desatentos.",
"cobblemon.ui.pokedex.info.form.pyroar-mega": "Mega Pyroar",
"cobblemon.species.pyroar-mega.desc": "Esse Pokémon cospe chamas a temperaturas superiores a 10.000 graus Celsius. Balança sua grandiosa e flamejante juba para proteger seus aliados.",
"cobblemon.ui.pokedex.info.form.floette-mega": "Mega Floette",
"cobblemon.species.floette-mega.desc": "A Flor Eterna absorveu toda a energia da Mega Evolução. A flor agora ataca inimigos por conta própria.",
"cobblemon.ui.pokedex.info.form.meowstic-mega": "Mega Meowstic",
"cobblemon.species.meowstic-mega.desc": "Mega Meowstic pode usar seu poder psíquico para comprimir ou expandir tudo. Sobrecarrega oponentes ao contorcer o tecido do espaço.",
"cobblemon.ui.pokedex.info.form.malamar-mega": "Mega Malamar",
"cobblemon.species.malamar-mega.desc": "Usa suas luzes coloridas para subjugar as personalidades e memórias de outros—e para controlá-los.",
"cobblemon.ui.pokedex.info.form.barbaracle-mega": "Mega Barbaracle",
"cobblemon.species.barbaracle-mega.desc": "Usa seus muitos braços para se divertir com seus oponentes. Isso ocupa muito a cabeça central.",
"cobblemon.ui.pokedex.info.form.dragalge-mega": "Mega Dragalge",
"cobblemon.species.dragalge-mega.desc": "Cospe um líquido capaz de confundir o poder regenerativo das células. O líquido é um veneno mortal para todos além de si mesmo.",
"cobblemon.ui.pokedex.info.form.hawlucha-mega": "Mega Hawlucha",
"cobblemon.species.hawlucha-mega.desc": "A Mega Evolução fortaleceu todos os seus músculos. Hawlucha posa para demonstrar sua força.",
"cobblemon.ui.pokedex.info.form.zygarde-mega": "Mega Zygarde",
"cobblemon.species.zygarde-mega.desc": "Em resposta às emoções das pessoas durante uma crise sem precedentes, Zygarde Mega Evolui e acalma a situação com seu poder inigualável.",
"cobblemon.ui.pokedex.info.form.crabominable-mega": "Mega Crabominable",
"cobblemon.species.crabominable-mega.desc": "Pode pulverizar concreto reforçado com um simples balanço de seus punho, cada um coberto por uma grossa camada de gelo.",
"cobblemon.ui.pokedex.info.form.golisopod-mega": "Mega Golisopod",
"cobblemon.species.golisopod-mega.desc": "Usa quatro de seus braços para atacar ferozmente seus inimigos. Quando os leva à beira da derrota, os finaliza com os braços que manteve escondido.",
"cobblemon.ui.pokedex.info.form.drampa-mega": "Mega Drampa",
"cobblemon.species.drampa-mega.desc": "As células de Drampa foram revigoradas, permitindo que recuperasse sua juventude. Manipula a atmosfera para convocar tempestades.",
"cobblemon.ui.pokedex.info.form.magearna-mega": "Mega Magearna",
"cobblemon.species.magearna-mega.desc": "Essa é Magearna quando um modo oculto é ativado. As emoções de Magearna começou a sentir agora se reprimem enquanto derruba inimigo após inimigo.",
"cobblemon.ui.pokedex.info.form.magearna-originalmega": "Mega Magearna Cor Original",
"cobblemon.species.magearna-originalmega.desc": "Um mecanismo para remover as limitações de Magearna permaneceu oculto dentro de Magearna por 500 anos. Esse mecanismo é ativado por uma Mega Pedra.",
"cobblemon.ui.pokedex.info.form.zeraora-mega": "Mega Zeraora",
"cobblemon.species.zeraora-mega.desc": "Armazena em seu corpo energia equivalente a dez relâmpagos. Quando para de impor limites a si mesmo, se torna um dos Pokémon elétricos mais fortes.",
"cobblemon.ui.pokedex.info.form.falinks-mega": "Mega Falinks",
"cobblemon.species.falinks-mega.desc": "Mega Falinks assumiu a formação de batalha suprema, que só pode ser atingida se os guerreiros e o latão tenham um vínculo inquebrável.",
"cobblemon.ui.pokedex.info.form.scovillain-mega": "Mega Scovillain",
"cobblemon.species.scovillain-mega.desc": "A Mega Evolução elevou a picância desse Pokémon. Balança sua \"gravata\" para golpear seus oponentes.",
"cobblemon.ui.pokedex.info.form.glimmora-mega": "Mega Glimmora",
"cobblemon.ui.pokedex.info.form.tatsugiri-mega": "Mega Tatsugiri Forma Curvada",
"cobblemon.species.tatsugiri-mega.desc": "O cérebro de Tatsugiri foi energizado pela Mega Evolução, tornando-o mais astuto. Pode criar e comandar cópias de si mesmo.",
"cobblemon.ui.pokedex.info.form.tatsugiri-droopymega": "Mega Tatsuguri Forma Molenga",
"cobblemon.species.tatsugiri-droopymega.desc": "Solidifica a energia da Mega Evolução, construindo uma pilha excessiva para lançar como projéteis. Esses projéteis explodem ao primeiro contato.",
"cobblemon.ui.pokedex.info.form.tatsugiri-stretchymega": "Mega Tatsugiri Forma Elástica",
"cobblemon.species.tatsugiri-stretchymega.desc": "Usando a energia da Mega Evolução, cria um prato onde repousar, permitindo com que se mova com mobilidade total até mesmo pelo ar.",
"cobblemon.ui.pokedex.info.form.baxcalibur-mega": "Mega Baxcalibur",
"cobblemon.species.baxcalibur-mega.desc": "A lâmina dorsal de Baxcalibur ficou ainda maior graças à Mega Evolução. Esse Pokémon dispara feixes do cabo localizado em seu peito."
"advancements.cobblemon.obtain_tm": "Olha esses movimentos!"
}
@@ -9222,8 +9222,8 @@
"block.cobblemon.normal_gem_block": "一般宝石块",
"block.cobblemon.fire_gem_block": "火之宝石块",
"block.cobblemon.water_gem_block": "水之宝石块",
"block.cobblemon.electric_gem_block": "电之宝石块",
"block.cobblemon.grass_gem_block": "草之宝石块",
"block.cobblemon.electric_gem_block": "草之宝石块",
"block.cobblemon.grass_gem_block": "电之宝石块",
"block.cobblemon.ice_gem_block": "冰之宝石块",
"block.cobblemon.fighting_gem_block": "格斗宝石块",
"block.cobblemon.poison_gem_block": "毒之宝石块",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

@@ -1,5 +1,5 @@
{
"pokemon": ["electrode hisuian=false", "furfrou", "alakazam", "gengar", "jigglypuff", "smeargle"],
"pokemon": ["electrode", "furfrou", "alakazam", "gengar", "jigglypuff", "smeargle"],
"cosmeticItems": [
{
"consumedItem": "minecraft:white_dye",
@@ -0,0 +1,41 @@
{
"name": "cobblemon.habitat.birch_wildlife_scar.name",
"type": "cobblemon:natural",
"spawns": [
{
"species": "cobblemon:geodude",
"bucket": "common",
"spawnablePositionType": "grounded",
"levelRange": "35-45",
"weight": 10
},
{
"species": "cobblemon:zubat",
"bucket": "common",
"spawnablePositionType": "grounded",
"levelRange": "35-45",
"weight": 9
},
{
"species": "cobblemon:machop",
"bucket": "common",
"spawnablePositionType": "grounded",
"levelRange": "36-46",
"weight": 8
},
{
"species": "cobblemon:graveler",
"bucket": "uncommon",
"spawnablePositionType": "grounded",
"levelRange": "40-50",
"weight": 6
},
{
"species": "cobblemon:golbat",
"bucket": "uncommon",
"spawnablePositionType": "grounded",
"levelRange": "40-50",
"weight": 6
}
]
}
@@ -0,0 +1,41 @@
{
"name": "cobblemon.habitat.oak_wildlife_scar.name",
"type": "cobblemon:natural",
"spawns": [
{
"species": "cobblemon:geodude",
"bucket": "common",
"spawnablePositionType": "grounded",
"levelRange": "35-45",
"weight": 10
},
{
"species": "cobblemon:zubat",
"bucket": "common",
"spawnablePositionType": "grounded",
"levelRange": "35-45",
"weight": 9
},
{
"species": "cobblemon:machop",
"bucket": "common",
"spawnablePositionType": "grounded",
"levelRange": "36-46",
"weight": 8
},
{
"species": "cobblemon:graveler",
"bucket": "uncommon",
"spawnablePositionType": "grounded",
"levelRange": "40-50",
"weight": 6
},
{
"species": "cobblemon:golbat",
"bucket": "uncommon",
"spawnablePositionType": "grounded",
"levelRange": "40-50",
"weight": 6
}
]
}
@@ -0,0 +1,41 @@
{
"name": "cobblemon.habitat.spruce_wildlife_scar.name",
"type": "cobblemon:natural",
"spawns": [
{
"species": "cobblemon:geodude",
"bucket": "common",
"spawnablePositionType": "grounded",
"levelRange": "35-45",
"weight": 10
},
{
"species": "cobblemon:zubat",
"bucket": "common",
"spawnablePositionType": "grounded",
"levelRange": "35-45",
"weight": 9
},
{
"species": "cobblemon:machop",
"bucket": "common",
"spawnablePositionType": "grounded",
"levelRange": "36-46",
"weight": 8
},
{
"species": "cobblemon:graveler",
"bucket": "uncommon",
"spawnablePositionType": "grounded",
"levelRange": "40-50",
"weight": 6
},
{
"species": "cobblemon:golbat",
"bucket": "uncommon",
"spawnablePositionType": "grounded",
"levelRange": "40-50",
"weight": 6
}
]
}
@@ -17,7 +17,7 @@
"weightMultiplier": {
"multiplier": 3.0,
"condition": {
"minLight": 8
"minLight": 1
}
},
"condition": {
@@ -44,7 +44,7 @@
"weightMultiplier": {
"multiplier": 3.0,
"condition": {
"minLight": 8
"minLight": 1
}
},
"condition": {
@@ -76,7 +76,7 @@
"#cobblemon:is_forest"
],
"timeRange": "night",
"maxLight": 7
"maxLight": 0
}
},
{
@@ -98,7 +98,7 @@
],
"timeRange": "night",
"isRaining": true,
"maxLight": 7
"maxLight": 0
}
},
{
@@ -119,7 +119,7 @@
"#cobblemon:is_forest"
],
"timeRange": "night",
"minLight": 8
"minLight": 1
}
},
{
@@ -141,7 +141,7 @@
],
"timeRange": "night",
"isRaining": true,
"minLight": 8
"minLight": 1
}
}
]
@@ -17,7 +17,7 @@
"weightMultiplier": {
"multiplier": 3.0,
"condition": {
"minLight": 8
"minLight": 1
}
},
"condition": {
@@ -50,7 +50,7 @@
],
"timeRange": "night",
"isRaining": false,
"maxLight": 7
"maxLight": 0
}
},
{
@@ -72,7 +72,7 @@
],
"timeRange": "night",
"isRaining": false,
"minLight": 8
"minLight": 1
}
}
]
@@ -27,7 +27,7 @@
"#aether:is_aether",
"#cobblemon:is_overworld"
],
"maxLight": 7
"maxLight": 0
},
"anticondition": {
"biomes": [
@@ -87,7 +87,7 @@
"biomes": [
"#cobblemon:is_spooky"
],
"maxLight": 7
"maxLight": 0
}
},
{
@@ -27,7 +27,7 @@
"#aether:is_aether",
"#cobblemon:is_overworld"
],
"maxLight": 7
"maxLight": 0
},
"anticondition": {
"biomes": [
@@ -87,7 +87,7 @@
"biomes": [
"#cobblemon:is_spooky"
],
"maxLight": 7
"maxLight": 0
}
},
{
@@ -27,7 +27,7 @@
"#aether:is_aether",
"#cobblemon:is_overworld"
],
"maxLight": 7
"maxLight": 0
},
"anticondition": {
"biomes": [
@@ -87,7 +87,7 @@
"biomes": [
"#cobblemon:is_spooky"
],
"maxLight": 7
"maxLight": 0
}
},
{
@@ -18,7 +18,7 @@
"weightMultiplier": {
"multiplier": 11.0,
"condition": {
"minLight": 8
"minLight": 1
}
},
"condition": {
@@ -47,7 +47,7 @@
"weightMultiplier": {
"multiplier": 3.0,
"condition": {
"minLight": 8
"minLight": 1
}
},
"condition": {
@@ -145,11 +145,6 @@
"biomes": [
"#cobblemon:is_glacial"
]
},
"anticondition": {
"biomes": [
"#cobblemon:is_frozen_ocean"
]
}
}
]
@@ -145,11 +145,6 @@
"biomes": [
"#cobblemon:is_glacial"
]
},
"anticondition": {
"biomes": [
"#cobblemon:is_frozen_ocean"
]
}
}
]
@@ -33,7 +33,7 @@
},
{
"id": "rockruff-dusk-2",
"pokemon": "rockruff wolf_form=dusk",
"pokemon": "rockruff dusk",
"presets": [
"natural",
"wild"
@@ -5,7 +5,7 @@
"spawns": [
{
"id": "lycanroc-midday-1",
"pokemon": "lycanroc wolf_form=midday",
"pokemon": "lycanroc midday",
"presets": [
"natural",
"wild"
@@ -33,7 +33,7 @@
},
{
"id": "lycanroc-midnight-2",
"pokemon": "lycanroc wolf_form=midnight",
"pokemon": "lycanroc midnight",
"presets": [
"natural",
"wild"
@@ -61,7 +61,7 @@
},
{
"id": "lycanroc-dusk-3",
"pokemon": "lycanroc wolf_form=dusk",
"pokemon": "lycanroc dusk",
"presets": [
"natural",
"wild"
@@ -10,7 +10,7 @@
"spawnablePositionType": "grounded",
"bucket": "common",
"level": "1-19",
"weight": 24.0,
"weight": 30.0,
"weightMultipliers": [
{
"multiplier": 1.5,
@@ -10,12 +10,12 @@
"spawnablePositionType": "grounded",
"bucket": "common",
"level": "14-48",
"weight": 12.0,
"weight": 60.0,
"weightMultipliers": [
{
"multiplier": 3.0,
"condition": {
"minLight": 8
"minLight": 1
}
},
{
@@ -22,7 +22,7 @@
],
"timeRange": "night",
"isRaining": false,
"minLight": 8
"minLight": 1
},
"herdablePokemon": [
{
@@ -55,7 +55,7 @@
],
"timeRange": "night",
"isRaining": false,
"minLight": 8
"minLight": 1
},
"herdablePokemon": [
{
@@ -33,7 +33,7 @@
},
"herdablePokemon": [
{
"pokemon": "farfetchd held_item=minecraft:stick alpha=true",
"pokemon": "farfetchd held_item=minecraft.stick alpha=true",
"weight": 30.0,
"levelRange": "1-100",
"maxTimes": 1,

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