Compare commits

..
514 changed files with 435 additions and 2551 deletions

No files matched your search

+3 -29
View File
@@ -1,42 +1,16 @@
# Changelog
## [1.8.5 (MONTH xth, 2026)](#1-8-5)
## [1.8.x (MONTH xth, 2026)](#1-8-x)
### Additions
- You can now drag to select multiple Pokémon inside the PC menu.
### Pokémon Added
#### Generation 4
#### Generation 5
#### Generation 6
#### Generation 7
#### Generation 8
#### Generation 9
### Model updates for the following Pokémon
### Animation updates for the following Pokémon
- Added the `healersSetSpawn` gamerule. When enabled, using a healing machine will set your spawnpoint.
- You can now view the biome, level, and date you caught a Pokémon.
### Changes
- Amethyst now grows from Typegem core blocks like typegems do
### Fixes
- Fixed Ponigiri food values for AppleSkin integration
- Fixed errors emitted by typos in Parched Peat bog structure files
### Developer
### Molang & Datapacks
- `q.is_standing_on_blocks` now properly checks for non-full blocks like slabs, Mud or Soul Sand
- Added Molang functions to play footstep sounds based on the corresponding surface. These are intended to be used by Pokémon animations.
- Pokémon can now have their Minecraft footstep sounds silenced in their poser. This doesn't affect emitting game events.
### Particles
### Localization
- Updated translations for:
- Updated translations for:
@@ -15,7 +15,6 @@ import com.cobblemon.mod.common.api.riding.RidingStyle;
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawner;
import com.cobblemon.mod.common.api.spawning.spawner.PlayerSpawnerFactory;
import com.cobblemon.mod.common.api.stats.CobblemonStats;
import com.cobblemon.mod.common.block.HealingMachineBlock;
import com.cobblemon.mod.common.duck.ServerLevelDuck;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.world.gamerules.CobblemonGameRules;
@@ -23,14 +22,10 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.core.BlockPos;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -38,9 +33,6 @@ import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
@Mixin(ServerPlayer.class)
public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
@@ -150,17 +142,4 @@ public abstract class ServerPlayerMixin implements PlayerSpawnerAccessor {
((ServerLevelDuck) this.serverLevel()).cobblemon$getLevelResourceLocation()
);
}
@Inject(
method = "findRespawnAndUseSpawnBlock(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;FZZ)Ljava/util/Optional;",
at = @At(value = "HEAD"),
cancellable = true
)
private static void cobblemon$useHealthStationAsRespawn(ServerLevel level, BlockPos pos, float angle, boolean forced, boolean keepInventory, CallbackInfoReturnable<Optional<ServerPlayer.RespawnPosAngle>> cir) {
BlockState state = level.getBlockState(pos);
Block block = state.getBlock();
if (block instanceof HealingMachineBlock && HealingMachineBlock.Companion.canSetSpawn(level)) {
cir.setReturnValue(HealingMachineBlock.Companion.findStandUpPosition(EntityType.PLAYER, level, pos).map((vec3) -> ServerPlayer.RespawnPosAngle.of(vec3, pos)));
}
}
}
@@ -344,6 +344,7 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(RideStaminaUpdatePacket.ID, RideStaminaUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(AlphaUpdatePacket.ID, AlphaUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(ScaleModifierUpdatePacket.ID, ScaleModifierUpdatePacket::decode, PokemonUpdatePacketHandler()))
list.add(PacketRegisterInfo(MetDataUpdatePacket.ID, MetDataUpdatePacket::decode, PokemonUpdatePacketHandler()))
// Evolution start
list.add(PacketRegisterInfo(AddEvolutionPacket.ID, AddEvolutionPacket::decode, PokemonUpdatePacketHandler()))
@@ -566,7 +567,6 @@ object CobblemonNetwork {
list.add(PacketRegisterInfo(SwapPartyPokemonPacket.ID, SwapPartyPokemonPacket::decode, SwapPartyPokemonHandler))
list.add(PacketRegisterInfo(MovePCPokemonPacket.ID, MovePCPokemonPacket::decode, MovePCPokemonHandler))
list.add(PacketRegisterInfo(MovePCPokemonBatchPacket.ID, MovePCPokemonBatchPacket::decode, MovePCPokemonBatchHandler))
list.add(PacketRegisterInfo(MovePartyPokemonPacket.ID, MovePartyPokemonPacket::decode, MovePartyPokemonHandler))
list.add(PacketRegisterInfo(SwapPCPartyPokemonPacket.ID, SwapPCPartyPokemonPacket::decode, SwapPCPartyPokemonHandler))
@@ -29,7 +29,6 @@ import com.cobblemon.mod.common.net.messages.client.storage.pc.InitializePCPacke
import com.cobblemon.mod.common.net.messages.client.storage.pc.MoveClientPCPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.SetPCPokemonPacket
import com.cobblemon.mod.common.net.messages.client.storage.pc.wallpaper.UnlockPCBoxWallpaperPacket
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePCPokemonBatchPacket
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.DataKeys
import com.cobblemon.mod.common.util.asTranslated
@@ -271,34 +270,6 @@ open class PCStore(
}
}
fun moveBatch(moves: List<Triple<UUID, PCPosition, PCPosition>>): Boolean {
if (moves.isEmpty() || moves.size > MovePCPokemonBatchPacket.MAX_MOVES) return false
if (moves.map { it.second }.toSet().size != moves.size ||
moves.map { it.third }.toSet().size != moves.size ||
moves.map { it.first }.toSet().size != moves.size
) return false
if (moves.any { (_, source, target) -> !isValidPosition(source) || !isValidPosition(target) }) return false
val sourcePositions = moves.mapTo(mutableSetOf()) { it.second }
val pokemonMoves = moves.map { (pokemonID, source, target) ->
val pokemon = get(source)?.takeIf { it.uuid == pokemonID } ?: return false
Triple(source, target, pokemon)
}
if (pokemonMoves.any { (_, target, _) -> get(target) != null && target !in sourcePositions }) return false
pokemonMoves.forEach { (source, _, _) -> setAtPosition(source, null) }
pokemonMoves.forEach { (_, target, pokemon) -> setAtPosition(target, pokemon) }
pokemonMoves.forEach { (_, _, pokemon) ->
sendPacketToObservers(RemoveClientPokemonPacket(this, pokemon.uuid))
}
pokemonMoves.forEach { (_, target, pokemon) ->
sendPacketToObservers(SetPCPokemonPacket(uuid, target) { pokemon })
}
pcChangeObservable.emit(Unit)
return true
}
override fun loadPositionFromNBT(nbt: CompoundTag): StoreCoordinates<PCPosition> {
return StoreCoordinates(this, PCPosition(nbt.getShort(DataKeys.STORE_BOX).toInt(), nbt.getByte(DataKeys.STORE_SLOT).toInt()))
}
@@ -24,7 +24,6 @@ import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerPlayer
import net.minecraft.util.RandomSource
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.EntityType
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.Item
@@ -32,9 +31,13 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.CollisionGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.*
import net.minecraft.world.level.block.BaseEntityBlock
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.HorizontalDirectionalBlock
import net.minecraft.world.level.block.Mirror
import net.minecraft.world.level.block.RenderShape
import net.minecraft.world.level.block.Rotation
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityType
@@ -45,11 +48,9 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty
import net.minecraft.world.level.block.state.properties.Property
import net.minecraft.world.level.pathfinder.PathComputationType
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.Vec3
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
import java.util.Optional
@Suppress("DEPRECATED", "OVERRIDE_DEPRECATION")
class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
@@ -78,14 +79,6 @@ class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
const val MAX_CHARGE_LEVEL = 5
val CHARGE_LEVEL: IntegerProperty = IntegerProperty.create("charge", 0, MAX_CHARGE_LEVEL + 1)
val NATURAL: BooleanProperty = BooleanProperty.create("natural")
fun canSetSpawn(level: Level): Boolean {
return level.gameRules.getBoolean(CobblemonGameRules.HEALER_SET_SPAWN)
}
fun findStandUpPosition(entityType: EntityType<*>, level: CollisionGetter, pos: BlockPos): Optional<Vec3> {
return RespawnAnchorBlock.findStandUpPosition(entityType, level, pos) // Exists if we ever want to make something more custom, but anchor block logic should suffice
}
}
init {
@@ -165,12 +158,7 @@ class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
}
val party = serverPlayerEntity.party()
val pc = serverPlayerEntity.pc()
val healPC = player.level().gameRules.getBoolean(CobblemonGameRules.HEALERS_HEAL_PC)
// Do spawnpoint stuff
if (canSetSpawn(world)) {
player.setRespawnPosition(world.dimension(), blockPos, player.yRot, false, true)
}
val healPC = player.level().gameRules.getBoolean(CobblemonGameRules.HEALERS_HEAL_PC);
if (party.none() && (!healPC || pc.none())) {
player.sendSystemMessage(lang("healingmachine.nopokemon").red(), true)
@@ -195,7 +183,6 @@ class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
player.sendSystemMessage(lang("healingmachine.notenoughcharge", "${((neededCharge/party.count())*100f).toInt()}%").red(), true)
}
party.forEach { it.tryRecallWithAnimation() }
return InteractionResult.CONSUME
}
@@ -160,8 +160,8 @@ class TypeGemClusterBlock(
&& state.getValue(STAGE) == 3) return false
val supportPos = pos.relative(state.getValue(FACING).opposite)
val supportState = level.getBlockState(supportPos)
return supportState.`is`(CobblemonBlockTags.TYPE_GEM_BLOCKS) || supportState.block == CobblemonBlocks.TYPE_GEM_CORE // Cannot grow if not on any gem blocks
val supportBlock = level.getBlockState(supportPos).block
return CobblemonBlocks.typeGemBlocks().containsValue(supportBlock) || (supportBlock == CobblemonBlocks.TYPE_GEM_CORE) // Cannot grow if not on any gem blocks
}
@@ -51,20 +51,10 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
ResourceLocation.parse("cobblemon:dragon_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_DRAGON,
ResourceLocation.parse("cobblemon:dark_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_DARK,
ResourceLocation.parse("cobblemon:steel_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_STEEL,
ResourceLocation.parse("cobblemon:fairy_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_FAIRY,
ResourceLocation.parse("minecraft:amethyst_block") to Blocks.SMALL_AMETHYST_BUD
ResourceLocation.parse("cobblemon:fairy_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_FAIRY
)
}
val AMETHYST_STAGES = listOf(
Blocks.SMALL_AMETHYST_BUD,
Blocks.MEDIUM_AMETHYST_BUD,
Blocks.LARGE_AMETHYST_BUD,
Blocks.AMETHYST_CLUSTER
)
private fun isAmethystStage(block: Block) = block in AMETHYST_STAGES
fun getConnectedGemBlocks(level: BlockGetter, pos: BlockPos): List<Pair<BlockState, BlockPos>> {
val connectedGems = mutableListOf<Pair<BlockState, BlockPos>>()
val visited = mutableSetOf<BlockPos>()
@@ -95,16 +85,12 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
Direction.entries.forEach {
if (random.nextFloat() < Cobblemon.config.typeGemGrowthChance) {
val faceState = level.getBlockState(pos.relative(it))
var newState = BLOCK_TO_CLUSTER[BuiltInRegistries.BLOCK.getKey(state.block)]?.defaultBlockState()
val randomGrowthType = decideClusterGrowthType(level, pos)
val newState = BLOCK_TO_CLUSTER[BuiltInRegistries.BLOCK.getKey(state.block)]?.defaultBlockState()
?.setValue(DirectionalBlock.FACING, it)
?.setValue(GROWTH_TYPE, randomGrowthType)
?: return
if (newState.hasProperty(GROWTH_TYPE)) {
newState = newState.setValue(GROWTH_TYPE, decideClusterGrowthType(level, pos))
} else if (getConnectedGemBlocks(level, pos).size > Cobblemon.config.typeGemMaxConnected) {
return@forEach
}
if (faceState.`is`(Blocks.AIR)) {
level.setBlock(pos.relative(it), newState, 3)
}
@@ -146,7 +132,7 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
if (!visited.add(clusterPos)) continue
val clusterState = level.getBlockState(clusterPos)
if (clusterState.block == expectedCluster && clusterState.hasProperty(GROWTH_TYPE)) {
if (clusterState.block == expectedCluster) {
clusters += clusterState to clusterPos
}
}
@@ -192,41 +178,13 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) {
Direction.entries.forEach { direction ->
val relativePos = pos.relative(direction)
val relativeState = level.getBlockState(relativePos)
val matchesFace = relativeState.hasProperty(DirectionalBlock.FACING)
&& relativeState.getValue(DirectionalBlock.FACING) == direction
if (!(forceGrow || (matchesFace && random.nextFloat() < Cobblemon.config.typeGemGrowthChance))) {
return@forEach
val clusterBlock = relativeState.block as? TypeGemClusterBlock ?: return@forEach
if ((relativeState.getValue(DirectionalBlock.FACING) == direction &&
random.nextFloat() < Cobblemon.config.typeGemGrowthChance) || forceGrow
) {
clusterBlock.advanceGrowth(relativeState, level, relativePos, random)
}
val block = relativeState.block
if (block is TypeGemClusterBlock) {
block.advanceGrowth(relativeState, level, relativePos, random)
} else if (isAmethystStage(block)) {
advanceAmethyst(relativeState, level, relativePos)
}
}
}
private fun advanceAmethyst(state: BlockState, level: LevelAccessor, pos: BlockPos) {
val facing = state.getValue(DirectionalBlock.FACING)
val supportState = level.getBlockState(pos.relative(facing.opposite))
if (!supportState.`is`(CobblemonBlockTags.TYPE_GEM_BLOCKS) && supportState.block != CobblemonBlocks.TYPE_GEM_CORE) {
return
}
if (state.block != Blocks.AMETHYST_CLUSTER) {
val nextStage = AMETHYST_STAGES[AMETHYST_STAGES.indexOf(state.block) + 1]
level.setBlock(pos, nextStage.defaultBlockState().setValue(DirectionalBlock.FACING, facing), 3)
return
}
// Fully grown clusters mature into amethyst blocks unless boxed in, mirroring stunted type gems
val boxedIn = Direction.entries.any { direction ->
direction != facing.opposite
&& level.getBlockState(pos.relative(direction)).`is`(CobblemonBlockTags.TYPE_GEM_BLOCKS)
}
if (!boxedIn) {
level.setBlock(pos, Blocks.AMETHYST_BLOCK.defaultBlockState(), 3)
}
}
@@ -111,7 +111,6 @@ object CobblemonClient {
val battleOverlay: BattleOverlay by lazy { BattleOverlay() }
val pokedexUsageContext: PokedexUsageContext by lazy { PokedexUsageContext() }
val rideControlsOverlay: RideControlsOverlay by lazy { RideControlsOverlay() }
var pcHealthToggle: Boolean = false
fun onLogin() {
clientPlayerData = ClientGeneralPlayerData()
@@ -29,8 +29,7 @@ class BoxStorageSlot(
val grabbedSlot = parent.grabbedSlot
return if (grabbedSlot == null) {
val pokemon = getPokemon()
pokemon == null || !parent.isInMultiSelection(pokemon, position)
true
} else {
grabbedSlot.getPokemon() != getPokemon()
}
@@ -50,7 +50,6 @@ import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvent
import kotlin.isInitialized
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.FastColor
class PCGUI(
val pc: ClientPC,
@@ -99,8 +98,6 @@ class PCGUI(
private val buttonWallpaperResource = cobblemonResource("textures/gui/pc/pc_button_set_wallpaper.png")
private val buttonInfoArrow = cobblemonResource("textures/gui/pc/info_arrow.png")
private val buttonHealthToggleResource = cobblemonResource("textures/gui/pc/pc_button_toggle_health.png")
private val topSpacerResource = cobblemonResource("textures/gui/pc/pc_spacer_top.png")
private val bottomSpacerResource = cobblemonResource("textures/gui/pc/pc_spacer_bottom.png")
private val rightSpacerResource = cobblemonResource("textures/gui/pc/pc_spacer_right.png")
@@ -132,55 +129,6 @@ class PCGUI(
var selectPointerOffsetIncrement = false
var displayOptions = false
private var dragStartX: Int? = null
private var dragStartY: Int? = null
private var dragEndX: Int? = null
private var dragEndY: Int? = null
private var selectionDragActive = false
data class SelectionArea(val left: Int, val top: Int, val right: Int, val bottom: Int)
private data class BoxGridBounds(val left: Int, val top: Int, val right: Int, val bottom: Int) {
fun contains(x: Int, y: Int) = x in left..< right && y >= top && y < bottom
}
private fun getBoxGridBounds(): BoxGridBounds {
val left = storageWidget.x
val top = storageWidget.y
return BoxGridBounds(
left,
top,
left + StorageWidget.SCREEN_WIDTH,
top + StorageWidget.SCREEN_HEIGHT
)
}
fun getSelectionArea(): SelectionArea? {
if (!selectionDragActive) return null
val startX = dragStartX ?: return null
val startY = dragStartY ?: return null
val endX = dragEndX ?: return null
val endY = dragEndY ?: return null
val bounds = getBoxGridBounds()
if (!bounds.contains(startX, startY)) return null
val columns = 6
val rows = 5
val slotPitch = StorageSlot.SIZE + StorageWidget.BOX_SLOT_PADDING
val gridLeft = bounds.left + StorageWidget.BOX_SLOT_START_OFFSET_X
val gridTop = bounds.top + StorageWidget.BOX_SLOT_START_OFFSET_Y + if (displayOptions) 5 else 0
val startColumn = ((startX - gridLeft) / slotPitch).coerceIn(0, columns - 1)
val endColumn = (((endX.coerceIn(bounds.left, bounds.right - 1)) - gridLeft) / slotPitch).coerceIn(0, columns - 1)
val startRow = ((startY - gridTop) / slotPitch).coerceIn(0, rows - 1)
val endRow = (((endY.coerceIn(bounds.top, bounds.bottom - 1)) - gridTop) / slotPitch).coerceIn(0, rows - 1)
return SelectionArea(
gridLeft + minOf(startColumn, endColumn) * slotPitch, // left
gridTop + minOf(startRow, endRow) * slotPitch, // top
gridLeft + (maxOf(startColumn, endColumn) * slotPitch) + StorageSlot.SIZE, // right
gridTop + (maxOf(startRow, endRow) * slotPitch) + StorageSlot.SIZE // bottom
)
}
override fun renderBlurredBackground(delta: Float) {}
override fun renderMenuBackground(context: GuiGraphics) {}
@@ -271,6 +219,7 @@ class PCGUI(
storageWidget.setupStorageSlots()
for (button in optionButtons) {
button.visible = displayOptions
button.highlighted = false
}
}.also { it.highlighted = displayOptions }
)
@@ -301,28 +250,12 @@ class PCGUI(
configuration.showParty = isVisible
wallpaperWidget.visible = !isVisible
(it as IconButton).highlighted = !isVisible
if (unseenWallpapers.isNotEmpty()) MarkPCBoxWallpapersSeenPacket(unseenWallpapers).sendToServer()
if (!unseenWallpapers.isEmpty()) MarkPCBoxWallpapersSeenPacket(unseenWallpapers).sendToServer()
}.also {
it.visible = displayOptions
optionButtons.add(it)
})
val healthButton = this.addRenderableWidget(IconButton(
pX = x + 230,
pY = y + 31,
buttonWidth = 20,
buttonHeight = 20,
resource = buttonHealthToggleResource,
label = "toggle_health_bars",
) {
CobblemonClient.pcHealthToggle = !CobblemonClient.pcHealthToggle
(it as IconButton).highlighted = CobblemonClient.pcHealthToggle
}.also {
it.visible = displayOptions
optionButtons.add(it)
})
healthButton.highlighted = CobblemonClient.pcHealthToggle
PokemonSortMode.entries.forEachIndexed { index, sortType ->
val typeName = sortType.name.lowercase()
this.addRenderableWidget(IconButton(
@@ -382,20 +315,6 @@ class PCGUI(
super.init()
}
private fun renderSelectionBox(context: GuiGraphics, area: SelectionArea) {
context.pose().pushPose()
context.pose().translate(0.0, 0.0, 1500.0)
val borderColor = FastColor.ARGB32.color(255, 205, 212, 255)
val bgColor = FastColor.ARGB32.color(75, 133, 183, 230)
val thickness = 1
context.fill(area.left, area.top, area.right, area.bottom, bgColor)
context.fill(area.left, area.top, area.right, area.top + thickness, borderColor)
context.fill(area.left, area.bottom - thickness, area.right, area.bottom, borderColor)
context.fill(area.left, area.top, area.left + thickness, area.bottom, borderColor)
context.fill(area.right - thickness, area.top, area.right, area.bottom, borderColor)
context.pose().popPose()
}
override fun render(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
val matrices = context.pose()
renderBackground(context, mouseX, mouseY, delta)
@@ -536,20 +455,6 @@ class PCGUI(
shadow = true
)
// var dexNo = pokemon.species.nationalPokedexNumber.toString()
// while (dexNo.length < 4) {
// dexNo = "0$dexNo"
// }
// drawScaledText(
// context = context,
// font = CobblemonResources.DEFAULT_LARGE,
// text = Component.literal(dexNo).bold(),
// x = x + 38,
// y = y + 1.5,
// shadow = true,
// scale = 0.85f
// )
drawScaledText(
context = context,
font = CobblemonResources.DEFAULT_LARGE,
@@ -780,14 +685,12 @@ class PCGUI(
scale = SCALE
)
if (optionButtons.isNotEmpty() && displayOptions) {
if (!optionButtons.isEmpty() && displayOptions) {
for (button in optionButtons) button.showAlt = hasShiftDown()
}
super.render(context, mouseX, mouseY, delta)
getSelectionArea()?.let { renderSelectionBox(context, it) }
// Item Tooltip
if (pokemon != null) {
val displayedItem = if (showCosmeticItem) pokemon.cosmeticItem else pokemon.heldItemNoCopy()
@@ -809,20 +712,6 @@ class PCGUI(
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
storageWidget.clearPendingStorageSlotClick()
selectionDragActive = false
val clickX = mouseX.toInt()
val clickY = mouseY.toInt()
if (storageWidget.multiSelection == null && button == 0 &&
getBoxGridBounds().contains(clickX, clickY) &&
storageWidget.pastureWidget == null) {
dragStartX = clickX
dragStartY = clickY
} else {
dragStartX = null
dragStartY = null
}
// Trigger child component function as they will need to check the entire screen click area
if (::boxNameWidget.isInitialized) boxNameWidget.mouseClicked(mouseX, mouseY, button)
return super.mouseClicked(mouseX, mouseY, button)
@@ -851,43 +740,9 @@ class PCGUI(
storageWidget.pastureWidget?.let { pasture ->
if (pasture.pastureScrollList.isHovered) pasture.pastureScrollList.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
}
if (button == 0 && storageWidget.pastureWidget == null) {
val startX = dragStartX
val startY = dragStartY
if (startX != null && startY != null) {
val offsetX = mouseX - startX
val offsetY = mouseY - startY
if (offsetX * offsetX + offsetY * offsetY >= 25.0) {
selectionDragActive = true
storageWidget.clearPendingStorageSlotClick()
dragEndX = mouseX.toInt()
dragEndY = mouseY.toInt()
}
}
}
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
}
override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
val handled = super.mouseReleased(mouseX, mouseY, button)
if (button == 0) {
if (selectionDragActive) {
dragEndX = mouseX.toInt()
dragEndY = mouseY.toInt()
storageWidget.updateSelection()
storageWidget.clearPendingStorageSlotClick()
} else {
storageWidget.completePendingStorageSlotClick(mouseX, mouseY)
}
}
dragStartX = null
dragStartY = null
dragEndX = null
dragEndY = null
selectionDragActive = false
return handled
}
override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
val boxNameFocused = this::boxNameWidget.isInitialized && boxNameWidget.isFocused
val filterFocused = this::filterWidget.isInitialized && filterWidget.isFocused
@@ -1,37 +0,0 @@
package com.cobblemon.mod.common.client.gui.pc
import com.cobblemon.mod.common.pokemon.Pokemon
data class PCMultiSelection(
private val grid: MutableList<MutableList<Pokemon?>> = mutableListOf(),
val sourceBox: Int = 0,
val sourceColumn: Int = 0,
val sourceRow: Int = 0
) {
fun getHorizontalSize(): Int = grid.firstOrNull()?.size ?: 0
fun getVerticalSize(): Int = grid.size
constructor(horizontalSize: Int, verticalSize: Int, sourceBox: Int, sourceColumn: Int, sourceRow: Int) : this(
MutableList(verticalSize) { MutableList<Pokemon?>(horizontalSize) { null } },
sourceBox,
sourceColumn,
sourceRow
)
fun getPokemon(x: Int, y: Int): Pokemon? {
return grid[y][x]
}
fun setPokemon(x: Int, y: Int, pokemon: Pokemon?) {
grid[y][x] = pokemon
}
fun pokemonEntries(): List<Triple<Int, Int, Pokemon>> {
return grid.flatMapIndexed { y, row ->
row.mapIndexedNotNull { x, pokemon -> pokemon?.let { Triple(x, y, it) } }
}
}
fun getPokemonCount(): Int = pokemonEntries().size
}
@@ -45,13 +45,11 @@ class ReleaseButton(
vOffset = if (isHovered(mouseX.toDouble(), mouseY.toDouble())) HEIGHT else 0,
textureHeight = HEIGHT * 2
)
val pokemonCount = parent.multiSelection?.getPokemonCount() ?: 0
drawScaledText(
context = context,
font = CobblemonResources.DEFAULT_LARGE,
text = if (pokemonCount > 1)
{ lang("ui.pc.release_all").bold() } else { lang("ui.pc.release").bold() },
text = lang("ui.pc.release").bold(),
x = x + (WIDTH / 2),
y = y + 3.5,
centered = true,
@@ -10,11 +10,10 @@ package com.cobblemon.mod.common.client.gui.pc
import com.cobblemon.mod.common.Cobblemon
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
import com.cobblemon.mod.common.client.gui.PokemonGUIAnimationStyle
import com.cobblemon.mod.common.client.gui.drawProfilePokemon
import com.cobblemon.mod.common.client.gui.pasture.PasturePCGUIConfiguration
import com.cobblemon.mod.common.client.gui.PokemonGUIAnimationStyle
import com.cobblemon.mod.common.client.render.drawScaledText
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState
import com.cobblemon.mod.common.client.render.renderScaledGuiItemIcon
@@ -23,19 +22,13 @@ import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.lang
import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
import juuxel.adorn.util.Colors
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.components.Button
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.sounds.SoundManager
import net.minecraft.network.chat.Component
import net.minecraft.util.Mth
import org.joml.Quaternionf
import org.joml.Vector3f
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.roundToInt
open class StorageSlot(
x: Int, y: Int,
@@ -61,17 +54,9 @@ open class StorageSlot(
}
override fun renderWidget(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
val selectionArea = parent.pcGui.getSelectionArea()
if (selectionArea != null && parent.getSelectedPokemon(selectionArea).contains(this)) {
val highlightColor = 0x40FFFFFF
context.fill(x + 1, y, x + (SIZE - 1), y + SIZE, highlightColor)
context.fill(x, y + 1, x + 1, y + (SIZE - 1), highlightColor)
context.fill(x + SIZE - 1, y + 1, x + SIZE, y + (SIZE - 1), highlightColor)
}
if (shouldRender()) {
renderSlot(context, x, y, delta)
}
}
fun renderSlot(context: GuiGraphics, posX: Int, posY: Int, partialTicks: Float) {
@@ -145,23 +130,6 @@ open class StorageSlot(
matrixStack = matrices
)
}
// Pokemon health
// Taken from vanilla durability rendering
val currentHealth = pokemon.currentHealth
val maxHealth = pokemon.maxHealth.toFloat()
if (currentHealth < maxHealth && CobblemonClient.pcHealthToggle) {
val damageValue = maxHealth - currentHealth
val f = max(0.0f, (maxHealth - (maxHealth - currentHealth)) / maxHealth)
val color = Mth.hsvToRgb(f / 3.0f, 1.0f, 1.0f)
val totalWidth = 12
val width = (totalWidth - damageValue * totalWidth / pokemon.maxHealth.toFloat()).roundToInt();
val k = posX + 1
val l = posY + 6
val bgColor = if (this is PartyStorageSlot) Colors.BLACK else 0xFF3E3E3E.toInt()
context.fill(RenderType.guiOverlay(), k, l, k + totalWidth, l + 1, bgColor)
context.fill(RenderType.guiOverlay(), k, l, k + width, l + 1, color or bgColor)
}
matrices.popPose()
}
@@ -11,6 +11,7 @@ package com.cobblemon.mod.common.client.gui.pc
import com.cobblemon.mod.common.CobblemonNetwork
import com.cobblemon.mod.common.CobblemonSounds
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.storage.StorePosition
import com.cobblemon.mod.common.api.storage.party.PartyPosition
import com.cobblemon.mod.common.api.storage.pc.PCPosition
import com.cobblemon.mod.common.api.text.bold
@@ -38,9 +39,8 @@ import net.minecraft.client.gui.components.Button
import net.minecraft.client.gui.screens.Screen
import net.minecraft.client.resources.sounds.SimpleSoundInstance
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.sounds.SoundEvent
import java.util.UUID
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePCPokemonBatchPacket.PCPokemonMove
class StorageWidget(
pX: Int, pY: Int,
@@ -77,14 +77,9 @@ class StorageWidget(
var displayConfirmRelease = false
var screenLoaded = false
var selectedPosition: PartyPosition? = null
var selectedPosition: StorePosition? = null
var grabbedSlot: GrabbedStorageSlot? = null
var multiSelection: PCMultiSelection? = null
private val multiGrabbedSlots = mutableMapOf<UUID, GrabbedStorageSlot>()
private var pendingStorageSlotClick: Button? = null
private var movePending = false
var box = 0
set(value) {
field =
@@ -118,22 +113,16 @@ class StorageWidget(
subKey = "ui.generic.yes",
onPress = {
if (canDeleteSelected() && displayConfirmRelease) {
val selection = multiSelection
if (selection != null) {
selection.pokemonEntries().forEach { (column, row, pokemon) ->
val position = PCPosition(
selection.sourceBox,
(selection.sourceRow + row) * 6 + selection.sourceColumn + column
)
CobblemonNetwork.sendToServer(ReleasePCPokemonPacket(pokemon.uuid, position))
}
} else {
val position = selectedPosition ?: return@ReleaseConfirmButton
val pokemon = getSelectedPokemon() ?: return@ReleaseConfirmButton
val position = selectedPosition ?: return@ReleaseConfirmButton
val pokemon = getSelectedPokemon() ?: return@ReleaseConfirmButton
CobblemonNetwork.sendToServer(ReleasePartyPokemonPacket(pokemon.uuid, position))
val packet = when (position) {
is PartyPosition -> ReleasePartyPokemonPacket(pokemon.uuid, position)
is PCPosition -> ReleasePCPokemonPacket(pokemon.uuid, position)
else -> return@ReleaseConfirmButton
}
CobblemonNetwork.sendToServer(packet)
playSound(CobblemonSounds.PC_RELEASE)
resetSelected()
displayConfirmRelease = false
@@ -160,8 +149,9 @@ class StorageWidget(
}
fun canDeleteSelected(): Boolean {
multiSelection?.let { return it.pokemonEntries().isNotEmpty() }
return party.filterNotNull().size > 1 && selectedPosition != null && grabbedSlot != null
return !(selectedPosition is PartyPosition && party.filterNotNull().size <= 1)
&& selectedPosition != null
&& grabbedSlot != null
}
fun setupStorageSlots() {
@@ -180,7 +170,7 @@ class StorageWidget(
parent = this,
pc = pc,
position = PCPosition(box, index),
onPress = { pendingStorageSlotClick = it }
onPress = { this.onStorageSlotClicked(it) }
).also { widget ->
this.addWidget(widget)
this.boxSlots.add(widget)
@@ -210,7 +200,7 @@ class StorageWidget(
parent = this,
party = party,
position = PartyPosition(partyIndex),
onPress = { pendingStorageSlotClick = it }
onPress = { this.onStorageSlotClicked(it) }
).also { widget ->
this.addWidget(widget)
this.partySlots.add(widget)
@@ -220,117 +210,14 @@ class StorageWidget(
private fun getSelectedPokemon(): Pokemon? {
val selectedPosition = this.selectedPosition ?: return null
return party.get(selectedPosition)
}
fun getSelectedPokemon(area: PCGUI.SelectionArea): List<BoxStorageSlot> {
return boxSlots.filter { slot ->
slot.x < area.right && slot.x + StorageSlot.SIZE > area.left &&
slot.y < area.bottom && slot.y + StorageSlot.SIZE > area.top &&
slot.getPokemon()?.let(pcGui.search::passes) == true
return when (selectedPosition) {
is PCPosition -> pc.get(selectedPosition)
is PartyPosition -> party.get(selectedPosition)
else -> null
}
}
fun clearPendingStorageSlotClick() {
pendingStorageSlotClick = null
}
fun completePendingStorageSlotClick(mouseX: Double, mouseY: Double) {
val button = pendingStorageSlotClick ?: return
pendingStorageSlotClick = null
if (button.isMouseOver(mouseX, mouseY)) {
onStorageSlotClicked(button)
}
}
fun updateSelection() {
val area = pcGui.getSelectionArea()
if (area == null) {
multiSelection = null
return
}
selectedPosition = null
grabbedSlot = null
pcGui.setPreviewPokemon(null)
val selectedSlots = getSelectedPokemon(area)
if (selectedSlots.isEmpty()) {
multiSelection = null
return
}
val minColumn = selectedSlots.minOf { it.position.slot % 6 }
val maxColumn = selectedSlots.maxOf { it.position.slot % 6 }
val minRow = selectedSlots.minOf { it.position.slot / 6 }
val maxRow = selectedSlots.maxOf { it.position.slot / 6 }
val selection = PCMultiSelection(maxColumn - minColumn + 1, maxRow - minRow + 1, box, minColumn, minRow)
selectedSlots.forEach { slot ->
val pokemon = slot.getPokemon() ?: return@forEach
val slotIndex = slot.position.slot
val column = slotIndex % 6
val row = slotIndex / 6
if (column in minColumn..maxColumn && row in minRow..maxRow) {
selection.setPokemon(column - minColumn, row - minRow, pokemon)
}
}
playSound(CobblemonSounds.PC_GRAB)
multiSelection = selection
}
private fun moveMultiSelectionTo(destination: PCPosition): Boolean {
val selection = multiSelection ?: return false
val width = selection.getHorizontalSize()
val height = selection.getVerticalSize()
val destinationColumn = destination.slot % 6
val destinationRow = destination.slot / 6
if (destinationColumn + width > 6 || destinationRow + height > 5) return false
val moves = mutableListOf<PCPokemonMove>()
val selectedSources = mutableSetOf<PCPosition>()
for (row in 0 until height) {
for (column in 0 until width) {
val pokemon = selection.getPokemon(column, row) ?: continue
val source = PCPosition(selection.sourceBox, (selection.sourceRow + row) * 6 + selection.sourceColumn + column)
val target = PCPosition(destination.box, (destinationRow + row) * 6 + destinationColumn + column)
selectedSources.add(source)
moves.add(PCPokemonMove(pokemon.uuid, source, target))
}
}
if (moves.isEmpty()) return false
for (row in 0 until height) {
for (column in 0 until width) {
if (selection.getPokemon(column, row) == null) continue
val target = PCPosition(destination.box, (destinationRow + row) * 6 + destinationColumn + column)
val displacedPokemon = pc.get(target) ?: continue
if (target in selectedSources) continue
val displacedSource = PCPosition(
selection.sourceBox,
(selection.sourceRow + row) * 6 + selection.sourceColumn + column
)
if (pc.get(displacedSource) != null && displacedSource !in selectedSources) return false
moves.add(PCPokemonMove(displacedPokemon.uuid, target, displacedSource))
}
}
if (moves.map { it.newPosition }.toSet().size != moves.size) return false
MovePCPokemonBatchPacket(moves).sendToServer()
return true
}
fun isInMultiSelection(pokemon: Pokemon, position: PCPosition): Boolean {
val selection = multiSelection ?: return false
return selection.sourceBox == position.box && selection.pokemonEntries().any { it.third == pokemon }
}
override fun renderWidget(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
updatePendingMove()
val matrices = context.pose()
// Party Label
if (pcGui.configuration.showParty) {
@@ -353,14 +240,11 @@ class StorageWidget(
shadow = true
)
val pokemonCount = multiSelection?.getPokemonCount() ?: 0
if (canDeleteSelected() && displayConfirmRelease) {
drawScaledText(
context = context,
font = CobblemonResources.DEFAULT_LARGE,
text = if (pokemonCount > 1)
{ lang("ui.pc.release_all").bold() } else { lang("ui.pc.release").bold() },
text = lang("ui.pc.release").bold(),
x = x + 223,
y = y + 119,
centered = true
@@ -424,7 +308,6 @@ class StorageWidget(
slot.render(context, mouseX, mouseY, delta)
val pokemon = slot.getPokemon()
if (grabbedSlot == null && slot.isHovered(mouseX, mouseY)
&& multiSelection == null
&& pokemon != null && pokemon != pcGui.previewPokemon
) {
pcGui.setPreviewPokemon(pokemon, pcGui.isPreviewInParty ?: false)
@@ -441,7 +324,6 @@ class StorageWidget(
slot.render(context, mouseX, mouseY, delta)
val pokemon = slot.getPokemon()
if (grabbedSlot == null && slot.isHovered(mouseX, mouseY)
&& multiSelection == null
&& pokemon != null && pokemon != pcGui.previewPokemon
) {
pcGui.setPreviewPokemon(pokemon, pcGui.isPreviewInParty ?: true)
@@ -453,32 +335,10 @@ class StorageWidget(
pastureWidget?.render(context, mouseX, mouseY, delta)
matrices.pushPose()
matrices.translate(0.0, 0.0, 1000.0)
renderSelectedPokemon(context, mouseX, mouseY, delta)
grabbedSlot?.render(context, mouseX, mouseY, delta)
matrices.popPose()
}
private fun renderSelectedPokemon(context: GuiGraphics, mouseX: Int, mouseY: Int, delta: Float) {
if (movePending) return
val selection = multiSelection
if (selection == null) {
grabbedSlot?.render(context, mouseX, mouseY, delta)
return
}
val slotOffset = StorageSlot.SIZE + BOX_SLOT_PADDING
selection.pokemonEntries().forEach { (column, row, pokemon) ->
val grabbed = multiGrabbedSlots.getOrPut(pokemon.uuid) {
GrabbedStorageSlot(0, 0, this, pokemon)
}
grabbed.render(
context,
mouseX + column * slotOffset,
mouseY + row * slotOffset,
delta
)
}
}
override fun mouseClicked(pMouseX: Double, pMouseY: Double, pButton: Int): Boolean {
if (displayConfirmRelease) {
if (releaseYesButton.isHovered(pMouseX, pMouseY)) releaseYesButton.mouseClicked(pMouseX, pMouseY, pButton)
@@ -511,55 +371,23 @@ class StorageWidget(
else -> return
}
val clickedPokemon = when (clickedPosition) {
is PCPosition -> pc.get(clickedPosition)
is PartyPosition -> party.get(clickedPosition)
else -> null
}
multiSelection?.let { selection ->
when (clickedPosition) {
is PCPosition -> {
if (clickedPosition.box == selection.sourceBox &&
clickedPosition.slot == selection.sourceRow * 6 + selection.sourceColumn
) {
resetSelected()
} else if (moveMultiSelectionTo(clickedPosition)) {
playSound(CobblemonSounds.PC_DROP)
movePending = true
}
}
is PartyPosition -> {
val selectedPokemon = selection.pokemonEntries().singleOrNull() ?: return
val (column, row, pokemon) = selectedPokemon
val source = PCPosition(
selection.sourceBox,
(selection.sourceRow + row) * 6 + selection.sourceColumn + column
)
if (pc.get(source) !== pokemon) return
val packet = clickedPokemon?.let {
SwapPCPartyPokemonPacket(it.uuid, clickedPosition, pokemon.uuid, source)
} ?: MovePCPokemonToPartyPacket(pokemon.uuid, source, clickedPosition)
packet.sendToServer()
playSound(CobblemonSounds.PC_DROP)
movePending = true
}
else -> Unit
}
return
}
// Reset release confirmation
displayConfirmRelease = false
// Clicking on itself, so unselect position
if (selectedPosition == clickedPosition) {
if (this.selectedPosition != null && this.selectedPosition == clickedPosition) {
if (grabbedSlot != null) playSound(CobblemonSounds.PC_DROP)
resetSelected()
return
}
// Check for selecting a Pokémon
val clickedPokemon = when(button) {
is BoxStorageSlot -> pc.get(clickedPosition as PCPosition)
is PartyStorageSlot -> party.get(clickedPosition as PartyPosition)
else -> null
}
val selectOverride = pcGui.configuration.selectOverride
if (selectOverride != null) {
selectOverride(pcGui, clickedPosition, clickedPokemon)
@@ -592,47 +420,59 @@ class StorageWidget(
}
}
if (clickedPosition is PCPosition) {
val column = clickedPosition.slot % 6
val row = clickedPosition.slot / 6
multiSelection = PCMultiSelection(1, 1, clickedPosition.box, column, row).also {
it.setPokemon(0, 0, clickedPokemon)
}
playSound(CobblemonSounds.PC_GRAB)
return
} else if (clickedPosition is PartyPosition) {
this.selectedPosition = clickedPosition
this.pcGui.setPreviewPokemon(clickedPokemon, pcGui.isPreviewInParty ?: false)
grabbedSlot = GrabbedStorageSlot(
x = button.x,
y = button.y,
parent = this,
pokemon = clickedPokemon
)
playSound(CobblemonSounds.PC_GRAB)
}
this.selectedPosition = clickedPosition
this.pcGui.setPreviewPokemon(clickedPokemon, pcGui.isPreviewInParty ?: false)
grabbedSlot = GrabbedStorageSlot(
x = button.x,
y = button.y,
parent = this,
pokemon = clickedPokemon
)
playSound(CobblemonSounds.PC_GRAB)
}
} else {
val sourcePosition = selectedPosition ?: return
val selectedPokemon = party.get(sourcePosition) ?: return
// Handle movement within the Box
val selectedPokemon = when(this.selectedPosition) {
is PCPosition -> pc.get(this.selectedPosition as PCPosition)
is PartyPosition -> party.get(this.selectedPosition as PartyPosition)
else -> null
} ?: return
// Box to Box
if (this.selectedPosition is PCPosition && clickedPosition is PCPosition) {
val packet = clickedPokemon?.let { SwapPCPokemonPacket(it.uuid, clickedPosition, selectedPokemon.uuid, this.selectedPosition as PCPosition) }
?: MovePCPokemonPacket(selectedPokemon.uuid, selectedPosition as PCPosition, clickedPosition)
packet.sendToServer()
playSound(CobblemonSounds.PC_DROP)
resetSelected()
}
// Box to Party
else if (this.selectedPosition is PCPosition && clickedPosition is PartyPosition) {
val packet = clickedPokemon?.let { SwapPCPartyPokemonPacket(clickedPokemon.uuid, clickedPosition, selectedPokemon.uuid, this.selectedPosition as PCPosition) }
?: MovePCPokemonToPartyPacket(selectedPokemon.uuid, this.selectedPosition as PCPosition, clickedPosition)
packet.sendToServer()
playSound(CobblemonSounds.PC_DROP)
resetSelected()
}
// Party to Box
if (clickedPosition is PCPosition) {
else if (this.selectedPosition is PartyPosition && clickedPosition is PCPosition) {
if (ServerSettings.preventCompletePartyDeposit && this.party.filterNotNull().size == 1 && clickedPokemon == null) {
return
}
val packet = clickedPokemon?.let { SwapPCPartyPokemonPacket(selectedPokemon.uuid, sourcePosition, clickedPokemon.uuid, clickedPosition) }
?: MovePartyPokemonToPCPacket(selectedPokemon.uuid, sourcePosition, clickedPosition)
val packet = clickedPokemon?.let { SwapPCPartyPokemonPacket(selectedPokemon.uuid, this.selectedPosition as PartyPosition, clickedPokemon.uuid, clickedPosition) }
?: MovePartyPokemonToPCPacket(selectedPokemon.uuid, this.selectedPosition as PartyPosition, clickedPosition)
packet.sendToServer()
playSound(CobblemonSounds.PC_DROP)
movePending = true
resetSelected()
}
// Party to Party
else if (clickedPosition is PartyPosition) {
val packet = clickedPokemon?.let { SwapPartyPokemonPacket(it.uuid, clickedPosition, selectedPokemon.uuid, sourcePosition) }
?: MovePartyPokemonPacket(selectedPokemon.uuid, sourcePosition, clickedPosition)
else if (this.selectedPosition is PartyPosition && clickedPosition is PartyPosition) {
val packet = clickedPokemon?.let { SwapPartyPokemonPacket(it.uuid, clickedPosition, selectedPokemon.uuid, this.selectedPosition as PartyPosition) }
?: MovePartyPokemonPacket(selectedPokemon.uuid, selectedPosition as PartyPosition, clickedPosition)
packet.sendToServer()
playSound(CobblemonSounds.PC_DROP)
movePending = true
resetSelected()
}
}
}
@@ -640,36 +480,6 @@ class StorageWidget(
fun resetSelected() {
selectedPosition = null
grabbedSlot = null
multiSelection = null
multiGrabbedSlots.clear()
pcGui.setPreviewPokemon(null)
}
// annoyingly complex solution, but server/client desync causes flashing when moving pokemon. this should fix it
// if you can think of a simpler solution, feel free to implement it
private fun updatePendingMove() {
if (!movePending) return
val selection = multiSelection
if (selection != null) {
val updated = selection.pokemonEntries().any { (column, row, pokemon) ->
val source = PCPosition(selection.sourceBox, (selection.sourceRow + row) * 6 + selection.sourceColumn + column)
pc.get(source)?.uuid != pokemon.uuid
}
if (updated) {
movePending = false
resetSelected()
}
return
}
val source = selectedPosition
val pokemon = grabbedSlot?.getPokemon()
if (source != null && pokemon != null) {
if (party.get(source)?.uuid != pokemon.uuid) {
movePending = false
resetSelected()
}
}
}
}
@@ -6,23 +6,59 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.gui.summary.widgets.screens.moves
package com.cobblemon.mod.common.client.gui.summary
import com.cobblemon.mod.common.client.gui.CobblemonRenderable
import com.cobblemon.mod.common.client.render.drawScaledText
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.components.ObjectSelectionList
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.util.Mth
class MoveDescriptionScrollList(
class ScrollableTextBoxEntry(
var line : MutableComponent
) :
ObjectSelectionList.Entry<ScrollableTextBoxEntry>() {
override fun render(
context: GuiGraphics,
index: Int,
rowTop: Int,
rowLeft: Int,
rowWidth: Int,
rowHeight: Int,
mouseX: Int,
mouseY: Int,
isHovered: Boolean,
partialTicks: Float
) {
drawScaledText(
context = context,
text = line,
x = rowLeft + 82,
y = rowTop,
scale = 0.5F,
shadow = true
)
}
override fun getNarration(): Component {
return line
}
}
class ScrollableTextBox(
private val listX: Int,
private val listY: Int,
height: Int,
width: Int,
slotHeight: Int
) : ObjectSelectionList<MoveDescriptionEntry>(
) : ObjectSelectionList<ScrollableTextBoxEntry>(
Minecraft.getInstance(),
60, // width
30, // height
width, // width
height, // height
0, // top
slotHeight
), CobblemonRenderable {
@@ -38,8 +74,31 @@ class MoveDescriptionScrollList(
return x + width - 3
}
override fun getMaxPosition(): Int {
return super.getMaxPosition() + 3 // add bottom padding
}
// we do our own scrollbar rendering, and this being true renders the vanilla one
override fun scrollbarVisible() = false
override fun renderWidget(context: GuiGraphics, pMouseX: Int, pMouseY: Int, f: Float) {
isHovered = pMouseX >= x && pMouseY >= y && pMouseX < x + width && pMouseY < y + height
if (maxScroll > 0) {
val right = x + width
val bottom = y + height
val darkGray = 0xFF5B595B.toInt()
val lightGray = 0xFF8C8C8C.toInt()
context.fill(right - 2, y + 2, right - 4, bottom - 2, darkGray)
// vanilla scrollbar mumbo jumbo
var scrollHeight = ((height * height).toFloat() / maxPosition.toFloat()).toInt()
scrollHeight = Mth.clamp(scrollHeight, 32, height - 8)
var scrollY = scrollAmount.toInt() * (height - scrollHeight + 2) / maxScroll + y - 1
if (scrollY < y) { scrollY = y }
context.fill(right - 2, scrollY + 2, right - 4, scrollY + scrollHeight - 3, lightGray)
}
context.enableScissor(
x,
y,
@@ -79,7 +138,7 @@ class MoveDescriptionScrollList(
&& mouseY < bottom
}
fun setMoveDescription(moveDescription: MutableComponent) {
fun setText(moveDescription: MutableComponent) {
clearEntries()
val splitWidth = 100
val text = moveDescription.string
@@ -103,7 +162,8 @@ class MoveDescriptionScrollList(
}
for (part in splitText) {
addEntry(MoveDescriptionEntry(Component.literal(part)))
addEntry(ScrollableTextBoxEntry(Component.literal(part)))
}
scrollAmount = 0.0
}
}
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.api.gui.MultiLineLabelK
import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.text.*
import com.cobblemon.mod.common.client.CobblemonResources
import com.cobblemon.mod.common.client.gui.summary.ScrollableTextBox
import com.cobblemon.mod.common.client.gui.summary.widgets.SoundlessWidget
import com.cobblemon.mod.common.client.gui.summary.widgets.common.reformatNatureTextIfMinted
import com.cobblemon.mod.common.client.gui.summary.widgets.screens.stats.StatWidget.Companion.SCALE
@@ -27,6 +28,7 @@ import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import net.minecraft.resources.ResourceLocation
class InfoWidget(
pX: Int,
@@ -45,6 +47,25 @@ class InfoWidget(
private val infoBaseResource = cobblemonResource("textures/gui/summary/summary_info_base.png")
}
private var metDataWidget: ScrollableTextBox = ScrollableTextBox(x + 5, y + 123, 20, 61, 5)
init {
pokemon.metData?.let { metData ->
val biome = ResourceLocation.parse(metData.biome.registeredName)
val biomeName = Component.translatable("biome.${biome.namespace}.${biome.path}")
metDataWidget.setText(lang("ui.info.met_data",
biomeName,
metData.date.monthValue,
metData.date.dayOfMonth,
metData.date.year,
metData.level
))
} ?: run {
metDataWidget.setText(lang("ui.info.met_data_unavailable"))
}
addWidget(metDataWidget)
}
override fun renderWidget(context: GuiGraphics, pMouseX: Int, pMouseY: Int, pPartialTicks: Float) {
val matrices = context.pose()
// Base texture
@@ -163,6 +184,17 @@ class InfoWidget(
)
matrices.popPose()
metDataWidget.render(context, pMouseX, pMouseY, pPartialTicks)
// val textLines = mutableListOf<MutableComponent>()
// pokemon.metData?.let { metData ->
// }
//
// metDataWidget.textLines = textLines
// metDataWidget.render(context, pMouseX, pMouseY, pPartialTicks)
drawScaledText(
context = context,
text = lang("ui.info.experience_points"),
@@ -1,47 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.client.gui.summary.widgets.screens.moves
import com.cobblemon.mod.common.client.render.drawScaledText
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.components.ObjectSelectionList
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
class MoveDescriptionEntry(
var line : MutableComponent
) :
ObjectSelectionList.Entry<MoveDescriptionEntry>() {
override fun render(
context: GuiGraphics,
index: Int,
rowTop: Int,
rowLeft: Int,
rowWidth: Int,
rowHeight: Int,
mouseX: Int,
mouseY: Int,
isHovered: Boolean,
partialTicks: Float
) {
drawScaledText(
context = context,
text = line,
x = rowLeft + 82,
y = rowTop,
scale = 0.5F,
shadow = true
)
}
override fun getNarration(): Component {
return line
}
}
@@ -13,6 +13,7 @@ import com.cobblemon.mod.common.api.gui.blitk
import com.cobblemon.mod.common.api.moves.Move
import com.cobblemon.mod.common.api.text.text
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.gui.summary.ScrollableTextBox
import com.cobblemon.mod.common.client.gui.summary.Summary
import com.cobblemon.mod.common.client.gui.summary.widgets.SoundlessWidget
import com.cobblemon.mod.common.client.render.drawScaledText
@@ -70,9 +71,11 @@ class MovesWidget(
addWidget(it)
}
private var descriptionScrollList = MoveDescriptionScrollList(
x + 69,
private var descriptionScrollList = ScrollableTextBox(
x + 68,
y + 113,
30,
61,
5
)
@@ -215,7 +218,7 @@ class MovesWidget(
fun selectMove(move: Move?) {
selectedMove = if (selectedMove == move || move == null) null else move
descriptionScrollList.setMoveDescription(selectedMove?.description ?: "".text())
descriptionScrollList.setText(selectedMove?.description ?: "".text())
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
@@ -47,6 +47,7 @@ import com.cobblemon.mod.common.net.messages.client.battle.BattleCaptureStartPac
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokeballPacket
import com.cobblemon.mod.common.pokeball.PokeBall
import com.cobblemon.mod.common.pokemon.PokemonMetData
import com.cobblemon.mod.common.pokemon.ai.PokemonBrain
import com.cobblemon.mod.common.pokemon.properties.UncatchableProperty
import com.cobblemon.mod.common.util.*
@@ -74,6 +75,9 @@ import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.EntityHitResult
import net.minecraft.world.phys.HitResult
import net.minecraft.world.phys.Vec3
import java.time.LocalDate
import java.time.ZoneId
import java.util.Date
import java.util.concurrent.CompletableFuture
class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragModifier, Schedulable {
@@ -360,6 +364,12 @@ class EmptyPokeBallEntity : ThrowableItemProjectile, PosableEntity, WaterDragMod
party.add(pokemon.pokemon)
val leashHolder = pokemon.leashHolder
pokemon.pokemon.metData = PokemonMetData(
this.level().getBiome(this.blockPosition()),
LocalDate.now(ZoneId.systemDefault()),
pokemon.pokemon.level
)
if (leashHolder != null) {
val blockPos = leashHolder.blockPosition()
val blockState = level().getBlockState(blockPos)
@@ -2744,9 +2744,4 @@ open class PokemonEntity(
}
fun hasRider() = this.passengers.any { it is LivingEntity }
override fun playStepSound(pos: BlockPos, state: BlockState) {
if (this.pokemon.species.silenceStepSounds) return
super.playStepSound(pos, state)
}
}
}
@@ -9,7 +9,6 @@
package com.cobblemon.mod.common.item.interactive
import com.cobblemon.mod.common.CobblemonItemComponents
import com.cobblemon.mod.common.item.components.FoodComponent
import net.minecraft.network.chat.Component
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundEvents
@@ -24,15 +23,10 @@ import net.minecraft.world.level.Level
class PonigiriItem : Item(
Properties().stacksTo(64)
.food(FoodProperties.Builder()
.nutrition(NUTRITION)
.saturationModifier(SATURATION_MODIFIER)
.nutrition(2)
.saturationModifier(0.55f)
.build())
) {
companion object {
const val NUTRITION = 2
const val SATURATION_MODIFIER = 0.55f
}
override fun getName(stack: ItemStack): Component {
val ingredients = stack.get(CobblemonItemComponents.INGREDIENT)
@@ -65,9 +59,4 @@ class PonigiriItem : Item(
override fun getEatingSound(): SoundEvent {
return SoundEvents.GENERIC_EAT
}
fun getFoodValues(stack: ItemStack): Pair<Int, Float> {
val (hunger, saturation) = stack.getOrDefault(CobblemonItemComponents.FOOD, FoodComponent(NUTRITION, SATURATION_MODIFIER))
return hunger to saturation
}
}
}
@@ -0,0 +1,44 @@
package com.cobblemon.mod.common.net.messages.client.pokemon.update
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.PokemonMetData
import com.cobblemon.mod.common.util.cobblemonResource
import net.minecraft.core.registries.Registries
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import java.time.Instant
import java.time.ZoneId
import kotlin.jvm.optionals.getOrNull
class MetDataUpdatePacket(pokemon: () -> Pokemon?, value: PokemonMetData): SingleUpdatePacket<PokemonMetData, MetDataUpdatePacket>(pokemon, value) {
override val id = ID
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
val biome = value.biome.unwrapKey().getOrNull()
?: ResourceKey.create(Registries.BIOME, ResourceLocation.parse("minecraft:plains"))
buffer.writeResourceKey(biome)
buffer.writeLong(value.date.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli())
buffer.writeInt(value.level)
}
override fun set(
pokemon: Pokemon,
value: PokemonMetData
) {
pokemon.metData = value
}
companion object {
val ID = cobblemonResource("met_data_update")
fun decode(buffer: RegistryFriendlyByteBuf): MetDataUpdatePacket {
val pokemon = decodePokemon(buffer)
val biomeKey = buffer.readResourceKey(Registries.BIOME)
val dateTime = buffer.readLong()
val date = Instant.ofEpochMilli(dateTime).atZone(ZoneId.systemDefault()).toLocalDate()
val level = buffer.readInt()
val biome = buffer.registryAccess().lookupOrThrow(Registries.BIOME).getOrThrow(biomeKey)
return MetDataUpdatePacket(pokemon, PokemonMetData(biome, date, level))
}
}
}
@@ -1,55 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://www.mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.net.messages.server.storage.pc
import com.cobblemon.mod.common.api.net.NetworkPacket
import com.cobblemon.mod.common.api.storage.pc.PCPosition
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.readPCPosition
import com.cobblemon.mod.common.util.writePCPosition
import java.util.UUID
import net.minecraft.network.RegistryFriendlyByteBuf
class MovePCPokemonBatchPacket(val moves: List<PCPokemonMove>) : NetworkPacket<MovePCPokemonBatchPacket> {
override val id = ID
data class PCPokemonMove(
val pokemonID: UUID,
val oldPosition: PCPosition,
val newPosition: PCPosition
)
override fun encode(buffer: RegistryFriendlyByteBuf) {
buffer.writeVarInt(moves.size)
moves.forEach { move ->
buffer.writeUUID(move.pokemonID)
buffer.writePCPosition(move.oldPosition)
buffer.writePCPosition(move.newPosition)
}
}
companion object {
val ID = cobblemonResource("move_pc_pokemon_batch")
const val MAX_MOVES = 60
fun decode(buffer: RegistryFriendlyByteBuf): MovePCPokemonBatchPacket {
val size = buffer.readVarInt()
require(size in 1..MAX_MOVES) { "Invalid batch PC move size: $size" }
return MovePCPokemonBatchPacket(
List(size) {
PCPokemonMove(
pokemonID = buffer.readUUID(),
oldPosition = buffer.readPCPosition(),
newPosition = buffer.readPCPosition()
)
}
)
}
}
}
@@ -1,23 +0,0 @@
/*
* Copyright (C) 2023 Cobblemon Contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://www.mozilla.org/MPL/2.0/.
*/
package com.cobblemon.mod.common.net.serverhandling.storage.pc
import com.cobblemon.mod.common.api.net.ServerNetworkPacketHandler
import com.cobblemon.mod.common.api.storage.pc.link.PCLinkManager
import com.cobblemon.mod.common.net.messages.client.storage.pc.ClosePCPacket
import com.cobblemon.mod.common.net.messages.server.storage.pc.MovePCPokemonBatchPacket
import net.minecraft.server.MinecraftServer
import net.minecraft.server.level.ServerPlayer
object MovePCPokemonBatchHandler : ServerNetworkPacketHandler<MovePCPokemonBatchPacket> {
override fun handle(packet: MovePCPokemonBatchPacket, server: MinecraftServer, player: ServerPlayer) {
val pc = PCLinkManager.getPC(player) ?: return run { ClosePCPacket(null).sendToPlayer(player) }
pc.moveBatch(packet.moves.map { Triple(it.pokemonID, it.oldPosition, it.newPosition) })
}
}
@@ -550,6 +550,12 @@ open class Pokemon : ShowdownIdentifiable {
onChange(OriginalTrainerUpdatePacket({ this }, value))
}
var metData: PokemonMetData? = null
set(value) {
field = value
value?.let { onChange(MetDataUpdatePacket({ this }, it)) }
}
/**
* Cache friendship on trade for OT
*/
@@ -1527,6 +1533,7 @@ open class Pokemon : ShowdownIdentifiable {
this.potentialMarks.clear()
this.potentialMarks += other.marks
this.markings = other.markings
this.metData = other.metData
this.recalculateCharacteristic()
this.updateAspects()
this.refreshOriginalTrainer()
@@ -0,0 +1,47 @@
package com.cobblemon.mod.common.pokemon
import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.core.Holder
import net.minecraft.world.level.biome.Biome
import java.time.LocalDate
/**
* Stores information about the circumstances of a player's meeting with a [Pokemon]
*
* @param biome A [Holder] for the [Biome] the [Pokemon] was caught in
* @param date A [LocalDate] of the real life date the [Pokemon] was caught
* @param level The level the [Pokemon] was when caught
*/
data class PokemonMetData(
val biome: Holder<Biome>,
val date: LocalDate,
val level: Int
) {
companion object {
private val LOCAL_DATE_CODEC: Codec<LocalDate> = Codec.STRING.xmap(
LocalDate::parse,
LocalDate::toString
)
val CODEC: Codec<PokemonMetData> = RecordCodecBuilder.create { instance ->
instance.group(
Biome.CODEC
.fieldOf("biome")
.forGetter { it.biome },
LOCAL_DATE_CODEC
.fieldOf("date")
.forGetter { it.date },
Codec.INT
.fieldOf("level")
.forGetter { it.level }
).apply(instance) { biome, date, level ->
PokemonMetData(
biome = biome,
date = date,
level = level
)
}
}
}
}
@@ -173,7 +173,6 @@ class Species : ShowdownIdentifiable {
.addStandardFunctions()
.addSpeciesFunctions(this)
var silenceStepSounds = false
fun initialize() {
Cobblemon.statProvider.provide(this)
@@ -257,7 +256,6 @@ class Species : ShowdownIdentifiable {
}
this.riding.encode(buffer)
buffer.writeBoolean(this.silenceStepSounds)
}
fun decode(buffer: RegistryFriendlyByteBuf) {
@@ -301,7 +299,6 @@ class Species : ShowdownIdentifiable {
}
}
this.riding = RidingProperties.decode(buffer)
this.silenceStepSounds = buffer.readBoolean()
this.initialize()
}
@@ -86,6 +86,7 @@ object DataKeys {
const val POKEMON_ORIGINAL_TRAINER_NAME = "PokemonOriginalTrainerName"
const val POKEMON_ORIGINAL_TRAINER_TYPE = "PokemonOriginalTrainerType"
const val POKEMON_ORIGINAL_TRAINER_FRIENDSHIP = "PokemonOriginalTrainerFriendship"
const val POKEMON_MET_DATA = "PokemonMetData"
const val POKEMON_PROPERTIES_MOVES = "Moves"
const val POKEMON_PROPERTIES_HELDITEM = "HeldItem"
@@ -234,11 +234,11 @@ fun Entity.isDusk(): Boolean {
}
fun Entity.isStandingOn(blocks: Set<String>, depth: Int = 2): Boolean {
for (currentDepth in 0..depth) {
val bellowBlockPos = blockPosBelowThatAffectsMyMovement.below(currentDepth)
for (currentDepth in 1..depth) {
val bellowBlockPos = blockPosition().below(currentDepth)
val blockState = level().getBlockState(bellowBlockPos)
if (blockState.isAir) continue
if (blockState.isAir || !blockState.isCollisionShapeFullBlock(level(), bellowBlockPos)) continue
val elementOrTags = ExtraCodecs.TAG_OR_ELEMENT_ID.listOf().decode(JavaOps.INSTANCE, blocks.toList()).result().get().first
elementOrTags.forEach {
@@ -8,25 +8,23 @@
package com.cobblemon.mod.common.util.codec.internal
import com.cobblemon.mod.common.api.mark.Marks
import com.cobblemon.mod.common.api.riding.stats.RidingStat
import com.cobblemon.mod.common.client.settings.ServerSettings
import com.cobblemon.mod.common.pokemon.OriginalTrainerType
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.PokemonMetData
import com.cobblemon.mod.common.util.DataKeys
import com.mojang.serialization.Codec
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.ItemStack
import java.util.*
internal data class ClientPokemonP4(
val originalTrainerFriendship: Optional<Int>
val originalTrainerFriendship: Optional<Int>,
val pokemonMetData: Optional<PokemonMetData>
) : Partial<Pokemon> {
override fun into(other: Pokemon): Pokemon {
this.originalTrainerFriendship.ifPresent { other.originalTrainerFriendship = it }
other.metData = this.pokemonMetData.orElse(null)
return other
}
@@ -36,12 +34,18 @@ internal data class ClientPokemonP4(
*/
internal val CODEC: MapCodec<ClientPokemonP4> = RecordCodecBuilder.mapCodec { instance ->
instance.group(
Codec.INT.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER_FRIENDSHIP).forGetter(ClientPokemonP4::originalTrainerFriendship)
).apply(instance, ::ClientPokemonP4)
Codec.INT.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER_FRIENDSHIP).forGetter(ClientPokemonP4::originalTrainerFriendship),
PokemonMetData.CODEC.optionalFieldOf(DataKeys.POKEMON_MET_DATA).forGetter(ClientPokemonP4::pokemonMetData)
).apply(instance) {
originalTrainerFriendship, pokemonMetData -> ClientPokemonP4(
originalTrainerFriendship, pokemonMetData
)
}
}
internal fun from(pokemon: Pokemon): ClientPokemonP4 = ClientPokemonP4(
Optional.ofNullable(pokemon.originalTrainerFriendship)
Optional.ofNullable(pokemon.originalTrainerFriendship),
Optional.ofNullable(pokemon.metData)
)
}
}
@@ -9,6 +9,7 @@
package com.cobblemon.mod.common.util.codec.internal
import com.cobblemon.mod.common.pokemon.Pokemon
import com.cobblemon.mod.common.pokemon.PokemonMetData
import com.cobblemon.mod.common.util.DataKeys
import com.mojang.serialization.Codec
import com.mojang.serialization.MapCodec
@@ -16,28 +17,32 @@ import com.mojang.serialization.codecs.RecordCodecBuilder
import java.util.*
internal data class PokemonP4(
val originalTrainerFriendship: Optional<Int>
val originalTrainerFriendship: Optional<Int>,
val pokemonMetData: Optional<PokemonMetData>
) : Partial<Pokemon> {
override fun into(other: Pokemon): Pokemon {
this.originalTrainerFriendship.ifPresent { other.originalTrainerFriendship = it }
other.refreshOriginalTrainer()
other.metData = this.pokemonMetData.orElse(null)
return other
}
companion object {
internal val CODEC: MapCodec<PokemonP4> = RecordCodecBuilder.mapCodec { instance ->
instance.group(
Codec.INT.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER_FRIENDSHIP).forGetter(PokemonP4::originalTrainerFriendship)
Codec.INT.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER_FRIENDSHIP).forGetter(PokemonP4::originalTrainerFriendship),
PokemonMetData.CODEC.optionalFieldOf(DataKeys.POKEMON_MET_DATA).forGetter(PokemonP4::pokemonMetData)
).apply(instance) {
originalTrainerFriendship -> PokemonP4(
originalTrainerFriendship
originalTrainerFriendship, pokemonMetData -> PokemonP4(
originalTrainerFriendship, pokemonMetData
)
}
}
internal fun from(pokemon: Pokemon): PokemonP4 = PokemonP4(
Optional.ofNullable(pokemon.originalTrainerFriendship)
Optional.ofNullable(pokemon.originalTrainerFriendship),
Optional.ofNullable(pokemon.metData)
)
}
}
@@ -27,7 +27,5 @@ object CobblemonGameRules {
@JvmField
val HEALERS_HEAL_PC: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("healersHealPC", GameRules.Category.MISC, BooleanRuleInvoker.`cobblemon$create`(false))
@JvmField
val HEALER_SET_SPAWN: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("healersSetSpawn", GameRules.Category.MISC, BooleanRuleInvoker.`cobblemon$create`(false))
@JvmField
val DO_POKEMON_PREDATION: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("doPokemonPredation", GameRules.Category.MOBS, BooleanRuleInvoker.`cobblemon$create`(true))
}
@@ -1815,12 +1815,6 @@
"wings_open": {
"scale": 0
}
},
"timeline": {
"0.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
"0.5": "q.run_molang('cobblemon:stepsound_claw_medium');",
"1.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
"1.5": "q.run_molang('cobblemon:stepsound_claw_medium');"
}
},
"animation.pidgeot.mount_ground_idle": {
@@ -3637,12 +3631,6 @@
"wings_open": {
"scale": 0
}
},
"timeline": {
"0.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
"0.5": "q.run_molang('cobblemon:stepsound_claw_medium');",
"1.0": "q.run_molang('cobblemon:stepsound_claw_medium');",
"1.5": "q.run_molang('cobblemon:stepsound_claw_medium');"
}
},
"animation.pidgeot.ride_ground_walk": {
@@ -1682,12 +1682,6 @@
"1.3333": [10, 9, 0]
}
}
},
"timeline": {
"0.0": "q.run_molang('cobblemon:stepsound_standard_medium');",
"0.4583": "q.run_molang('cobblemon:stepsound_standard_medium');",
"0.6667": "q.run_molang('cobblemon:stepsound_standard_medium');",
"1.125": "q.run_molang('cobblemon:stepsound_standard_medium');"
}
},
"animation.arcanine.ride_ground_walk": {
@@ -2645,12 +2639,6 @@
"chest_fluff_right": {
"rotation": [5, "-22.5+math.cos(q.anim_time*90*8-120)*15", "-math.sin(q.anim_time*90*8-120)*3"]
}
},
"timeline": {
"0.125": "q.run_molang('cobblemon:stepsound_standard_medium');",
"0.2083": "q.run_molang('cobblemon:stepsound_standard_large');",
"0.2917": "q.run_molang('cobblemon:stepsound_standard_medium');",
"0.375": "q.run_molang('cobblemon:stepsound_standard_medium');"
}
},
"animation.arcanine.ride_ground_run": {
@@ -4173,101 +4161,41 @@
"eye_left": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {
"pre": [0, 0, 0],
"post": [-0.1, 0, 0.1]
},
"0.5": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0, 0.1]
},
"1.6667": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
"0.5": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
"1.6667": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eye_right": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {
"pre": [0, 0, 0],
"post": [0.1, 0, 0.1]
},
"0.5": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0, 0.1]
},
"1.6667": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
"0.5": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
"1.6667": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"0.5": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"1.6667": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"0.5": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"1.6667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"0.5": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"1.6667": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"0.5": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"1.6667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"jaw": {
@@ -4895,101 +4823,41 @@
"eye_left": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {
"pre": [0, 0, 0],
"post": [-0.1, 0, 0.1]
},
"0.5": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0, 0.1]
},
"1.6667": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
"0.5": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, 0.1]},
"1.6667": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eye_right": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {
"pre": [0, 0, 0],
"post": [0.1, 0, 0.1]
},
"0.5": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0, 0.1]
},
"1.6667": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
"0.5": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, 0.1]},
"1.6667": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"0.5": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"1.6667": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"0.5": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"1.6667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.1667": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"0.5": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
},
"1.4167": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"1.6667": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
},
"2.5": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"0.5": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
"1.4167": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"1.6667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
"2.5": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"jaw": {
@@ -5419,20 +5287,14 @@
"position": {
"0.0": [-0.1, 0, 0.1],
"0.125": [-0.1, 0, 0.1],
"0.1667": {
"pre": [-0.1, 0, 0.1],
"post": [0, 0, 0]
}
"0.1667": {"pre": [-0.1, 0, 0.1], "post": [0, 0, 0]}
}
},
"eye_right": {
"position": {
"0.0": [0.1, 0, 0.1],
"0.125": [0.1, 0, 0.1],
"0.1667": {
"pre": [0.1, 0, 0.1],
"post": [0, 0, 0]
}
"0.1667": {"pre": [0.1, 0, 0.1], "post": [0, 0, 0]}
}
}
}
@@ -5629,95 +5491,47 @@
"eye_left": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.2, 0, 0.1]
},
"0.3333": {
"pre": [-0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eye_right": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [0.2, 0, 0.1]
},
"0.3333": {
"pre": [0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.2, 0, 0.1]
},
"0.3333": {
"pre": [-0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [0.2, 0, 0.1]
},
"0.3333": {
"pre": [0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_left_hurt": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"0.3333": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"0.3333": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"eyelid_right_hurt": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"0.3333": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"0.3333": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"jaw": {
@@ -6424,95 +6238,47 @@
"eye_left": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.2, 0, 0.1]
},
"0.3333": {
"pre": [-0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eye_right": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [0.2, 0, 0.1]
},
"0.3333": {
"pre": [0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.2, 0, 0.1]
},
"0.3333": {
"pre": [-0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [-0.2, 0, 0.1]},
"0.3333": {"pre": [-0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [0.2, 0, 0.1]
},
"0.3333": {
"pre": [0.2, 0, 0.1],
"post": [0, 0, 0]
},
"1.25": {
"pre": [0, 0, 0],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [0.2, 0, 0.1]},
"0.3333": {"pre": [0.2, 0, 0.1], "post": [0, 0, 0]},
"1.25": {"pre": [0, 0, 0], "post": [0, 0, 0]}
}
},
"eyelid_left_hurt": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"0.3333": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"0.3333": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"eyelid_right_hurt": {
"position": {
"0.0": [0, 0, 0],
"0.0417": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"0.3333": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
"0.0417": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"0.3333": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"jaw": {
@@ -3150,10 +3150,6 @@
"locator_seat_2": {
"rotation": [45, 0, 0]
}
},
"timeline": {
"0.5": "q.run_molang('cobblemon:stepsound_claw_large');",
"1.5": "q.run_molang('cobblemon:stepsound_claw_large');"
}
},
"animation.corviknight.ground_run": {
@@ -4477,10 +4473,6 @@
"locator_seat_2": {
"rotation": [25, 0, 0]
}
},
"timeline": {
"0.3333": "q.run_molang('cobblemon:stepsound_claw_large');",
"0.8333": "q.run_molang('cobblemon:stepsound_claw_large');"
}
},
"animation.corviknight.air_idle": {
@@ -566,12 +566,6 @@
"1.5": [0, 0.2, 0]
}
}
},
"timeline": {
"0.5417": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.7083": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"1.2917": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"1.4583": "q.run_molang('cobblemon:stepsound_hoof_medium');"
}
},
"animation.wyrdeer.sleep": {
@@ -786,27 +780,15 @@
"eyelid_right": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"0.5": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
"0.25": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"0.5": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"0.25": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"0.5": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
"0.25": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"0.5": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"ear_right": {
@@ -1204,36 +1186,18 @@
"position": {
"0.0": [0, 0, 0],
"1.5833": [-0.1, 0, -0.1],
"1.6667": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
},
"3.0": {
"pre": [0, 0, 0],
"post": [-0.1, 0, -0.1]
},
"3.125": {
"pre": [-0.1, 0, -0.1],
"post": [0, 0, 0]
}
"1.6667": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]},
"3.0": {"pre": [0, 0, 0], "post": [-0.1, 0, -0.1]},
"3.125": {"pre": [-0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"eyelid_left": {
"position": {
"0.0": [0, 0, 0],
"1.5833": [0.1, 0, -0.1],
"1.6667": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
},
"3.0": {
"pre": [0, 0, 0],
"post": [0.1, 0, -0.1]
},
"3.125": {
"pre": [0.1, 0, -0.1],
"post": [0, 0, 0]
}
"1.6667": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]},
"3.0": {"pre": [0, 0, 0], "post": [0.1, 0, -0.1]},
"3.125": {"pre": [0.1, 0, -0.1], "post": [0, 0, 0]}
}
},
"tail": {
@@ -2240,16 +2204,6 @@
"1.1667": [0, 0, 0]
}
}
},
"timeline": {
"0.2083": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.2917": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.375": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.4583": "q.run_molang('cobblemon:stepsound_hoof_large');",
"0.7917": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.875": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"0.9583": "q.run_molang('cobblemon:stepsound_hoof_medium');",
"1.0417": "q.run_molang('cobblemon:stepsound_hoof_large');"
}
},
"animation.wyrdeer.ride_jump": {
@@ -1267,6 +1267,8 @@
"cobblemon.ui.info.ability": "Ability",
"cobblemon.ui.info.experience_points": "Exp. Points",
"cobblemon.ui.info.to_next_level": "To Next Lv.",
"cobblemon.ui.info.met_data": "Met in %1$s on %2$s/%3$s/%4$s at Lv.%5$s",
"cobblemon.ui.info.met_data_unavailable": "Met a long time ago",
"cobblemon.ui.trade": "Trade",
"cobblemon.trade.expired.sender": "Your request to trade with %1$s has timed out!",
"cobblemon.trade.expired.receiver": "The trade request from %1$s has timed out!",
@@ -1299,7 +1301,6 @@
"cobblemon.ui.pc.filter.tooltip": "Format: pikachu shiny held_item lvl=1...",
"cobblemon.ui.pc.options": "Options",
"cobblemon.ui.pc.release": "Release",
"cobblemon.ui.pc.release_all": "Release All",
"cobblemon.ui.sort.name": "Sort by name",
"cobblemon.ui.sort.level": "Sort by level",
"cobblemon.ui.sort.pokedex_number": "Sort by Pokédex number",
@@ -2031,850 +2031,6 @@
{ "name": "cobblemon:animation/wings/steel_wing_flap_medium_8", "volume": 0.25 }
]
},
"stepsound.dirt.standard.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/dirt/standard/large/stepsound_dirt_standard_large_1", "volume": 0.2 },
{ "name": "cobblemon:stepsound/dirt/standard/large/stepsound_dirt_standard_large_2", "volume": 0.2 },
{ "name": "cobblemon:stepsound/dirt/standard/large/stepsound_dirt_standard_large_3", "volume": 0.2 },
{ "name": "cobblemon:stepsound/dirt/standard/large/stepsound_dirt_standard_large_4", "volume": 0.2 },
{ "name": "cobblemon:stepsound/dirt/standard/large/stepsound_dirt_standard_large_5", "volume": 0.2 },
{ "name": "cobblemon:stepsound/dirt/standard/large/stepsound_dirt_standard_large_6", "volume": 0.2 },
{ "name": "cobblemon:stepsound/dirt/standard/large/stepsound_dirt_standard_large_7", "volume": 0.2 },
{ "name": "cobblemon:stepsound/dirt/standard/large/stepsound_dirt_standard_large_8", "volume": 0.2 }
]
},
"stepsound.dirt.standard.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/dirt/standard/medium/stepsound_dirt_standard_medium_1", "volume": 0.1 },
{ "name": "cobblemon:stepsound/dirt/standard/medium/stepsound_dirt_standard_medium_2", "volume": 0.1 },
{ "name": "cobblemon:stepsound/dirt/standard/medium/stepsound_dirt_standard_medium_3", "volume": 0.1 },
{ "name": "cobblemon:stepsound/dirt/standard/medium/stepsound_dirt_standard_medium_4", "volume": 0.1 },
{ "name": "cobblemon:stepsound/dirt/standard/medium/stepsound_dirt_standard_medium_5", "volume": 0.1 },
{ "name": "cobblemon:stepsound/dirt/standard/medium/stepsound_dirt_standard_medium_6", "volume": 0.1 },
{ "name": "cobblemon:stepsound/dirt/standard/medium/stepsound_dirt_standard_medium_7", "volume": 0.1 },
{ "name": "cobblemon:stepsound/dirt/standard/medium/stepsound_dirt_standard_medium_8", "volume": 0.1 }
]
},
"stepsound.grass.standard.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/grass/standard/large/stepsound_grass_standard_large_1", "volume": 0.2 },
{ "name": "cobblemon:stepsound/grass/standard/large/stepsound_grass_standard_large_2", "volume": 0.2 },
{ "name": "cobblemon:stepsound/grass/standard/large/stepsound_grass_standard_large_3", "volume": 0.2 },
{ "name": "cobblemon:stepsound/grass/standard/large/stepsound_grass_standard_large_4", "volume": 0.2 },
{ "name": "cobblemon:stepsound/grass/standard/large/stepsound_grass_standard_large_5", "volume": 0.2 },
{ "name": "cobblemon:stepsound/grass/standard/large/stepsound_grass_standard_large_6", "volume": 0.2 },
{ "name": "cobblemon:stepsound/grass/standard/large/stepsound_grass_standard_large_7", "volume": 0.2 },
{ "name": "cobblemon:stepsound/grass/standard/large/stepsound_grass_standard_large_8", "volume": 0.2 }
]
},
"stepsound.grass.standard.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/grass/standard/medium/stepsound_grass_standard_medium_1", "volume": 0.1 },
{ "name": "cobblemon:stepsound/grass/standard/medium/stepsound_grass_standard_medium_2", "volume": 0.1 },
{ "name": "cobblemon:stepsound/grass/standard/medium/stepsound_grass_standard_medium_3", "volume": 0.1 },
{ "name": "cobblemon:stepsound/grass/standard/medium/stepsound_grass_standard_medium_4", "volume": 0.1 },
{ "name": "cobblemon:stepsound/grass/standard/medium/stepsound_grass_standard_medium_5", "volume": 0.1 },
{ "name": "cobblemon:stepsound/grass/standard/medium/stepsound_grass_standard_medium_6", "volume": 0.1 },
{ "name": "cobblemon:stepsound/grass/standard/medium/stepsound_grass_standard_medium_7", "volume": 0.1 },
{ "name": "cobblemon:stepsound/grass/standard/medium/stepsound_grass_standard_medium_8", "volume": 0.1 }
]
},
"stepsound.stone.standard.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/stone/standard/large/stepsound_stone_standard_large_1", "volume": 0.2 },
{ "name": "cobblemon:stepsound/stone/standard/large/stepsound_stone_standard_large_2", "volume": 0.2 },
{ "name": "cobblemon:stepsound/stone/standard/large/stepsound_stone_standard_large_3", "volume": 0.2 },
{ "name": "cobblemon:stepsound/stone/standard/large/stepsound_stone_standard_large_4", "volume": 0.2 },
{ "name": "cobblemon:stepsound/stone/standard/large/stepsound_stone_standard_large_5", "volume": 0.2 },
{ "name": "cobblemon:stepsound/stone/standard/large/stepsound_stone_standard_large_6", "volume": 0.2 },
{ "name": "cobblemon:stepsound/stone/standard/large/stepsound_stone_standard_large_7", "volume": 0.2 },
{ "name": "cobblemon:stepsound/stone/standard/large/stepsound_stone_standard_large_8", "volume": 0.2 }
]
},
"stepsound.stone.standard.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/stone/standard/medium/stepsound_stone_standard_medium_1", "volume": 0.1 },
{ "name": "cobblemon:stepsound/stone/standard/medium/stepsound_stone_standard_medium_2", "volume": 0.1 },
{ "name": "cobblemon:stepsound/stone/standard/medium/stepsound_stone_standard_medium_3", "volume": 0.1 },
{ "name": "cobblemon:stepsound/stone/standard/medium/stepsound_stone_standard_medium_4", "volume": 0.1 },
{ "name": "cobblemon:stepsound/stone/standard/medium/stepsound_stone_standard_medium_5", "volume": 0.1 },
{ "name": "cobblemon:stepsound/stone/standard/medium/stepsound_stone_standard_medium_6", "volume": 0.1 },
{ "name": "cobblemon:stepsound/stone/standard/medium/stepsound_stone_standard_medium_7", "volume": 0.1 },
{ "name": "cobblemon:stepsound/stone/standard/medium/stepsound_stone_standard_medium_8", "volume": 0.1 }
]
},
"stepsound.sand.standard.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/sand/standard/large/stepsound_sand_standard_large_1", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/standard/large/stepsound_sand_standard_large_2", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/standard/large/stepsound_sand_standard_large_3", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/standard/large/stepsound_sand_standard_large_4", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/standard/large/stepsound_sand_standard_large_5", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/standard/large/stepsound_sand_standard_large_6", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/standard/large/stepsound_sand_standard_large_7", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/standard/large/stepsound_sand_standard_large_8", "volume": 0.2 }
]
},
"stepsound.sand.standard.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/sand/standard/medium/stepsound_sand_standard_medium_1", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/standard/medium/stepsound_sand_standard_medium_2", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/standard/medium/stepsound_sand_standard_medium_3", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/standard/medium/stepsound_sand_standard_medium_4", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/standard/medium/stepsound_sand_standard_medium_5", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/standard/medium/stepsound_sand_standard_medium_6", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/standard/medium/stepsound_sand_standard_medium_7", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/standard/medium/stepsound_sand_standard_medium_8", "volume": 0.1 }
]
},
"stepsound.snow.standard.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/snow/standard/large/stepsound_snow_standard_large_1", "volume": 0.18 },
{ "name": "cobblemon:stepsound/snow/standard/large/stepsound_snow_standard_large_2", "volume": 0.18 },
{ "name": "cobblemon:stepsound/snow/standard/large/stepsound_snow_standard_large_3", "volume": 0.18 },
{ "name": "cobblemon:stepsound/snow/standard/large/stepsound_snow_standard_large_4", "volume": 0.18 },
{ "name": "cobblemon:stepsound/snow/standard/large/stepsound_snow_standard_large_5", "volume": 0.18 },
{ "name": "cobblemon:stepsound/snow/standard/large/stepsound_snow_standard_large_6", "volume": 0.18 },
{ "name": "cobblemon:stepsound/snow/standard/large/stepsound_snow_standard_large_7", "volume": 0.18 },
{ "name": "cobblemon:stepsound/snow/standard/large/stepsound_snow_standard_large_8", "volume": 0.18 }
]
},
"stepsound.snow.standard.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/snow/standard/medium/stepsound_snow_standard_medium_1", "volume": 0.08 },
{ "name": "cobblemon:stepsound/snow/standard/medium/stepsound_snow_standard_medium_2", "volume": 0.08 },
{ "name": "cobblemon:stepsound/snow/standard/medium/stepsound_snow_standard_medium_3", "volume": 0.08 },
{ "name": "cobblemon:stepsound/snow/standard/medium/stepsound_snow_standard_medium_4", "volume": 0.08 },
{ "name": "cobblemon:stepsound/snow/standard/medium/stepsound_snow_standard_medium_5", "volume": 0.08 },
{ "name": "cobblemon:stepsound/snow/standard/medium/stepsound_snow_standard_medium_6", "volume": 0.08 },
{ "name": "cobblemon:stepsound/snow/standard/medium/stepsound_snow_standard_medium_7", "volume": 0.08 },
{ "name": "cobblemon:stepsound/snow/standard/medium/stepsound_snow_standard_medium_8", "volume": 0.08 }
]
},
"stepsound.wood.standard.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/wood/standard/large/stepsound_wood_standard_large_1", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/standard/large/stepsound_wood_standard_large_2", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/standard/large/stepsound_wood_standard_large_3", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/standard/large/stepsound_wood_standard_large_4", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/standard/large/stepsound_wood_standard_large_5", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/standard/large/stepsound_wood_standard_large_6", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/standard/large/stepsound_wood_standard_large_7", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/standard/large/stepsound_wood_standard_large_8", "volume": 0.25 }
]
},
"stepsound.wood.standard.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/wood/standard/medium/stepsound_wood_standard_medium_1", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/standard/medium/stepsound_wood_standard_medium_2", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/standard/medium/stepsound_wood_standard_medium_3", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/standard/medium/stepsound_wood_standard_medium_4", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/standard/medium/stepsound_wood_standard_medium_5", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/standard/medium/stepsound_wood_standard_medium_6", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/standard/medium/stepsound_wood_standard_medium_7", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/standard/medium/stepsound_wood_standard_medium_8", "volume": 0.15 }
]
},
"stepsound.mud.standard.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/mud/standard/large/stepsound_mud_standard_large_1", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/standard/large/stepsound_mud_standard_large_2", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/standard/large/stepsound_mud_standard_large_3", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/standard/large/stepsound_mud_standard_large_4", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/standard/large/stepsound_mud_standard_large_5", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/standard/large/stepsound_mud_standard_large_6", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/standard/large/stepsound_mud_standard_large_7", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/standard/large/stepsound_mud_standard_large_8", "volume": 0.22 }
]
},
"stepsound.mud.standard.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/mud/standard/medium/stepsound_mud_standard_medium_1", "volume": 0.14 },
{ "name": "cobblemon:stepsound/mud/standard/medium/stepsound_mud_standard_medium_2", "volume": 0.14 },
{ "name": "cobblemon:stepsound/mud/standard/medium/stepsound_mud_standard_medium_3", "volume": 0.14 },
{ "name": "cobblemon:stepsound/mud/standard/medium/stepsound_mud_standard_medium_4", "volume": 0.14 },
{ "name": "cobblemon:stepsound/mud/standard/medium/stepsound_mud_standard_medium_5", "volume": 0.14 },
{ "name": "cobblemon:stepsound/mud/standard/medium/stepsound_mud_standard_medium_6", "volume": 0.14 },
{ "name": "cobblemon:stepsound/mud/standard/medium/stepsound_mud_standard_medium_7", "volume": 0.14 },
{ "name": "cobblemon:stepsound/mud/standard/medium/stepsound_mud_standard_medium_8", "volume": 0.14 }
]
},
"stepsound.glass.standard.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/glass/standard/large/stepsound_glass_standard_large_1", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/standard/large/stepsound_glass_standard_large_2", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/standard/large/stepsound_glass_standard_large_3", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/standard/large/stepsound_glass_standard_large_4", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/standard/large/stepsound_glass_standard_large_5", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/standard/large/stepsound_glass_standard_large_6", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/standard/large/stepsound_glass_standard_large_7", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/standard/large/stepsound_glass_standard_large_8", "volume": 0.2 }
]
},
"stepsound.glass.standard.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/glass/standard/medium/stepsound_glass_standard_medium_1", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/standard/medium/stepsound_glass_standard_medium_2", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/standard/medium/stepsound_glass_standard_medium_3", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/standard/medium/stepsound_glass_standard_medium_4", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/standard/medium/stepsound_glass_standard_medium_5", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/standard/medium/stepsound_glass_standard_medium_6", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/standard/medium/stepsound_glass_standard_medium_7", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/standard/medium/stepsound_glass_standard_medium_8", "volume": 0.1 }
]
},
"stepsound.metal.standard.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/metal/standard/large/stepsound_metal_standard_large_1", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/standard/large/stepsound_metal_standard_large_2", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/standard/large/stepsound_metal_standard_large_3", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/standard/large/stepsound_metal_standard_large_4", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/standard/large/stepsound_metal_standard_large_5", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/standard/large/stepsound_metal_standard_large_6", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/standard/large/stepsound_metal_standard_large_7", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/standard/large/stepsound_metal_standard_large_8", "volume": 0.2 }
]
},
"stepsound.metal.standard.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/metal/standard/medium/stepsound_metal_standard_medium_1", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/standard/medium/stepsound_metal_standard_medium_2", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/standard/medium/stepsound_metal_standard_medium_3", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/standard/medium/stepsound_metal_standard_medium_4", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/standard/medium/stepsound_metal_standard_medium_5", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/standard/medium/stepsound_metal_standard_medium_6", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/standard/medium/stepsound_metal_standard_medium_7", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/standard/medium/stepsound_metal_standard_medium_8", "volume": 0.1 }
]
},
"stepsound.dirt.hoof.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/dirt/hoof/large/stepsound_dirt_hoof_large_1", "volume": 0.25 },
{ "name": "cobblemon:stepsound/dirt/hoof/large/stepsound_dirt_hoof_large_2", "volume": 0.25 },
{ "name": "cobblemon:stepsound/dirt/hoof/large/stepsound_dirt_hoof_large_3", "volume": 0.25 },
{ "name": "cobblemon:stepsound/dirt/hoof/large/stepsound_dirt_hoof_large_4", "volume": 0.25 },
{ "name": "cobblemon:stepsound/dirt/hoof/large/stepsound_dirt_hoof_large_5", "volume": 0.25 },
{ "name": "cobblemon:stepsound/dirt/hoof/large/stepsound_dirt_hoof_large_6", "volume": 0.25 },
{ "name": "cobblemon:stepsound/dirt/hoof/large/stepsound_dirt_hoof_large_7", "volume": 0.25 },
{ "name": "cobblemon:stepsound/dirt/hoof/large/stepsound_dirt_hoof_large_8", "volume": 0.25 }
]
},
"stepsound.dirt.hoof.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/dirt/hoof/medium/stepsound_dirt_hoof_medium_1", "volume": 0.15 },
{ "name": "cobblemon:stepsound/dirt/hoof/medium/stepsound_dirt_hoof_medium_2", "volume": 0.15 },
{ "name": "cobblemon:stepsound/dirt/hoof/medium/stepsound_dirt_hoof_medium_3", "volume": 0.15 },
{ "name": "cobblemon:stepsound/dirt/hoof/medium/stepsound_dirt_hoof_medium_4", "volume": 0.15 },
{ "name": "cobblemon:stepsound/dirt/hoof/medium/stepsound_dirt_hoof_medium_5", "volume": 0.15 },
{ "name": "cobblemon:stepsound/dirt/hoof/medium/stepsound_dirt_hoof_medium_6", "volume": 0.15 },
{ "name": "cobblemon:stepsound/dirt/hoof/medium/stepsound_dirt_hoof_medium_7", "volume": 0.15 },
{ "name": "cobblemon:stepsound/dirt/hoof/medium/stepsound_dirt_hoof_medium_8", "volume": 0.15 }
]
},
"stepsound.grass.hoof.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/grass/hoof/large/stepsound_grass_hoof_large_1", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/hoof/large/stepsound_grass_hoof_large_2", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/hoof/large/stepsound_grass_hoof_large_3", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/hoof/large/stepsound_grass_hoof_large_4", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/hoof/large/stepsound_grass_hoof_large_5", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/hoof/large/stepsound_grass_hoof_large_6", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/hoof/large/stepsound_grass_hoof_large_7", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/hoof/large/stepsound_grass_hoof_large_8", "volume": 0.25 }
]
},
"stepsound.grass.hoof.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/grass/hoof/medium/stepsound_grass_hoof_medium_1", "volume": 0.15 },
{ "name": "cobblemon:stepsound/grass/hoof/medium/stepsound_grass_hoof_medium_2", "volume": 0.15 },
{ "name": "cobblemon:stepsound/grass/hoof/medium/stepsound_grass_hoof_medium_3", "volume": 0.15 },
{ "name": "cobblemon:stepsound/grass/hoof/medium/stepsound_grass_hoof_medium_4", "volume": 0.15 },
{ "name": "cobblemon:stepsound/grass/hoof/medium/stepsound_grass_hoof_medium_5", "volume": 0.15 },
{ "name": "cobblemon:stepsound/grass/hoof/medium/stepsound_grass_hoof_medium_6", "volume": 0.15 },
{ "name": "cobblemon:stepsound/grass/hoof/medium/stepsound_grass_hoof_medium_7", "volume": 0.15 },
{ "name": "cobblemon:stepsound/grass/hoof/medium/stepsound_grass_hoof_medium_8", "volume": 0.15 }
]
},
"stepsound.stone.hoof.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/stone/hoof/large/stepsound_stone_hoof_large_1", "volume": 0.25 },
{ "name": "cobblemon:stepsound/stone/hoof/large/stepsound_stone_hoof_large_2", "volume": 0.25 },
{ "name": "cobblemon:stepsound/stone/hoof/large/stepsound_stone_hoof_large_3", "volume": 0.25 },
{ "name": "cobblemon:stepsound/stone/hoof/large/stepsound_stone_hoof_large_4", "volume": 0.25 },
{ "name": "cobblemon:stepsound/stone/hoof/large/stepsound_stone_hoof_large_5", "volume": 0.25 },
{ "name": "cobblemon:stepsound/stone/hoof/large/stepsound_stone_hoof_large_6", "volume": 0.25 },
{ "name": "cobblemon:stepsound/stone/hoof/large/stepsound_stone_hoof_large_7", "volume": 0.25 },
{ "name": "cobblemon:stepsound/stone/hoof/large/stepsound_stone_hoof_large_8", "volume": 0.25 }
]
},
"stepsound.stone.hoof.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/stone/hoof/medium/stepsound_stone_hoof_medium_1", "volume": 0.15 },
{ "name": "cobblemon:stepsound/stone/hoof/medium/stepsound_stone_hoof_medium_2", "volume": 0.15 },
{ "name": "cobblemon:stepsound/stone/hoof/medium/stepsound_stone_hoof_medium_3", "volume": 0.15 },
{ "name": "cobblemon:stepsound/stone/hoof/medium/stepsound_stone_hoof_medium_4", "volume": 0.15 },
{ "name": "cobblemon:stepsound/stone/hoof/medium/stepsound_stone_hoof_medium_5", "volume": 0.15 },
{ "name": "cobblemon:stepsound/stone/hoof/medium/stepsound_stone_hoof_medium_6", "volume": 0.15 },
{ "name": "cobblemon:stepsound/stone/hoof/medium/stepsound_stone_hoof_medium_7", "volume": 0.15 },
{ "name": "cobblemon:stepsound/stone/hoof/medium/stepsound_stone_hoof_medium_8", "volume": 0.15 }
]
},
"stepsound.sand.hoof.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/sand/hoof/large/stepsound_sand_hoof_large_1", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/hoof/large/stepsound_sand_hoof_large_2", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/hoof/large/stepsound_sand_hoof_large_3", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/hoof/large/stepsound_sand_hoof_large_4", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/hoof/large/stepsound_sand_hoof_large_5", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/hoof/large/stepsound_sand_hoof_large_6", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/hoof/large/stepsound_sand_hoof_large_7", "volume": 0.2 },
{ "name": "cobblemon:stepsound/sand/hoof/large/stepsound_sand_hoof_large_8", "volume": 0.2 }
]
},
"stepsound.sand.hoof.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/sand/hoof/medium/stepsound_sand_hoof_medium_1", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/hoof/medium/stepsound_sand_hoof_medium_2", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/hoof/medium/stepsound_sand_hoof_medium_3", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/hoof/medium/stepsound_sand_hoof_medium_4", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/hoof/medium/stepsound_sand_hoof_medium_5", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/hoof/medium/stepsound_sand_hoof_medium_6", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/hoof/medium/stepsound_sand_hoof_medium_7", "volume": 0.1 },
{ "name": "cobblemon:stepsound/sand/hoof/medium/stepsound_sand_hoof_medium_8", "volume": 0.1 }
]
},
"stepsound.snow.hoof.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/snow/hoof/large/stepsound_snow_hoof_large_1", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/hoof/large/stepsound_snow_hoof_large_2", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/hoof/large/stepsound_snow_hoof_large_3", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/hoof/large/stepsound_snow_hoof_large_4", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/hoof/large/stepsound_snow_hoof_large_5", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/hoof/large/stepsound_snow_hoof_large_6", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/hoof/large/stepsound_snow_hoof_large_7", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/hoof/large/stepsound_snow_hoof_large_8", "volume": 0.22 }
]
},
"stepsound.snow.hoof.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/snow/hoof/medium/stepsound_snow_hoof_medium_1", "volume": 0.12 },
{ "name": "cobblemon:stepsound/snow/hoof/medium/stepsound_snow_hoof_medium_2", "volume": 0.12 },
{ "name": "cobblemon:stepsound/snow/hoof/medium/stepsound_snow_hoof_medium_3", "volume": 0.12 },
{ "name": "cobblemon:stepsound/snow/hoof/medium/stepsound_snow_hoof_medium_4", "volume": 0.12 },
{ "name": "cobblemon:stepsound/snow/hoof/medium/stepsound_snow_hoof_medium_5", "volume": 0.12 },
{ "name": "cobblemon:stepsound/snow/hoof/medium/stepsound_snow_hoof_medium_6", "volume": 0.12 },
{ "name": "cobblemon:stepsound/snow/hoof/medium/stepsound_snow_hoof_medium_7", "volume": 0.12 },
{ "name": "cobblemon:stepsound/snow/hoof/medium/stepsound_snow_hoof_medium_8", "volume": 0.12 }
]
},
"stepsound.wood.hoof.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/wood/hoof/large/stepsound_wood_hoof_large_1", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/hoof/large/stepsound_wood_hoof_large_2", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/hoof/large/stepsound_wood_hoof_large_3", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/hoof/large/stepsound_wood_hoof_large_4", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/hoof/large/stepsound_wood_hoof_large_5", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/hoof/large/stepsound_wood_hoof_large_6", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/hoof/large/stepsound_wood_hoof_large_7", "volume": 0.25 },
{ "name": "cobblemon:stepsound/wood/hoof/large/stepsound_wood_hoof_large_8", "volume": 0.25 }
]
},
"stepsound.wood.hoof.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/wood/hoof/medium/stepsound_wood_hoof_medium_1", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/hoof/medium/stepsound_wood_hoof_medium_2", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/hoof/medium/stepsound_wood_hoof_medium_3", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/hoof/medium/stepsound_wood_hoof_medium_4", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/hoof/medium/stepsound_wood_hoof_medium_5", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/hoof/medium/stepsound_wood_hoof_medium_6", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/hoof/medium/stepsound_wood_hoof_medium_7", "volume": 0.15 },
{ "name": "cobblemon:stepsound/wood/hoof/medium/stepsound_wood_hoof_medium_8", "volume": 0.15 }
]
},
"stepsound.mud.hoof.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/mud/hoof/large/stepsound_mud_hoof_large_1", "volume": 0.2 },
{ "name": "cobblemon:stepsound/mud/hoof/large/stepsound_mud_hoof_large_2", "volume": 0.2 },
{ "name": "cobblemon:stepsound/mud/hoof/large/stepsound_mud_hoof_large_3", "volume": 0.2 },
{ "name": "cobblemon:stepsound/mud/hoof/large/stepsound_mud_hoof_large_4", "volume": 0.2 },
{ "name": "cobblemon:stepsound/mud/hoof/large/stepsound_mud_hoof_large_5", "volume": 0.2 },
{ "name": "cobblemon:stepsound/mud/hoof/large/stepsound_mud_hoof_large_6", "volume": 0.2 },
{ "name": "cobblemon:stepsound/mud/hoof/large/stepsound_mud_hoof_large_7", "volume": 0.2 },
{ "name": "cobblemon:stepsound/mud/hoof/large/stepsound_mud_hoof_large_8", "volume": 0.2 }
]
},
"stepsound.mud.hoof.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/mud/hoof/medium/stepsound_mud_hoof_medium_1", "volume": 0.1 },
{ "name": "cobblemon:stepsound/mud/hoof/medium/stepsound_mud_hoof_medium_2", "volume": 0.1 },
{ "name": "cobblemon:stepsound/mud/hoof/medium/stepsound_mud_hoof_medium_3", "volume": 0.1 },
{ "name": "cobblemon:stepsound/mud/hoof/medium/stepsound_mud_hoof_medium_4", "volume": 0.1 },
{ "name": "cobblemon:stepsound/mud/hoof/medium/stepsound_mud_hoof_medium_5", "volume": 0.1 },
{ "name": "cobblemon:stepsound/mud/hoof/medium/stepsound_mud_hoof_medium_6", "volume": 0.1 },
{ "name": "cobblemon:stepsound/mud/hoof/medium/stepsound_mud_hoof_medium_7", "volume": 0.1 },
{ "name": "cobblemon:stepsound/mud/hoof/medium/stepsound_mud_hoof_medium_8", "volume": 0.1 }
]
},
"stepsound.glass.hoof.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/glass/hoof/large/stepsound_glass_hoof_large_1", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/hoof/large/stepsound_glass_hoof_large_2", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/hoof/large/stepsound_glass_hoof_large_3", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/hoof/large/stepsound_glass_hoof_large_4", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/hoof/large/stepsound_glass_hoof_large_5", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/hoof/large/stepsound_glass_hoof_large_6", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/hoof/large/stepsound_glass_hoof_large_7", "volume": 0.2 },
{ "name": "cobblemon:stepsound/glass/hoof/large/stepsound_glass_hoof_large_8", "volume": 0.2 }
]
},
"stepsound.glass.hoof.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/glass/hoof/medium/stepsound_glass_hoof_medium_1", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/hoof/medium/stepsound_glass_hoof_medium_2", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/hoof/medium/stepsound_glass_hoof_medium_3", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/hoof/medium/stepsound_glass_hoof_medium_4", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/hoof/medium/stepsound_glass_hoof_medium_5", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/hoof/medium/stepsound_glass_hoof_medium_6", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/hoof/medium/stepsound_glass_hoof_medium_7", "volume": 0.1 },
{ "name": "cobblemon:stepsound/glass/hoof/medium/stepsound_glass_hoof_medium_8", "volume": 0.1 }
]
},
"stepsound.metal.hoof.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/metal/hoof/large/stepsound_metal_hoof_large_1", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/hoof/large/stepsound_metal_hoof_large_2", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/hoof/large/stepsound_metal_hoof_large_3", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/hoof/large/stepsound_metal_hoof_large_4", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/hoof/large/stepsound_metal_hoof_large_5", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/hoof/large/stepsound_metal_hoof_large_6", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/hoof/large/stepsound_metal_hoof_large_7", "volume": 0.2 },
{ "name": "cobblemon:stepsound/metal/hoof/large/stepsound_metal_hoof_large_8", "volume": 0.2 }
]
},
"stepsound.metal.hoof.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/metal/hoof/medium/stepsound_metal_hoof_medium_1", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/hoof/medium/stepsound_metal_hoof_medium_2", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/hoof/medium/stepsound_metal_hoof_medium_3", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/hoof/medium/stepsound_metal_hoof_medium_4", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/hoof/medium/stepsound_metal_hoof_medium_5", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/hoof/medium/stepsound_metal_hoof_medium_6", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/hoof/medium/stepsound_metal_hoof_medium_7", "volume": 0.1 },
{ "name": "cobblemon:stepsound/metal/hoof/medium/stepsound_metal_hoof_medium_8", "volume": 0.1 }
]
},
"stepsound.grass.minecraft": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "step/grass1", "volume": 0.05 },
{ "name": "step/grass2", "volume": 0.05 },
{ "name": "step/grass3", "volume": 0.05 },
{ "name": "step/grass4", "volume": 0.05 },
{ "name": "step/grass5", "volume": 0.05 },
{ "name": "step/grass6", "volume": 0.05 }
]
},
"stepsound.glass.minecraft": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "step/stone1", "volume": 0.05 },
{ "name": "step/stone2", "volume": 0.05 },
{ "name": "step/stone3", "volume": 0.05 },
{ "name": "step/stone4", "volume": 0.05 },
{ "name": "step/stone5", "volume": 0.05 },
{ "name": "step/stone6", "volume": 0.05 }
]
},
"stepsound.dirt.minecraft": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "step/gravel1", "volume": 0.05 },
{ "name": "step/gravel2", "volume": 0.05 },
{ "name": "step/gravel3", "volume": 0.05 },
{ "name": "step/gravel4", "volume": 0.05 }
]
},
"stepsound.mud.minecraft": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "block/mud/step1", "volume": 0.2 },
{ "name": "block/mud/step2", "volume": 0.2 },
{ "name": "block/mud/step3", "volume": 0.2 },
{ "name": "block/mud/step4", "volume": 0.2 },
{ "name": "block/mud/step5", "volume": 0.2 },
{ "name": "block/mud/step6", "volume": 0.2 }
]
},
"stepsound.stone.minecraft": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "step/stone1", "volume": 0.08 },
{ "name": "step/stone2", "volume": 0.08 },
{ "name": "step/stone3", "volume": 0.08 },
{ "name": "step/stone4", "volume": 0.08 },
{ "name": "step/stone5", "volume": 0.08 },
{ "name": "step/stone6", "volume": 0.08 }
]
},
"stepsound.wood.minecraft": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "block/cherry_wood/step1", "volume": 0.2 },
{ "name": "block/cherry_wood/step2", "volume": 0.2 },
{ "name": "block/cherry_wood/step3", "volume": 0.2 },
{ "name": "block/cherry_wood/step4", "volume": 0.2 },
{ "name": "block/cherry_wood/step5", "volume": 0.2 },
{ "name": "block/cherry_wood/step6", "volume": 0.2 }
]
},
"stepsound.metal.minecraft": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "block/copper/step1", "volume": 0.2 },
{ "name": "block/copper/step2", "volume": 0.2 },
{ "name": "block/copper/step3", "volume": 0.2 },
{ "name": "block/copper/step4", "volume": 0.2 },
{ "name": "block/copper/step5", "volume": 0.2 },
{ "name": "block/copper/step6", "volume": 0.2 }
]
},
"stepsound.sand.minecraft": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "step/sand1", "volume": 0.08 },
{ "name": "step/sand2", "volume": 0.08 },
{ "name": "step/sand3", "volume": 0.08 },
{ "name": "step/sand4", "volume": 0.08 },
{ "name": "step/sand5", "volume": 0.08 }
]
},
"stepsound.snow.minecraft": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "step/snow1", "volume": 0.08 },
{ "name": "step/snow2", "volume": 0.08 },
{ "name": "step/snow3", "volume": 0.08 },
{ "name": "step/snow4", "volume": 0.08 }
]
},
"stepsound.amethyst.minecraft": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "block/amethyst/step1", "volume": 0.11 },
{ "name": "block/amethyst/step2", "volume": 0.11 },
{ "name": "block/amethyst/step3", "volume": 0.11 },
{ "name": "block/amethyst/step4", "volume": 0.11 },
{ "name": "block/amethyst/step5", "volume": 0.11 },
{ "name": "block/amethyst/step6", "volume": 0.11 },
{ "name": "block/amethyst/step7", "volume": 0.11 },
{ "name": "block/amethyst/step8", "volume": 0.11 },
{ "name": "block/amethyst/step9", "volume": 0.11 },
{ "name": "block/amethyst/step10", "volume": 0.11 },
{ "name": "block/amethyst/step11", "volume": 0.11 },
{ "name": "block/amethyst/step12", "volume": 0.11 },
{ "name": "block/amethyst/step13", "volume": 0.11 },
{ "name": "block/amethyst/step14", "volume": 0.11 }
]
},
"stepsound.grass.claw.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/grass/claw/large/stepsound_grass_claw_large_1", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/claw/large/stepsound_grass_claw_large_2", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/claw/large/stepsound_grass_claw_large_3", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/claw/large/stepsound_grass_claw_large_4", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/claw/large/stepsound_grass_claw_large_5", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/claw/large/stepsound_grass_claw_large_6", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/claw/large/stepsound_grass_claw_large_7", "volume": 0.25 },
{ "name": "cobblemon:stepsound/grass/claw/large/stepsound_grass_claw_large_8", "volume": 0.25 }
]
},
"stepsound.grass.claw.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/grass/claw/medium/stepsound_grass_claw_medium_1", "volume": 0.14 },
{ "name": "cobblemon:stepsound/grass/claw/medium/stepsound_grass_claw_medium_2", "volume": 0.14 },
{ "name": "cobblemon:stepsound/grass/claw/medium/stepsound_grass_claw_medium_3", "volume": 0.14 },
{ "name": "cobblemon:stepsound/grass/claw/medium/stepsound_grass_claw_medium_4", "volume": 0.14 },
{ "name": "cobblemon:stepsound/grass/claw/medium/stepsound_grass_claw_medium_5", "volume": 0.14 },
{ "name": "cobblemon:stepsound/grass/claw/medium/stepsound_grass_claw_medium_6", "volume": 0.14 },
{ "name": "cobblemon:stepsound/grass/claw/medium/stepsound_grass_claw_medium_7", "volume": 0.14 },
{ "name": "cobblemon:stepsound/grass/claw/medium/stepsound_grass_claw_medium_8", "volume": 0.14 }
]
},
"stepsound.dirt.claw.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/dirt/claw/large/stepsound_dirt_claw_large_1", "volume": 0.22 },
{ "name": "cobblemon:stepsound/dirt/claw/large/stepsound_dirt_claw_large_2", "volume": 0.22 },
{ "name": "cobblemon:stepsound/dirt/claw/large/stepsound_dirt_claw_large_3", "volume": 0.22 },
{ "name": "cobblemon:stepsound/dirt/claw/large/stepsound_dirt_claw_large_4", "volume": 0.22 },
{ "name": "cobblemon:stepsound/dirt/claw/large/stepsound_dirt_claw_large_5", "volume": 0.22 },
{ "name": "cobblemon:stepsound/dirt/claw/large/stepsound_dirt_claw_large_6", "volume": 0.22 },
{ "name": "cobblemon:stepsound/dirt/claw/large/stepsound_dirt_claw_large_7", "volume": 0.22 },
{ "name": "cobblemon:stepsound/dirt/claw/large/stepsound_dirt_claw_large_8", "volume": 0.22 }
]
},
"stepsound.dirt.claw.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/dirt/claw/medium/stepsound_dirt_claw_medium_1", "volume": 0.11 },
{ "name": "cobblemon:stepsound/dirt/claw/medium/stepsound_dirt_claw_medium_2", "volume": 0.11 },
{ "name": "cobblemon:stepsound/dirt/claw/medium/stepsound_dirt_claw_medium_3", "volume": 0.11 },
{ "name": "cobblemon:stepsound/dirt/claw/medium/stepsound_dirt_claw_medium_4", "volume": 0.11 },
{ "name": "cobblemon:stepsound/dirt/claw/medium/stepsound_dirt_claw_medium_5", "volume": 0.11 },
{ "name": "cobblemon:stepsound/dirt/claw/medium/stepsound_dirt_claw_medium_6", "volume": 0.11 },
{ "name": "cobblemon:stepsound/dirt/claw/medium/stepsound_dirt_claw_medium_7", "volume": 0.11 },
{ "name": "cobblemon:stepsound/dirt/claw/medium/stepsound_dirt_claw_medium_8", "volume": 0.11 }
]
},
"stepsound.stone.claw.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/stone/claw/large/stepsound_stone_claw_large_1", "volume": 0.22 },
{ "name": "cobblemon:stepsound/stone/claw/large/stepsound_stone_claw_large_2", "volume": 0.22 },
{ "name": "cobblemon:stepsound/stone/claw/large/stepsound_stone_claw_large_3", "volume": 0.22 },
{ "name": "cobblemon:stepsound/stone/claw/large/stepsound_stone_claw_large_4", "volume": 0.22 },
{ "name": "cobblemon:stepsound/stone/claw/large/stepsound_stone_claw_large_5", "volume": 0.22 },
{ "name": "cobblemon:stepsound/stone/claw/large/stepsound_stone_claw_large_6", "volume": 0.22 },
{ "name": "cobblemon:stepsound/stone/claw/large/stepsound_stone_claw_large_7", "volume": 0.22 },
{ "name": "cobblemon:stepsound/stone/claw/large/stepsound_stone_claw_large_8", "volume": 0.22 }
]
},
"stepsound.stone.claw.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/stone/claw/medium/stepsound_stone_claw_medium_1", "volume": 0.11 },
{ "name": "cobblemon:stepsound/stone/claw/medium/stepsound_stone_claw_medium_2", "volume": 0.11 },
{ "name": "cobblemon:stepsound/stone/claw/medium/stepsound_stone_claw_medium_3", "volume": 0.11 },
{ "name": "cobblemon:stepsound/stone/claw/medium/stepsound_stone_claw_medium_4", "volume": 0.11 },
{ "name": "cobblemon:stepsound/stone/claw/medium/stepsound_stone_claw_medium_5", "volume": 0.11 },
{ "name": "cobblemon:stepsound/stone/claw/medium/stepsound_stone_claw_medium_6", "volume": 0.11 },
{ "name": "cobblemon:stepsound/stone/claw/medium/stepsound_stone_claw_medium_7", "volume": 0.11 },
{ "name": "cobblemon:stepsound/stone/claw/medium/stepsound_stone_claw_medium_8", "volume": 0.11 }
]
},
"stepsound.sand.claw.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/sand/claw/large/stepsound_sand_claw_large_1", "volume": 0.22 },
{ "name": "cobblemon:stepsound/sand/claw/large/stepsound_sand_claw_large_2", "volume": 0.22 },
{ "name": "cobblemon:stepsound/sand/claw/large/stepsound_sand_claw_large_3", "volume": 0.22 },
{ "name": "cobblemon:stepsound/sand/claw/large/stepsound_sand_claw_large_4", "volume": 0.22 },
{ "name": "cobblemon:stepsound/sand/claw/large/stepsound_sand_claw_large_5", "volume": 0.22 },
{ "name": "cobblemon:stepsound/sand/claw/large/stepsound_sand_claw_large_6", "volume": 0.22 },
{ "name": "cobblemon:stepsound/sand/claw/large/stepsound_sand_claw_large_7", "volume": 0.22 },
{ "name": "cobblemon:stepsound/sand/claw/large/stepsound_sand_claw_large_8", "volume": 0.22 }
]
},
"stepsound.sand.claw.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/sand/claw/medium/stepsound_sand_claw_medium_1", "volume": 0.11 },
{ "name": "cobblemon:stepsound/sand/claw/medium/stepsound_sand_claw_medium_2", "volume": 0.11 },
{ "name": "cobblemon:stepsound/sand/claw/medium/stepsound_sand_claw_medium_3", "volume": 0.11 },
{ "name": "cobblemon:stepsound/sand/claw/medium/stepsound_sand_claw_medium_4", "volume": 0.11 },
{ "name": "cobblemon:stepsound/sand/claw/medium/stepsound_sand_claw_medium_5", "volume": 0.11 },
{ "name": "cobblemon:stepsound/sand/claw/medium/stepsound_sand_claw_medium_6", "volume": 0.11 },
{ "name": "cobblemon:stepsound/sand/claw/medium/stepsound_sand_claw_medium_7", "volume": 0.11 },
{ "name": "cobblemon:stepsound/sand/claw/medium/stepsound_sand_claw_medium_8", "volume": 0.11 }
]
},
"stepsound.snow.claw.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/snow/claw/large/stepsound_snow_claw_large_1", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/claw/large/stepsound_snow_claw_large_2", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/claw/large/stepsound_snow_claw_large_3", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/claw/large/stepsound_snow_claw_large_4", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/claw/large/stepsound_snow_claw_large_5", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/claw/large/stepsound_snow_claw_large_6", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/claw/large/stepsound_snow_claw_large_7", "volume": 0.22 },
{ "name": "cobblemon:stepsound/snow/claw/large/stepsound_snow_claw_large_8", "volume": 0.22 }
]
},
"stepsound.snow.claw.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/snow/claw/medium/stepsound_snow_claw_medium_1", "volume": 0.11 },
{ "name": "cobblemon:stepsound/snow/claw/medium/stepsound_snow_claw_medium_2", "volume": 0.11 },
{ "name": "cobblemon:stepsound/snow/claw/medium/stepsound_snow_claw_medium_3", "volume": 0.11 },
{ "name": "cobblemon:stepsound/snow/claw/medium/stepsound_snow_claw_medium_4", "volume": 0.11 },
{ "name": "cobblemon:stepsound/snow/claw/medium/stepsound_snow_claw_medium_5", "volume": 0.11 },
{ "name": "cobblemon:stepsound/snow/claw/medium/stepsound_snow_claw_medium_6", "volume": 0.11 },
{ "name": "cobblemon:stepsound/snow/claw/medium/stepsound_snow_claw_medium_7", "volume": 0.11 },
{ "name": "cobblemon:stepsound/snow/claw/medium/stepsound_snow_claw_medium_8", "volume": 0.11 }
]
},
"stepsound.wood.claw.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/wood/claw/large/stepsound_wood_claw_large_1", "volume": 0.22 },
{ "name": "cobblemon:stepsound/wood/claw/large/stepsound_wood_claw_large_2", "volume": 0.22 },
{ "name": "cobblemon:stepsound/wood/claw/large/stepsound_wood_claw_large_3", "volume": 0.22 },
{ "name": "cobblemon:stepsound/wood/claw/large/stepsound_wood_claw_large_4", "volume": 0.22 },
{ "name": "cobblemon:stepsound/wood/claw/large/stepsound_wood_claw_large_5", "volume": 0.22 },
{ "name": "cobblemon:stepsound/wood/claw/large/stepsound_wood_claw_large_6", "volume": 0.22 },
{ "name": "cobblemon:stepsound/wood/claw/large/stepsound_wood_claw_large_7", "volume": 0.22 },
{ "name": "cobblemon:stepsound/wood/claw/large/stepsound_wood_claw_large_8", "volume": 0.22 }
]
},
"stepsound.wood.claw.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/wood/claw/medium/stepsound_wood_claw_medium_1", "volume": 0.11 },
{ "name": "cobblemon:stepsound/wood/claw/medium/stepsound_wood_claw_medium_2", "volume": 0.11 },
{ "name": "cobblemon:stepsound/wood/claw/medium/stepsound_wood_claw_medium_3", "volume": 0.11 },
{ "name": "cobblemon:stepsound/wood/claw/medium/stepsound_wood_claw_medium_4", "volume": 0.11 },
{ "name": "cobblemon:stepsound/wood/claw/medium/stepsound_wood_claw_medium_5", "volume": 0.11 },
{ "name": "cobblemon:stepsound/wood/claw/medium/stepsound_wood_claw_medium_6", "volume": 0.11 },
{ "name": "cobblemon:stepsound/wood/claw/medium/stepsound_wood_claw_medium_7", "volume": 0.11 },
{ "name": "cobblemon:stepsound/wood/claw/medium/stepsound_wood_claw_medium_8", "volume": 0.11 }
]
},
"stepsound.mud.claw.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/mud/claw/large/stepsound_mud_claw_large_1", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/claw/large/stepsound_mud_claw_large_2", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/claw/large/stepsound_mud_claw_large_3", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/claw/large/stepsound_mud_claw_large_4", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/claw/large/stepsound_mud_claw_large_5", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/claw/large/stepsound_mud_claw_large_6", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/claw/large/stepsound_mud_claw_large_7", "volume": 0.22 },
{ "name": "cobblemon:stepsound/mud/claw/large/stepsound_mud_claw_large_8", "volume": 0.22 }
]
},
"stepsound.mud.claw.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/mud/claw/medium/stepsound_mud_claw_medium_1", "volume": 0.11 },
{ "name": "cobblemon:stepsound/mud/claw/medium/stepsound_mud_claw_medium_2", "volume": 0.11 },
{ "name": "cobblemon:stepsound/mud/claw/medium/stepsound_mud_claw_medium_3", "volume": 0.11 },
{ "name": "cobblemon:stepsound/mud/claw/medium/stepsound_mud_claw_medium_4", "volume": 0.11 },
{ "name": "cobblemon:stepsound/mud/claw/medium/stepsound_mud_claw_medium_5", "volume": 0.11 },
{ "name": "cobblemon:stepsound/mud/claw/medium/stepsound_mud_claw_medium_6", "volume": 0.11 },
{ "name": "cobblemon:stepsound/mud/claw/medium/stepsound_mud_claw_medium_7", "volume": 0.11 },
{ "name": "cobblemon:stepsound/mud/claw/medium/stepsound_mud_claw_medium_8", "volume": 0.11 }
]
},
"stepsound.glass.claw.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/glass/claw/large/stepsound_glass_claw_large_1", "volume": 0.22 },
{ "name": "cobblemon:stepsound/glass/claw/large/stepsound_glass_claw_large_2", "volume": 0.22 },
{ "name": "cobblemon:stepsound/glass/claw/large/stepsound_glass_claw_large_3", "volume": 0.22 },
{ "name": "cobblemon:stepsound/glass/claw/large/stepsound_glass_claw_large_4", "volume": 0.22 },
{ "name": "cobblemon:stepsound/glass/claw/large/stepsound_glass_claw_large_5", "volume": 0.22 },
{ "name": "cobblemon:stepsound/glass/claw/large/stepsound_glass_claw_large_6", "volume": 0.22 },
{ "name": "cobblemon:stepsound/glass/claw/large/stepsound_glass_claw_large_7", "volume": 0.22 },
{ "name": "cobblemon:stepsound/glass/claw/large/stepsound_glass_claw_large_8", "volume": 0.22 }
]
},
"stepsound.glass.claw.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/glass/claw/medium/stepsound_glass_claw_medium_1", "volume": 0.11 },
{ "name": "cobblemon:stepsound/glass/claw/medium/stepsound_glass_claw_medium_2", "volume": 0.11 },
{ "name": "cobblemon:stepsound/glass/claw/medium/stepsound_glass_claw_medium_3", "volume": 0.11 },
{ "name": "cobblemon:stepsound/glass/claw/medium/stepsound_glass_claw_medium_4", "volume": 0.11 },
{ "name": "cobblemon:stepsound/glass/claw/medium/stepsound_glass_claw_medium_5", "volume": 0.11 },
{ "name": "cobblemon:stepsound/glass/claw/medium/stepsound_glass_claw_medium_6", "volume": 0.11 },
{ "name": "cobblemon:stepsound/glass/claw/medium/stepsound_glass_claw_medium_7", "volume": 0.11 },
{ "name": "cobblemon:stepsound/glass/claw/medium/stepsound_glass_claw_medium_8", "volume": 0.11 }
]
},
"stepsound.metal.claw.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/metal/claw/large/stepsound_metal_claw_large_1", "volume": 0.22 },
{ "name": "cobblemon:stepsound/metal/claw/large/stepsound_metal_claw_large_2", "volume": 0.22 },
{ "name": "cobblemon:stepsound/metal/claw/large/stepsound_metal_claw_large_3", "volume": 0.22 },
{ "name": "cobblemon:stepsound/metal/claw/large/stepsound_metal_claw_large_4", "volume": 0.22 },
{ "name": "cobblemon:stepsound/metal/claw/large/stepsound_metal_claw_large_5", "volume": 0.22 },
{ "name": "cobblemon:stepsound/metal/claw/large/stepsound_metal_claw_large_6", "volume": 0.22 },
{ "name": "cobblemon:stepsound/metal/claw/large/stepsound_metal_claw_large_7", "volume": 0.22 },
{ "name": "cobblemon:stepsound/metal/claw/large/stepsound_metal_claw_large_8", "volume": 0.22 }
]
},
"stepsound.metal.claw.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/metal/claw/medium/stepsound_metal_claw_medium_1", "volume": 0.11 },
{ "name": "cobblemon:stepsound/metal/claw/medium/stepsound_metal_claw_medium_2", "volume": 0.11 },
{ "name": "cobblemon:stepsound/metal/claw/medium/stepsound_metal_claw_medium_3", "volume": 0.11 },
{ "name": "cobblemon:stepsound/metal/claw/medium/stepsound_metal_claw_medium_4", "volume": 0.11 },
{ "name": "cobblemon:stepsound/metal/claw/medium/stepsound_metal_claw_medium_5", "volume": 0.11 },
{ "name": "cobblemon:stepsound/metal/claw/medium/stepsound_metal_claw_medium_6", "volume": 0.11 },
{ "name": "cobblemon:stepsound/metal/claw/medium/stepsound_metal_claw_medium_7", "volume": 0.11 },
{ "name": "cobblemon:stepsound/metal/claw/medium/stepsound_metal_claw_medium_8", "volume": 0.11 }
]
},
"stepsound.leaves.universal.large": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/leaves/universal/large/stepsound_leaves_universal_large_1", "volume": 0.12 },
{ "name": "cobblemon:stepsound/leaves/universal/large/stepsound_leaves_universal_large_2", "volume": 0.12 },
{ "name": "cobblemon:stepsound/leaves/universal/large/stepsound_leaves_universal_large_3", "volume": 0.12 },
{ "name": "cobblemon:stepsound/leaves/universal/large/stepsound_leaves_universal_large_4", "volume": 0.12 },
{ "name": "cobblemon:stepsound/leaves/universal/large/stepsound_leaves_universal_large_5", "volume": 0.12 },
{ "name": "cobblemon:stepsound/leaves/universal/large/stepsound_leaves_universal_large_6", "volume": 0.12 },
{ "name": "cobblemon:stepsound/leaves/universal/large/stepsound_leaves_universal_large_7", "volume": 0.12 },
{ "name": "cobblemon:stepsound/leaves/universal/large/stepsound_leaves_universal_large_8", "volume": 0.12 }
]
},
"stepsound.leaves.universal.medium": {
"subtitle": "subtitles.block.generic.footsteps",
"sounds": [
{ "name": "cobblemon:stepsound/leaves/universal/medium/stepsound_leaves_universal_medium_1", "volume": 0.06 },
{ "name": "cobblemon:stepsound/leaves/universal/medium/stepsound_leaves_universal_medium_2", "volume": 0.06 },
{ "name": "cobblemon:stepsound/leaves/universal/medium/stepsound_leaves_universal_medium_3", "volume": 0.06 },
{ "name": "cobblemon:stepsound/leaves/universal/medium/stepsound_leaves_universal_medium_4", "volume": 0.06 },
{ "name": "cobblemon:stepsound/leaves/universal/medium/stepsound_leaves_universal_medium_5", "volume": 0.06 },
{ "name": "cobblemon:stepsound/leaves/universal/medium/stepsound_leaves_universal_medium_6", "volume": 0.06 },
{ "name": "cobblemon:stepsound/leaves/universal/medium/stepsound_leaves_universal_medium_7", "volume": 0.06 },
{ "name": "cobblemon:stepsound/leaves/universal/medium/stepsound_leaves_universal_medium_8", "volume": 0.06 }
]
},
"ride.loop.wind.mono": {
"sounds": [
{
Loaded 100 of 514 files, more files were not shown because too many files have changed in this diff. Show more