fix playermolang sometimes failing when they die

Signed-off-by: Polymeta <4726322-polymeta@users.noreply.gitlab.com>
This commit is contained in:
Polymeta
2026-10-14 13:33:40 +01:00
parent bbc9a5e62e
commit 6f3894f27b
8 changed files with 32 additions and 15 deletions
+4
View File
@@ -36,9 +36,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`)
@@ -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()
@@ -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.
@@ -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"
@@ -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