Compare commits

..
Author SHA1 Message Date
whatsy bacc482bf0 finishing touches 2026-10-14 16:25:16 -04:00
Gertimoshka edb3f906f8 Simpler Mixin 2026-10-14 21:48:14 +02:00
whatsy 4171bf341b Add config option to allow using healing machines as a respawn point 2026-10-14 15:02:54 -04:00
Polymeta 6f3894f27b fix playermolang sometimes failing when they die
Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
2026-10-14 13:33:40 +01:00
Polymeta bbc9a5e62e Merge branch 'campfire-book-lies' into 'main'
Recipe Book Lies No More

See merge request cable-mc/cobblemon!2487
2026-10-14 11:32:52 +00:00
dhi_holo 8caa82f123 Recipe Book Lies No More
Changed the icon for the misc category
2026-10-14 18:42:58 +10:00
22 changed files with 96 additions and 213 deletions
+7
View File
@@ -2,6 +2,7 @@
## [1.8.3 (MONTH xth, 2026)](#1-8-3)
### Additions
- Added the `healersSetSpawn` gamerule. When enabled, using a healing machine will set your spawnpoint.
### Pokémon Added
#### Generation 4
@@ -21,6 +22,8 @@
### Animation updates for the following Pokémon
### Changes
- Changed the Misc icon in the Campfire Pot Recipe Book to Health Candy
- Moved EXP Candies from the Medicine recipe book category to the Misc category
### Fixes
- Fixed datapacks with item interaction evolutions that don't specify an item crashing the world on load.
@@ -34,9 +37,13 @@
- Fixed conflicts with other mods that would make use of recipe books in certain ways (Farmer's Delight Cooking Pot)
- Fixed Pokémon battles stalling when a sidemod cancels the `THROWN_POKEBALL_HIT` hit event
- Fixed choice feature tab completion in `spawnpokemon/pokegive/pokeedit` commands
- Fixed MoLang that's targeting players intermittedly failing when they have died, needing them to relog
### Developer
- Bumped NeoForge to `21.1.195` to get access to MixinExtras `0.5` and the expressions annotation
- New Platform Event `PLAYER_RESPAWN` which is fired when a player respawns (either through death or returning from the end)
- Platform Events `SERVER_PLAYER_TICK_PRE` and `SERVER_PLAYER_TICK_POST` no longer fire when the player is dead
- it is now tied much closer to the actual entity rather than the player (or their connection)
### Molang & Datapacks
- Fixed `q.pokemon.nature` returning class instance instead of proper string value (`cobblemon:adamant`)
@@ -15,6 +15,7 @@ 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;
@@ -22,10 +23,14 @@ 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;
@@ -33,6 +38,9 @@ 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 {
@@ -142,4 +150,17 @@ 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)));
}
}
}
@@ -260,6 +260,9 @@ object Cobblemon {
RequestManager.onLogoff(it.player)
serverPlayerStructs.remove(it.player.uuid)
}
PlatformEvents.PLAYER_RESPAWN.subscribe {
serverPlayerStructs.remove(it.player.uuid)
}
PlatformEvents.PLAYER_DEATH.subscribe {
PCLinkManager.removeLink(it.player.uuid)
battleRegistry.getBattleByParticipatingPlayer(it.player)?.stop()
@@ -24,6 +24,7 @@ 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
@@ -31,13 +32,9 @@ 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.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.*
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityType
@@ -48,9 +45,11 @@ 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) {
@@ -79,6 +78,14 @@ 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 {
@@ -158,7 +165,12 @@ class HealingMachineBlock(settings: Properties) : BaseEntityBlock(settings) {
}
val party = serverPlayerEntity.party()
val pc = serverPlayerEntity.pc()
val healPC = player.level().gameRules.getBoolean(CobblemonGameRules.HEALERS_HEAL_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)
}
if (party.none() && (!healPC || pc.none())) {
player.sendSystemMessage(lang("healingmachine.nopokemon").red(), true)
@@ -183,6 +195,7 @@ 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
}
@@ -55,6 +55,8 @@ object PlatformEvents {
@JvmField
val CLIENT_PLAYER_LOGOUT = EventObservable<ClientPlayerEvent.Logout>()
@JvmField
val PLAYER_RESPAWN = EventObservable<ServerPlayerEvent.Respawn>()
@JvmField
val PLAYER_DEATH = CancelableObservable<ServerPlayerEvent.Death>()
@JvmField
val RIGHT_CLICK_BLOCK = CancelableObservable<ServerPlayerEvent.RightClickBlock>()
@@ -50,6 +50,11 @@ interface ServerPlayerEvent {
*/
data class Logout(override val player: ServerPlayer) : ServerPlayerEvent
/**
* Fired when the [player] respawns (either by coming back from the end or dying).
*/
data class Respawn(override val player: ServerPlayer) : ServerPlayerEvent
/**
* Fired when the [player] dies.
* If canceled the death will be prevented but healing is required in order to not be stuck in a loop.
@@ -26,5 +26,7 @@ object CobblemonGameRules {
val SHINY_STARTERS: GameRules.Key<GameRules.BooleanValue> = Cobblemon.implementation.registerGameRule("doShinyStarters", GameRules.Category.MISC, BooleanRuleInvoker.`cobblemon$create`(false))
@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))
}
@@ -855,7 +855,7 @@
"advancements.cobblemon.obtain_berry.description": "地表に育ち多くの用途を持つ、きのみを手に入れる",
"advancements.cobblemon.obtain_mutated_berry": "想定外の結果",
"advancements.cobblemon.obtain_mutated_berry.description": "違う種類のきのみの木を隣り合わせに植えて突然変異を目撃する",
"advancements.cobblemon.obtain_all_berries": "もぎってナッツ",
"advancements.cobblemon.obtain_all_berries": "もぎもぎフルーツ",
"advancements.cobblemon.obtain_all_berries.description": "Cobblemonに登場する全てのきのみを集める",
"advancements.cobblemon.use_pasture": "みんなのポケモン牧場",
"advancements.cobblemon.use_pasture.description": "ぼくじょうブロックを作りポケモンを放し飼いにする",
@@ -6219,7 +6219,7 @@
"cobblemon.egg_group.water_2": "水中②",
"cobblemon.egg_group.ditto": "メタモン",
"cobblemon.egg_group.dragon": "ドラゴン",
"cobblemon.egg_group.undiscovered": "未発見",
"cobblemon.egg_group.undiscovered": "タマゴ未発見",
"cobblemon.trade.canceled.sender": "%1$s との交換リクエストをキャンセルしました。",
"cobblemon.trade.canceled.receiver": "%1$s が交換リクエストをキャンセルしました...",
"cobblemon.trade.sent": "%1$s との交換をリクエストしました。",
@@ -6981,7 +6981,7 @@
"cobblemon.mark.ribbon_contest_sinnoh_tough_3.desc": "スーパーコンテスト たくましさ部門 ウルトラランク 優勝!",
"cobblemon.mark.ribbon_contest_sinnoh_tough_4": "パワフルリボンマスター",
"cobblemon.mark.ribbon_contest_super_master_beauty": "うつくしさマスターリボン",
"cobblemon.mark.ribbon_contest_super_master_beauty.title": "とうじからきれいな %1$s",
"cobblemon.mark.ribbon_contest_super_master_beauty.title": "とうじきれいだった %1$s",
"cobblemon.mark.ribbon_contest_super_master_beauty.desc": "コンテストで うつくしさを 発揮した ポケモンに 贈られる 記念リボン",
"cobblemon.mark.ribbon_contest_super_master_cleverness": "かしこさマスターリボン",
"cobblemon.mark.ribbon_contest_super_master_cleverness.title": "てんさいとよばれた %1$s",
@@ -7002,7 +7002,7 @@
"cobblemon.mark.ribbon_contest_super_master_coolness": "かっこよさマスターリボン",
"cobblemon.mark.ribbon_contest_super_master_cuteness.desc": "コンテストで かわいさを 発揮した ポケモンに 贈られる 記念リボン",
"cobblemon.mark.ribbon_contest_super_master_toughness": "たくましさマスターリボン",
"cobblemon.mark.ribbon_contest_super_master_toughness.title": "むかしからムキムキの %1$s",
"cobblemon.mark.ribbon_contest_super_master_toughness.title": "ムキムキの %1$s",
"cobblemon.mark.ribbon_contest_super_master_toughness.desc": "コンテストで たくましさを 発揮した ポケモンに 贈られる 記念リボン",
"cobblemon.mark.ribbon_contest_super_star": "コンテストスターリボン",
"cobblemon.mark.ribbon_contest_super_star.title": "でんせつてきスターの %1$s",
@@ -9243,7 +9243,7 @@
"cobblemon.ui.moves.learnset.tm.discovered": "発見済み",
"cobblemon.ui.moves.level": "レベルアップ",
"cobblemon.ui.moves.egg": "タマゴ技",
"cobblemon.ui.moves.tm": "わざマシン",
"cobblemon.ui.moves.tm": "わざマシン",
"cobblemon.ui.tm_machine.can_learn": "覚えられる",
"cobblemon.ui.tm_machine.cannot_learn": "覚えられない",
"cobblemon.ui.tm_machine.learned": "覚えている",
@@ -9596,42 +9596,5 @@
"cobblemon.config.ui.world_spawning_blocklist": "ワールドごとのスポーンブロックリスト",
"cobblemon.config.ui.world_spawning_blocklist.tooltip": "ポケモンの出現ロジックを無効にするワールド。",
"advancements.cobblemon.obtain_tm": "Show Me Your Moves!",
"advancements.cobblemon.obtain_tm.description": "わざマシンを見つけるか、印刷する",
"itemGroup.cobblemon.tm_item": "Cobblemon:わざマシン",
"block.cobblemon.wistensu": "フジブヨウ",
"block.cobblemon.lobaila": "ミゾグレン",
"block.cobblemon.pauvillea": "フラビリア",
"block.cobblemon.pomohana": "ポンノハナ",
"block.cobblemon.voltaconia": "ボルトコニア",
"block.cobblemon.verdroot": "ミノルート",
"block.cobblemon.lucibell": "サイヴェル",
"block.cobblemon.mistleaf": "ミストリーフ",
"cobblemon.ui.pokedex.info.evolution_tree": "進化の流れ",
"cobblemon.ui.pokedex.evolution.item_interact.tooltip": "%1$sが必要",
"cobblemon.ui.pokedex.evolution.trade.tooltip.with_species": "%1$sとのポケモン交換で進化",
"cobblemon.ui.pokedex.evolution.trade.tooltip.with_any_species": "ポケモン交換で進化",
"cobblemon.ui.pokedex.evolution.shedder.tooltip": "予備のモンスターボールと手持ちの空きが必要",
"cobblemon.ui.pokedex.evolution.or": "または",
"cobblemon.ui.pokedex.evolution.one_of": "以下のいずれか:",
"cobblemon.ui.pokedex.requirement.advancement.tooltip": "プレイヤーが進捗 %1$sを達成している必要あり",
"cobblemon.ui.pokedex.requirement.battle_critical_hits.tooltip": "バトルで%1$s回急所に当てる",
"cobblemon.ui.pokedex.requirement.biome.anticondition.tooltip": "%1$sバイオームでは進化出来ない",
"cobblemon.ui.pokedex.requirement.biome.both.tooltip": "%2$sを除いた%1$sバイオームでのみ進化",
"cobblemon.ui.pokedex.requirement.biome.tooltip": "%1$sバイオームでのみ進化",
"cobblemon.ui.pokedex.requirement.blocks_traveled.tooltip": "%1$sブロック分旅をする",
"cobblemon.ui.pokedex.requirement.damage_taken.tooltip": "バトルで倒れず%1$sダメージ受ける",
"cobblemon.ui.pokedex.requirement.defeat.tooltip": "進化するためにはバトルで%1$sを倒す",
"cobblemon.ui.pokedex.requirement.friendship.tooltip": "なかよし度%1$sが必要",
"cobblemon.ui.pokedex.requirement.has_move.tooltip": "%1$sを覚える必要がある",
"cobblemon.ui.pokedex.requirement.has_move_type.tooltip": "%1$sタイプの技を覚えておく必要がある",
"cobblemon.ui.pokedex.requirement.held_item.tooltip": "%1$sを持っている必要がある",
"cobblemon.ui.pokedex.requirement.level.tooltip.min": "レベル%1$sから進化",
"cobblemon.ui.pokedex.requirement.party_member.tooltip": "レベルが%1$sから%2$sの間で進化",
"cobblemon.ui.pokedex.requirement.pokemon_properties.tooltip": "%1$sでなければいけない",
"cobblemon.ui.pokedex.requirement.properties.and": "%1$s と %2$s",
"cobblemon.ui.pokedex.requirement.level.tooltip.between": "レベルが%1$sから%2$sの間で進化",
"cobblemon.ui.pokedex.requirement.moon_phase.tooltip": "月の満ち欠けが%1$sでなければいけない",
"cobblemon.ui.pokedex.requirement.nature.toxtricity_amped": "性格が§aがんばりや§r、 §aゆうかん§r、 §aいじっぱり§r、 §aやんちゃ§r、 §aすなお§r、 §aわんぱく§r、 §aのうてんき§r、 §aせっかち§r、 §aようき§r、 §aむじゃき§r、 §aうっかりや§r、 §aなまいき§r、 §aきまぐれ§rのどれか",
"cobblemon.ui.pokedex.requirement.nature.toxtricity_low_key": "性格が§aさみしがり§r、 §aずぶとい§r、 §aのんき§r、 §aおくびょう§r、 §aまじめ§r、 §aひかえめ§r、 §aおっとり§r、 §aれいせい§r、 §aてれや§r、 §aおだやか§r、 §a\tおとなしい§r、 §aしんちょう§rのどれか",
"cobblemon.ui.pokedex.requirement.nickname.malamar": "ニックネームを§aDinnerbone§rか§aGrumm§rにする"
"advancements.cobblemon.obtain_tm.description": "わざマシンを見つけるか、印刷する"
}
@@ -9413,114 +9413,5 @@
"cobblemon.ui.pokedex.info.form.tatsugiri-stretchymega": "Mega Tatsugiri Forma Estendida",
"cobblemon.species.tatsugiri-stretchymega.desc": "Usando a energia da Mega Evolução, cria um prato onde repousar, permitindo com que se mova com mobilidade total até mesmo pelo ar.",
"cobblemon.ui.pokedex.info.form.baxcalibur-mega": "Mega Baxcalibur",
"cobblemon.species.baxcalibur-mega.desc": "A lâmina dorsal de Baxcalibur ficou ainda maior graças à Mega Evolução. Esse Pokémon dispara feixes do cabo localizado em seu peito.",
"itemGroup.cobblemon.tm_item": "Cobblemon: Máquinas Técnicas",
"block.cobblemon.pomohana": "Pomohana",
"block.cobblemon.pauvillea": "Pa'uvillea",
"block.cobblemon.lobaila": "Lobaila",
"block.cobblemon.wistensu": "Wistensu",
"block.cobblemon.voltaconia": "Voltaconia",
"block.cobblemon.verdroot": "Verdroot",
"block.cobblemon.lucibell": "Lucibell",
"block.cobblemon.mistleaf": "Mistleaf",
"cobblemon.ui.pokedex.info.evolution_tree": "Árvore Evolutiva",
"cobblemon.ui.pokedex.evolution.item_interact.tooltip": "Precisa do item %1$s para evoluir",
"cobblemon.ui.pokedex.evolution.trade.tooltip.with_species": "Evolui quando trocado segurando %1$s",
"cobblemon.ui.pokedex.evolution.trade.tooltip.with_any_species": "Evolui quando trocado",
"cobblemon.ui.pokedex.evolution.shedder.tooltip": "Também requer uma Pokébola extra e um espaço vazio na equipe",
"cobblemon.ui.pokedex.evolution.or": "OU",
"cobblemon.ui.pokedex.evolution.one_of": "Um de:",
"cobblemon.ui.pokedex.requirement.advancement.tooltip": "Jogador precisa ter a conquista %1$s",
"cobblemon.ui.pokedex.requirement.battle_critical_hits.tooltip": "Precisa acertar %1$s acertos críticos em batalha",
"cobblemon.ui.pokedex.requirement.biome.anticondition.tooltip": "Não pode estar no bioma %1$s",
"cobblemon.ui.pokedex.requirement.biome.both.tooltip": "Precisa estar no bioma %1$s e não no bioma %2$s",
"cobblemon.ui.pokedex.requirement.biome.tooltip": "Precisa estar no bioma %1$s",
"cobblemon.ui.pokedex.requirement.blocks_traveled.tooltip": "Precisa viajar %1$s blocos",
"cobblemon.ui.pokedex.requirement.damage_taken.tooltip": "Precisa receber %1$s de dano em uma batalha sem desmaiar",
"cobblemon.ui.pokedex.requirement.defeat.tooltip": "Precisa derrotar %1$s em batalha para evoluir",
"cobblemon.ui.pokedex.requirement.friendship.tooltip": "Requer no mínimo %1$s de amizade",
"cobblemon.ui.pokedex.requirement.has_move.tooltip": "Precisa conhecer o movimento %1$s",
"cobblemon.ui.pokedex.requirement.has_move_type.tooltip": "Precisa conhecer um movimento do tipo %1$s",
"cobblemon.ui.pokedex.requirement.held_item.tooltip": "Precisa estar segurando %1$s",
"cobblemon.ui.pokedex.requirement.level.tooltip.min": "Evolui ao ultrapassar o nível %1$s",
"cobblemon.ui.pokedex.requirement.level.tooltip.between": "Evoluiu entre os níveis %1$s e %2$s",
"cobblemon.ui.pokedex.requirement.moon_phase.tooltip": "Precisa evoluir na fase %1$s da lua",
"cobblemon.ui.pokedex.requirement.nature.toxtricity_amped": "Precisa ter a natureza §aDestemida§r, §aValente§r, §aRígida§r, §aTeimosa§r, §aDócil§r, §aInquieta§r, §aRelaxada§r, §aApressada§r, §aAlegre§r, §aInguênua§r, §aImprudente§r, §aAtrevida§r, ou §aPeculiar§r",
"cobblemon.ui.pokedex.requirement.nature.toxtricity_low_key": "Precisa ter a natureza §aSolitária§r, §aCorajosa§r, §aDescontraída§r, §aTímida§r, §aSéria§r, §aModesta§r, §aMansa§r, §aQuieta§r, §aAtrapalhada§r, §aCalma§r, §aGentil§r, ou §aCuidadosa§r",
"cobblemon.ui.pokedex.requirement.negate.tooltip": "Não: %1$s",
"cobblemon.ui.pokedex.requirement.nickname.malamar": "Precisa se chamar §aDinnerbone§r ou §aGrumm§r",
"cobblemon.ui.pokedex.requirement.party_member.anticondition.tooltip": "Equipe não pode ter um Pokémon com %1$s",
"cobblemon.ui.pokedex.requirement.party_member.tooltip": "Equipe precisa ter um Pokémon com %1$s",
"cobblemon.ui.pokedex.requirement.pokemon_properties.tooltip": "Precisa estar %1$s",
"cobblemon.ui.pokedex.requirement.properties.and": "%1$s e %2$s",
"cobblemon.ui.pokedex.requirement.properties.custom.cocoon_species": "Casulo %1$s",
"cobblemon.ui.pokedex.requirement.properties.held_item": "Segurando %1$s",
"cobblemon.ui.pokedex.requirement.properties.int_feature": "%1$s %2$s",
"cobblemon.ui.pokedex.requirement.properties.nature": "Natureza %1$s",
"cobblemon.ui.pokedex.requirement.properties.nickname": "Nomeado %1$s",
"cobblemon.ui.pokedex.requirement.properties.type": "Tipo %1$s",
"cobblemon.ui.pokedex.requirement.property_range.tooltip": "Requer %1$s entre %2$s e %3$s",
"cobblemon.ui.pokedex.requirement.recoil.tooltip": "Precisa sofrer %1$s unidades de recuo em batalha",
"cobblemon.ui.pokedex.requirement.stat_compare.tooltip": "Precisa ter seu %1$s acima de %2$s",
"cobblemon.ui.pokedex.requirement.stat_equal.tooltip": "Precisa ter seu %1$s igual ao seu %2$s",
"cobblemon.ui.pokedex.requirement.structure.anticondition.tooltip": "Não pode estar na estrutura %1$s",
"cobblemon.ui.pokedex.requirement.structure.both.tooltip": "Precisa estar na estrutura %1$s e não na estrutura %2$s",
"cobblemon.ui.pokedex.requirement.structure.tooltip": "Precisa estar na estrutura %1$s",
"cobblemon.ui.pokedex.requirement.time_range.tooltip": "Precisa evoluir durante %1$s",
"cobblemon.ui.pokedex.requirement.use_move.tooltip": "Precisa usar o movimento %1$s em batalha",
"cobblemon.ui.pokedex.requirement.weather.tooltip.raining": "Precisa estar na chuva para evoluir",
"cobblemon.ui.pokedex.requirement.weather.tooltip.thundering": "Precisa estar em uma tempestade para evoluir",
"cobblemon.ui.moon_phase.full_moon": "Lua Cheia",
"cobblemon.ui.moon_phase.waning_gibbous": "Crescente Gibosa",
"cobblemon.ui.moon_phase.third_quarter": "Quarto Crescente",
"cobblemon.ui.moon_phase.waning_crescent": "Crescente",
"cobblemon.ui.moon_phase.new_moon": "Lua Nova",
"cobblemon.ui.moon_phase.waxing_crescent": "Minguante",
"cobblemon.ui.moon_phase.first_quarter": "Quarto Minguante",
"cobblemon.ui.moon_phase.waxing_gibbous": "Minguante Gibosa",
"cobblemon.ui.time_range.any": "Qualquer",
"cobblemon.ui.time_range.day": "Dia",
"cobblemon.ui.time_range.night": "Noite",
"cobblemon.ui.time_range.noon": "Meio-dia",
"cobblemon.ui.time_range.midnight": "Meia-noite",
"cobblemon.ui.time_range.dawn": "Alvorecer",
"cobblemon.ui.time_range.dusk": "Entardecer",
"cobblemon.ui.time_range.twilight": "Crepúsculo",
"cobblemon.ui.time_range.morning": "Manhã",
"cobblemon.ui.time_range.afternoon": "Tarde",
"cobblemon.ui.time_range.predawn": "Pré-amanhecer",
"cobblemon.ui.time_range.evening": "Tardinha",
"cobblemon.subtitle.item.bright_powder.use": "Pó Brilhante ilumina",
"cobblemon.config.ui.type_gem_max_connected": "Máximo de Blocos de Gema de Tipo Conectados",
"cobblemon.config.ui.type_gem_min_growth": "Mínimo de Crescimento de Gema de Tipo",
"cobblemon.config.ui.type_gem_growth_chance": "Chance de Crescimento de Gema de Tipo",
"cobblemon.config.ui.type_gem_initial_expansion_cycles": "Cíclos de Expansão Iniciais de Gemas de Tipo",
"cobblemon.battle.activate.ficklebeam": "%1$s vai com tudo neste próximo ataque!",
"tag.item.cobblemon.oricorio_flowers": "Flores de Néctar",
"tag.item.cobblemon.terrain_plants": "Plantas de Terreno",
"tag.item.cobblemon.tall_flowers": "Flores Altas",
"tag.worldgen.biome.cobblemon.evolution.regional.bergmite_hisuibiome": "Hisuiano",
"tag.worldgen.biome.cobblemon.evolution.regional.bergmite_kalosbiome": "Kalosiano",
"tag.worldgen.biome.cobblemon.evolution.regional.cubone_alolabiome": "Alolano",
"tag.worldgen.biome.cobblemon.evolution.regional.cubone_kantobiome": "Kantoniano",
"tag.worldgen.biome.cobblemon.evolution.regional.dartrix_alolabiome": "Alolano",
"tag.worldgen.biome.cobblemon.evolution.regional.dartrix_hisuibiome": "Hisuiano",
"tag.worldgen.biome.cobblemon.evolution.regional.dewott_hisuibiome": "Hisuiano",
"tag.worldgen.biome.cobblemon.evolution.regional.dewott_unovabiome": "Unovano",
"tag.worldgen.biome.cobblemon.evolution.regional.exeggcute_alolabiome": "Alolano",
"tag.worldgen.biome.cobblemon.evolution.regional.exeggcute_kantobiome": "Kantoniano",
"tag.worldgen.biome.cobblemon.evolution.regional.goomy_hisuibiome": "Hisuiano",
"tag.worldgen.biome.cobblemon.evolution.regional.goomy_kalosbiome": "Kalosiano",
"tag.worldgen.biome.cobblemon.evolution.regional.koffing_galarbiome": "Galariano",
"tag.worldgen.biome.cobblemon.evolution.regional.koffing_kantobiome": "Kantoniano",
"tag.worldgen.biome.cobblemon.evolution.regional.mimejr_galarbiome": "Galariano",
"tag.worldgen.biome.cobblemon.evolution.regional.mimejr_sinnohbiome": "Sinnohano",
"tag.worldgen.biome.cobblemon.evolution.regional.petilil_hisuibiome": "Hisuiano",
"tag.worldgen.biome.cobblemon.evolution.regional.petilil_unovabiome": "Unovano",
"tag.worldgen.biome.cobblemon.evolution.regional.pikachu_alolabiome": "Alolano",
"tag.worldgen.biome.cobblemon.evolution.regional.pikachu_kantobiome": "Kantoniano",
"tag.worldgen.biome.cobblemon.evolution.regional.quilava_hisuibiome": "Hisuiano",
"tag.worldgen.biome.cobblemon.evolution.regional.quilava_johtobiome": "Johtoniano",
"tag.worldgen.biome.cobblemon.evolution.regional.rufflet_hisuibiome": "Hisuiano",
"tag.worldgen.biome.cobblemon.evolution.regional.rufflet_unovabiome": "Unovano"
"cobblemon.species.baxcalibur-mega.desc": "A lâmina dorsal de Baxcalibur ficou ainda maior graças à Mega Evolução. Esse Pokémon dispara feixes do cabo localizado em seu peito."
}
@@ -9021,34 +9021,5 @@
"cobblemon.config.ui.world_spawning_blocklist.tooltip": "Миры, в которых отключается принцип появления покемонов.",
"advancements.cobblemon.obtain_tm.description": "Найдите или напечатайте ТМ",
"cobblemon.species.victreebel-mega.desc": "В результате Мега эволюции объём кислоты у этого покемона увеличился, заполняя весь его рот. Если он не будет осторожен, кислота переполнится и выльется наружу.",
"cobblemon.ui.pokedex.info.form.victreebel-mega": "Мега Виктрибелл",
"itemGroup.cobblemon.tm_item": "Технические машины",
"block.cobblemon.pomohana": "Помохана",
"block.cobblemon.pauvillea": "Па'увилия",
"block.cobblemon.lobaila": "Лобалия",
"block.cobblemon.wistensu": "Вистенсу",
"block.cobblemon.voltaconia": "Вольтакония",
"block.cobblemon.verdroot": "Вердрут",
"block.cobblemon.lucibell": "Люсибель",
"block.cobblemon.mistleaf": "Мистлиф",
"cobblemon.ui.pokedex.info.evolution_tree": "Древо эволюции",
"cobblemon.ui.pokedex.evolution.item_interact.tooltip": "Требуется %1$s для эволюции",
"cobblemon.ui.pokedex.evolution.trade.tooltip.with_species": "Эволюционирует при обмене с %1$s",
"cobblemon.ui.pokedex.evolution.trade.tooltip.with_any_species": "Эволюционирует при обмене",
"cobblemon.ui.pokedex.evolution.shedder.tooltip": "Также требует запасной покебол и свободное место в команде",
"cobblemon.ui.pokedex.evolution.or": "ИЛИ",
"cobblemon.ui.pokedex.evolution.one_of": "Один из:",
"cobblemon.ui.pokedex.requirement.advancement.tooltip": "У игрока должно быть достижение %1$s",
"cobblemon.ui.pokedex.requirement.battle_critical_hits.tooltip": "Должен попасть %1$s критическими ударами в битве",
"cobblemon.ui.pokedex.requirement.biome.anticondition.tooltip": "Не должен быть в %1$s биоме",
"cobblemon.ui.pokedex.requirement.biome.both.tooltip": "Должен быть в %1$s биоме и не в %2$s биоме",
"cobblemon.ui.pokedex.requirement.biome.tooltip": "Должен быть в %1$s биоме",
"cobblemon.ui.pokedex.requirement.blocks_traveled.tooltip": "Должен пройти %1$s блоков",
"cobblemon.ui.pokedex.requirement.damage_taken.tooltip": "Должен получить %1$s урона в битве без поражения",
"cobblemon.ui.pokedex.requirement.defeat.tooltip": "Должен победить против %1$s в битве для эволюции",
"cobblemon.ui.pokedex.requirement.friendship.tooltip": "Требует как минимум %1$s дружбы",
"cobblemon.ui.pokedex.requirement.has_move.tooltip": "Должен знать приём %1$s",
"cobblemon.ui.pokedex.requirement.has_move_type.tooltip": "Должен знать приём %1$s типа",
"cobblemon.ui.pokedex.requirement.held_item.tooltip": "Должен удерживать %1$s",
"cobblemon.ui.pokedex.requirement.level.tooltip.min": "Эволюционирует начиная с %1$s уровня"
"cobblemon.ui.pokedex.info.form.victreebel-mega": "Мега Виктрибелл"
}
@@ -157,4 +157,6 @@ transitive-accessible method net/minecraft/client/model/HumanoidModel setupAttac
transitive-accessible method net/minecraft/client/model/HumanoidModel poseRightArm (Lnet/minecraft/world/entity/LivingEntity;)V
transitive-accessible method net/minecraft/client/model/HumanoidModel poseLeftArm (Lnet/minecraft/world/entity/LivingEntity;)V
transitive-accessible method net/minecraft/world/level/block/BaseEntityBlock createTickerHelper (Lnet/minecraft/world/level/block/entity/BlockEntityType;Lnet/minecraft/world/level/block/entity/BlockEntityType;Lnet/minecraft/world/level/block/entity/BlockEntityTicker;)Lnet/minecraft/world/level/block/entity/BlockEntityTicker;
transitive-accessible method net/minecraft/world/level/block/BaseEntityBlock createTickerHelper (Lnet/minecraft/world/level/block/entity/BlockEntityType;Lnet/minecraft/world/level/block/entity/BlockEntityType;Lnet/minecraft/world/level/block/entity/BlockEntityTicker;)Lnet/minecraft/world/level/block/entity/BlockEntityTicker;
transitive-accessible class net/minecraft/server/level/ServerPlayer$RespawnPosAngle
@@ -1,6 +1,6 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "medicines",
"category": "misc",
"ingredients": [
{
"item": "cobblemon:exp_candy_m"
@@ -1,6 +1,6 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "medicines",
"category": "misc",
"ingredients": [
{
"item": "cobblemon:exp_candy_s"
@@ -1,6 +1,6 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "medicines",
"category": "misc",
"ingredients": [
{
"item": "cobblemon:exp_candy_xs"
@@ -1,6 +1,6 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "medicines",
"category": "misc",
"ingredients": [
{
"item": "cobblemon:exp_candy_l"
@@ -1,6 +1,6 @@
{
"type": "cobblemon:cooking_pot_shapeless",
"category": "medicines",
"category": "misc",
"ingredients": [
{
"item": "minecraft:sculk"
@@ -56,7 +56,7 @@ public class RecipeBookCategoriesMixin {
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_FOODS", $VALUES.length + 1, new ItemStack(CobblemonItems.LEEK_AND_POTATO_STEW)));
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_MEDICINES", $VALUES.length + 2, new ItemStack(CobblemonItems.POTION)));
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_COMPLEX_DISHES", $VALUES.length + 3, new ItemStack(CobblemonItems.APRIJUICE_RED)));
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_MISC", $VALUES.length + 4, new ItemStack(CobblemonItems.PROTEIN)));
types.add(cobblemon$createCategory("COBBLEMON_COOKING_POT_MISC", $VALUES.length + 4, new ItemStack(CobblemonItems.HEALTH_CANDY)));
$VALUES = types.toArray(RecipeBookCategories[]::new);
}
@@ -11,27 +11,22 @@ package com.cobblemon.mod.fabric.mixin;
import com.cobblemon.mod.common.platform.events.PlatformEvents;
import com.cobblemon.mod.common.platform.events.ServerPlayerTickEvent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Player.class)
public class PlayerMixin {
@Mixin(ServerPlayer.class)
public class ServerPlayerMixin {
@Inject(method = "tick", at = @At("HEAD"))
private void onPreTick(CallbackInfo ci) {
Player player = (Player)(Object)this;
if (player instanceof ServerPlayer) {
PlatformEvents.SERVER_PLAYER_TICK_PRE.emit(new ServerPlayerTickEvent.Pre((ServerPlayer)player));
}
ServerPlayer player = (ServerPlayer)(Object)this;
PlatformEvents.SERVER_PLAYER_TICK_PRE.emit(new ServerPlayerTickEvent.Pre(player));
}
@Inject(method = "tick", at = @At("TAIL"))
private void onPostTick(CallbackInfo ci) {
Player player = (Player)(Object)this;
if (player instanceof ServerPlayer) {
PlatformEvents.SERVER_PLAYER_TICK_POST.emit(new ServerPlayerTickEvent.Post((ServerPlayer)player));
}
ServerPlayer player = (ServerPlayer)(Object)this;
PlatformEvents.SERVER_PLAYER_TICK_POST.emit(new ServerPlayerTickEvent.Post(player));
}
}
@@ -37,6 +37,7 @@ import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback
import net.fabricmc.fabric.api.entity.event.v1.EntitySleepEvents
import net.fabricmc.fabric.api.entity.event.v1.ServerEntityWorldChangeEvents
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents
import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents
import net.fabricmc.fabric.api.event.player.UseBlockCallback
@@ -175,6 +176,7 @@ object CobblemonFabric : CobblemonImplementation {
ServerPlayConnectionEvents.DISCONNECT.register { handler, server ->
if (!server.isStopped) server.executeIfPossible { PlatformEvents.SERVER_PLAYER_LOGOUT.post(ServerPlayerEvent.Logout(handler.player)) }
}
ServerPlayerEvents.AFTER_RESPAWN.register { oldPlayer, newPlayer, alive -> PlatformEvents.PLAYER_RESPAWN.post(ServerPlayerEvent.Respawn(newPlayer)) }
ServerLivingEntityEvents.ALLOW_DEATH.register { entity, _, _ ->
if (entity is ServerPlayer) {
PlatformEvents.PLAYER_DEATH.postThen(
@@ -15,7 +15,7 @@
"EntityMixin",
"FabricBrewingStandMenuMixin",
"FabricSoundEngineMixin",
"PlayerMixin",
"ServerPlayerMixin",
"RecipeBookSettingsMixin",
"RecipeBookTypeMixin",
"ServerEntityMixin"
@@ -34,5 +34,5 @@ object CobblemonEnumExtensions {
Supplier<List<ItemStack>> { listOf(ItemStack(CobblemonItems.APRIJUICE_RED)) as List<ItemStack> })
@JvmField
val COOKING_POT_MISC = EnumProxy(RecipeBookCategories::class.java,
Supplier<List<ItemStack>> { listOf(ItemStack(CobblemonItems.PROTEIN)) as List<ItemStack> })
Supplier<List<ItemStack>> { listOf(ItemStack(CobblemonItems.HEALTH_CANDY)) as List<ItemStack> })
}
@@ -24,7 +24,7 @@ import net.neoforged.neoforge.event.server.ServerAboutToStartEvent
import net.neoforged.neoforge.event.server.ServerStartedEvent
import net.neoforged.neoforge.event.server.ServerStoppedEvent
import net.neoforged.neoforge.event.server.ServerStoppingEvent
import net.neoforged.neoforge.event.tick.PlayerTickEvent
import net.neoforged.neoforge.event.tick.EntityTickEvent
object NeoForgePlatformEventHandler {
@@ -53,14 +53,14 @@ object NeoForgePlatformEventHandler {
}
@SubscribeEvent
fun prePlayerTick(e: PlayerTickEvent.Pre) {
fun prePlayerTick(e: EntityTickEvent.Pre) {
if (e.entity is ServerPlayer) {
PlatformEvents.SERVER_PLAYER_TICK_PRE.post(ServerPlayerTickEvent.Pre(e.entity as ServerPlayer))
}
}
@SubscribeEvent
fun postPlayerTick(e: PlayerTickEvent.Post) {
fun postPlayerTick(e: EntityTickEvent.Post) {
if (e.entity is ServerPlayer) {
PlatformEvents.SERVER_PLAYER_TICK_POST.post(ServerPlayerTickEvent.Post(e.entity as ServerPlayer))
}
@@ -98,6 +98,12 @@ object NeoForgePlatformEventHandler {
)
}
@SubscribeEvent
fun onRespawn(e: PlayerEvent.PlayerRespawnEvent) {
val player = e.entity as? ServerPlayer ?: return
PlatformEvents.PLAYER_RESPAWN.post(ServerPlayerEvent.Respawn(player))
}
@SubscribeEvent
fun onRightClickBlock(e: PlayerInteractEvent.RightClickBlock) {
val player = e.entity as? ServerPlayer ?: return