From ce11e6b44a4e16d3dce4d82da268007c40126623 Mon Sep 17 00:00:00 2001 From: celeste Date: Sun, 23 Jul 2023 12:02:39 -0600 Subject: [PATCH] Fix hurt sounds requiring the mod server-side as well --- .../java/com/wildfire/main/GenderPlayer.java | 20 ++-- .../wildfire/main/WildfireEventHandler.java | 70 ------------- .../com/wildfire/main/WildfireGender.java | 1 - .../wildfire/main/WildfireGenderServer.java | 3 + .../com/wildfire/main/WildfireSounds.java | 11 +-- .../wildfire/mixins/LivingEntityMixin.java | 98 +++++++++++++++++++ .../mixins/PlayerEntityServerMixin.java | 77 --------------- .../assets/wildfire_gender/lang/cs_cz.json | 2 - .../assets/wildfire_gender/lang/de_ch.json | 2 - .../assets/wildfire_gender/lang/de_de.json | 2 - .../assets/wildfire_gender/lang/en_us.json | 2 - .../assets/wildfire_gender/lang/fr_fr.json | 2 - .../assets/wildfire_gender/lang/lol_us.json | 2 - .../assets/wildfire_gender/sounds.json | 11 +-- .../resources/wildfire_gender.mixins.json | 2 +- 15 files changed, 120 insertions(+), 185 deletions(-) create mode 100644 src/main/java/com/wildfire/mixins/LivingEntityMixin.java delete mode 100644 src/main/java/com/wildfire/mixins/PlayerEntityServerMixin.java diff --git a/src/main/java/com/wildfire/main/GenderPlayer.java b/src/main/java/com/wildfire/main/GenderPlayer.java index bccb68e5..d344b694 100644 --- a/src/main/java/com/wildfire/main/GenderPlayer.java +++ b/src/main/java/com/wildfire/main/GenderPlayer.java @@ -22,9 +22,11 @@ import com.wildfire.main.config.ConfigKey; import com.wildfire.main.config.Configuration; import com.wildfire.physics.BreastPhysics; +import net.minecraft.sound.SoundEvent; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import javax.annotation.Nullable; import java.util.UUID; import java.util.function.Consumer; @@ -257,26 +259,30 @@ public enum SyncStatus { } public enum Gender { - FEMALE(Text.translatable("wildfire_gender.label.female").formatted(Formatting.LIGHT_PURPLE)), - MALE(Text.translatable("wildfire_gender.label.male").formatted(Formatting.BLUE)), - OTHER(Text.translatable("wildfire_gender.label.other").formatted(Formatting.GREEN)); + FEMALE(Text.translatable("wildfire_gender.label.female").formatted(Formatting.LIGHT_PURPLE), true, WildfireSounds.FEMALE_HURT), + MALE(Text.translatable("wildfire_gender.label.male").formatted(Formatting.BLUE), false, null), + OTHER(Text.translatable("wildfire_gender.label.other").formatted(Formatting.GREEN), true, WildfireSounds.FEMALE_HURT); private final Text name; + private final boolean canHaveBreasts; + private final @Nullable SoundEvent hurtSound; - Gender(Text name) { + Gender(Text name, boolean canHaveBreasts, @Nullable SoundEvent hurtSound) { this.name = name; + this.canHaveBreasts = canHaveBreasts; + this.hurtSound = hurtSound; } public Text getDisplayName() { return name; } - public boolean hasFemaleHurtSounds() { - return this == FEMALE || this == OTHER; + public @Nullable SoundEvent getHurtSound() { + return hurtSound; } public boolean canHaveBreasts() { - return this != MALE; + return canHaveBreasts; } } } diff --git a/src/main/java/com/wildfire/main/WildfireEventHandler.java b/src/main/java/com/wildfire/main/WildfireEventHandler.java index 7032caac..e7a03a6e 100644 --- a/src/main/java/com/wildfire/main/WildfireEventHandler.java +++ b/src/main/java/com/wildfire/main/WildfireEventHandler.java @@ -22,8 +22,6 @@ import com.wildfire.main.networking.PacketSendGenderInfo; import com.wildfire.main.networking.PacketSync; -import java.util.Random; -import java.util.Set; import java.util.UUID; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents; @@ -34,12 +32,7 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.sound.EntityTrackingSoundInstance; import net.minecraft.client.util.InputUtil; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.sound.SoundCategory; -import net.minecraft.sound.SoundEvent; -import net.minecraft.sound.SoundEvents; import net.minecraft.util.Identifier; import org.lwjgl.glfw.GLFW; @@ -112,72 +105,9 @@ public static void registerClientEvents() { } }); - //Receive hurt - - ClientPlayNetworking.registerGlobalReceiver(new Identifier(WildfireGender.MODID, "hurt"), - (client, handler, buf, responseSender) -> { - UUID uuid = buf.readUuid(); - GenderPlayer.Gender gender = buf.readEnumConstant(GenderPlayer.Gender.class); - boolean hurtSounds = buf.readBoolean(); - - //Vector3d pos = new Vector3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); - - SoundEvent hurtSound = null; - if(gender == GenderPlayer.Gender.FEMALE) { - hurtSound = Math.random() > 0.5f ? WildfireSounds.FEMALE_HURT1 : WildfireSounds.FEMALE_HURT2; - } - if(hurtSound == null) return; - - if(hurtSounds) { - PlayerEntity ent = MinecraftClient.getInstance().world.getPlayerByUuid(uuid); - if (ent != null) { - long randomLong = new Random().nextLong(0L,1L); - final SoundEvent hurtSound2 = hurtSound; - // ensures it's executed in the main thread - client.execute(() -> { - client.getSoundManager().play(new EntityTrackingSoundInstance(hurtSound2, SoundCategory.PLAYERS, 1f, 1f, ent, randomLong)); - }); - } - } - }); - ClientPlayNetworking.registerGlobalReceiver(new Identifier(WildfireGender.MODID, "sync"), (client, handler, buf, responseSender) -> { PacketSync.handle(client, handler, buf, responseSender); }); } - - //TODO: Eventually we may want to replace this with a map or something and replace things like drowning sounds with other drowning sounds - private final Set playerHurtSounds = Set.of(SoundEvents.ENTITY_PLAYER_HURT, - SoundEvents.ENTITY_PLAYER_HURT_DROWN, - SoundEvents.ENTITY_PLAYER_HURT_FREEZE, - SoundEvents.ENTITY_PLAYER_HURT_ON_FIRE, - SoundEvents.ENTITY_PLAYER_HURT_SWEET_BERRY_BUSH - ); -/* - @SubscribeEvent(priority = EventPriority.LOWEST) - public void onPlaySound(PlaySoundAtEntityEvent event) { - if (playerHurtSounds.contains(event.getSound()) && event.getEntity() instanceof Player p && p.level.isClientSide) { - //Cancel as we handle all hurt sounds manually so that we can - event.setCanceled(true); - SoundEvent soundEvent = event.getSound(); - if (p.hurtTime == p.hurtDuration && p.hurtTime > 0) { - //Note: We check hurtTime == hurtDuration and hurtTime > 0 or otherwise when the server sends a hurt sound to the client - // and the client will check itself instead of the player who was damaged. - GenderPlayer plr = WildfireGender.getPlayerById(p.getUUID()); - if (plr != null && plr.hasHurtSounds() && plr.getGender().hasFemaleHurtSounds()) { - //If the player who produced the hurt sound is a female sound replace it - soundEvent = Math.random() > 0.5f ? WildfireSounds.FEMALE_HURT1 : WildfireSounds.FEMALE_HURT2; - } - } else if (p.getUUID().equals(Minecraft.getInstance().player.getUUID())) { - //Skip playing remote hurt sounds. Note: sounds played via /playsound will not be intercepted - // as they are played directly - //Note: This might behave slightly strangely if a mod is manually firing a player damage sound - // only on the server and not also on the client - //TODO: Ideally we would fix that edge case but I find it highly unlikely it will ever actually occur - return; - } - p.level.playLocalSound(p.getX(), p.getY(), p.getZ(), soundEvent, event.getCategory(), event.getVolume(), event.getPitch(), false); - } - }*/ } diff --git a/src/main/java/com/wildfire/main/WildfireGender.java b/src/main/java/com/wildfire/main/WildfireGender.java index 792a803e..17a07f73 100644 --- a/src/main/java/com/wildfire/main/WildfireGender.java +++ b/src/main/java/com/wildfire/main/WildfireGender.java @@ -39,7 +39,6 @@ public class WildfireGender implements ClientModInitializer { @Override public void onInitializeClient() { WildfireEventHandler.registerClientEvents(); - WildfireSounds.register(); } @Nullable diff --git a/src/main/java/com/wildfire/main/WildfireGenderServer.java b/src/main/java/com/wildfire/main/WildfireGenderServer.java index 0db83d77..5c0ab908 100644 --- a/src/main/java/com/wildfire/main/WildfireGenderServer.java +++ b/src/main/java/com/wildfire/main/WildfireGenderServer.java @@ -27,6 +27,9 @@ public class WildfireGenderServer implements ModInitializer { @Override public void onInitialize() { + // while this class is named 'Server', this is actually a common code path, + // so we can safely register here for both sides. + WildfireSounds.register(); ServerPlayNetworking.registerGlobalReceiver(new Identifier(WildfireGender.MODID, "send_gender_info"), (server, playerEntity, handler, buf, responseSender) -> { PacketSendGenderInfo.handle(server, playerEntity, handler, buf, responseSender); diff --git a/src/main/java/com/wildfire/main/WildfireSounds.java b/src/main/java/com/wildfire/main/WildfireSounds.java index e50176e9..6583e978 100644 --- a/src/main/java/com/wildfire/main/WildfireSounds.java +++ b/src/main/java/com/wildfire/main/WildfireSounds.java @@ -24,14 +24,9 @@ import net.minecraft.util.Identifier; public class WildfireSounds { - private static Identifier SND1 = new Identifier(WildfireGender.MODID, "female_hurt1"); - public static SoundEvent FEMALE_HURT1 = SoundEvent.of(SND1); + public static final SoundEvent FEMALE_HURT = SoundEvent.of(new Identifier(WildfireGender.MODID, "female_hurt")); - private static Identifier SND2 = new Identifier(WildfireGender.MODID, "female_hurt2"); - public static SoundEvent FEMALE_HURT2 = SoundEvent.of(SND2); - - public static void register() { - Registry.register(Registries.SOUND_EVENT, SND1, FEMALE_HURT1); - Registry.register(Registries.SOUND_EVENT, SND2, FEMALE_HURT2); + protected static void register() { + Registry.register(Registries.SOUND_EVENT, FEMALE_HURT.getId(), FEMALE_HURT); } } diff --git a/src/main/java/com/wildfire/mixins/LivingEntityMixin.java b/src/main/java/com/wildfire/mixins/LivingEntityMixin.java new file mode 100644 index 00000000..96c8e79b --- /dev/null +++ b/src/main/java/com/wildfire/mixins/LivingEntityMixin.java @@ -0,0 +1,98 @@ +/* + Wildfire's Female Gender Mod is a female gender mod created for Minecraft. + Copyright (C) 2023 WildfireRomeo + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +package com.wildfire.mixins; + +import com.wildfire.main.GenderPlayer; +import com.wildfire.main.WildfireGender; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.sound.SoundEvent; +import org.spongepowered.asm.mixin.Mixin; +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; + +/* + * A note on why this implementation in particular was chosen: + * + * While this could be reduced down to one mixin (the `#onDamaged(DamageSource)` one in particular), and forego any sort + * of server-side handling, this is being done as (at least as of when this is being written,) the mod fails to ever + * perform an initial sync upon a player joining a dedicated server; as such, we're using client- *and* server-side mixins + * to provide some level of consistency, even if syncing isn't consistent. + * + * We're additionally playing *alongside* the vanilla hurt sound, largely for the sake of accessibility, as the vanilla + * hurt sound may provide important context as for why a player is taking damage, which could prove especially helpful + * for players with poor/no eyesight. + * + * Additionally, completely replacing the hurt sound server-side would essentially require the mod client-side as well + * to hear *any* hurt sounds from players with this setting enabled, which rules out mixins to methods such as + * `PlayerEntity#getHurtSound(DamageSource)`. + */ +@Mixin(LivingEntity.class) +public class LivingEntityMixin { + @Environment(EnvType.CLIENT) + @Inject( + method = "onDamaged", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/LivingEntity;playSound(Lnet/minecraft/sound/SoundEvent;FF)V" + ) + ) + public void clientGenderHurtSound(DamageSource damageSource, CallbackInfo ci) { + MinecraftClient client = MinecraftClient.getInstance(); + if(client.player == null || client.world == null) return; + + if((LivingEntity)(Object)this instanceof PlayerEntity player) { + if(player.getWorld().isClient() && player.getUuid().equals(client.player.getUuid())) { + this.playGenderHurtSound(player); + } + } + } + + @Inject( + method = "damage", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/LivingEntity;playHurtSound(Lnet/minecraft/entity/damage/DamageSource;)V" + ) + ) + public void serverGenderHurtSound(DamageSource source, float amount, CallbackInfoReturnable cir) { + if((LivingEntity)(Object)this instanceof PlayerEntity player) { + if(!player.getWorld().isClient()) this.playGenderHurtSound(player); + } + } + + @Unique + private void playGenderHurtSound(PlayerEntity player) { + GenderPlayer genderPlayer = WildfireGender.getPlayerById(player.getUuid()); + if(genderPlayer == null || !genderPlayer.hasHurtSounds()) return; + + SoundEvent hurtSound = genderPlayer.getGender().getHurtSound(); + if(hurtSound != null) { + float pitch = (player.getRandom().nextFloat() - player.getRandom().nextFloat()) * 0.2F + 1.0F; + player.playSound(hurtSound, 1f, pitch); + } + } +} diff --git a/src/main/java/com/wildfire/mixins/PlayerEntityServerMixin.java b/src/main/java/com/wildfire/mixins/PlayerEntityServerMixin.java deleted file mode 100644 index c9e40803..00000000 --- a/src/main/java/com/wildfire/mixins/PlayerEntityServerMixin.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - Wildfire's Female Gender Mod is a female gender mod created for Minecraft. - Copyright (C) 2023 WildfireRomeo - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -package com.wildfire.mixins; -import com.mojang.authlib.GameProfile; -import com.wildfire.main.GenderPlayer; -import com.wildfire.main.WildfireGender; -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; -import net.fabricmc.fabric.api.networking.v1.PlayerLookup; -import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.damage.DamageSource; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -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(value = PlayerEntity.class, priority = 900) -public abstract class PlayerEntityServerMixin extends LivingEntity { - - - public PlayerEntityServerMixin(World world, BlockPos pos, float yaw, GameProfile profile) { - super(EntityType.PLAYER, world); - } - - @Inject(method = "applyDamage", at = @At("HEAD"), cancellable = true) - private void onDamagePlayer(DamageSource source, float amount, CallbackInfo ci) { - if (!this.isInvulnerableTo(source)) { - PlayerEntity self = (PlayerEntity) (Object) this; - - amount = this.applyArmorToDamage(source, amount); - amount = this.modifyAppliedDamage(source, amount); - float f = amount; - amount = Math.max(amount - this.getAbsorptionAmount(), 0.0F); - - if(amount != 0.0f) { - //send to client hurt sound? - GenderPlayer plr = WildfireGender.getPlayerById(self.getUuid()); - if (plr != null) { - PacketByteBuf buf = PacketByteBufs.create(); - buf.writeUuid(plr.uuid); - buf.writeEnumConstant(plr.getGender()); - buf.writeBoolean(plr.hasHurtSounds()); - for (ServerPlayerEntity player : PlayerLookup.tracking((ServerWorld) getWorld(), getWorld().getPlayerByUuid(plr.uuid).getBlockPos())) { - if (ServerPlayNetworking.canSend(player, new Identifier("wildfire_gender", "hurt"))) { - ServerPlayNetworking.send(player, new Identifier("wildfire_gender", "hurt"), buf); - } - } - } - } - } - } - -} \ No newline at end of file diff --git a/src/main/resources/assets/wildfire_gender/lang/cs_cz.json b/src/main/resources/assets/wildfire_gender/lang/cs_cz.json index b8a36ef6..360c76d2 100644 --- a/src/main/resources/assets/wildfire_gender/lang/cs_cz.json +++ b/src/main/resources/assets/wildfire_gender/lang/cs_cz.json @@ -2,8 +2,6 @@ "category.wildfire_gender.generic": "Wildfire's Female Gender Mod", "key.wildfire_gender.gender_menu": "Menu ženského pohlaví", - "wildfire_gender.hurt.female": "Zranění ženského hráče", - "wildfire_gender.player_list.title": "Female Gender Mod", "wildfire_gender.player_list.settings_button": "Nastavení", "wildfire_gender.player_list.sync_status": "Status synchronizace", diff --git a/src/main/resources/assets/wildfire_gender/lang/de_ch.json b/src/main/resources/assets/wildfire_gender/lang/de_ch.json index 0dc3a51a..b24d8971 100644 --- a/src/main/resources/assets/wildfire_gender/lang/de_ch.json +++ b/src/main/resources/assets/wildfire_gender/lang/de_ch.json @@ -2,8 +2,6 @@ "category.wildfire_gender.generic": "Wildfire's Wiiblicher Geschlects Mod", "key.wildfire_gender.gender_menu": "Geschlechtsmenu", - "wildfire_gender.hurt.female": "Spielerin nimmt schade", - "wildfire_gender.player_list.title": "Wiiblicher Geschlechts Mod", "wildfire_gender.player_list.settings_button": "Iistellige", "wildfire_gender.player_list.sync_status": "Synchronisierigsstatus", diff --git a/src/main/resources/assets/wildfire_gender/lang/de_de.json b/src/main/resources/assets/wildfire_gender/lang/de_de.json index d1466570..40bcfcf0 100644 --- a/src/main/resources/assets/wildfire_gender/lang/de_de.json +++ b/src/main/resources/assets/wildfire_gender/lang/de_de.json @@ -2,8 +2,6 @@ "category.wildfire_gender.generic": "Wildfire's Weibliche Geschlechtsmod", "key.wildfire_gender.gender_menu": "Geschlechtsmenü", - "wildfire_gender.hurt.female": "Spielerin nimmt schaden", - "wildfire_gender.player_list.title": "Weibliche Geschlechts Mod", "wildfire_gender.player_list.settings_button": "Einstellungen", "wildfire_gender.player_list.sync_status": "Synchronisierungsstatus", diff --git a/src/main/resources/assets/wildfire_gender/lang/en_us.json b/src/main/resources/assets/wildfire_gender/lang/en_us.json index 371d643b..2cffad15 100644 --- a/src/main/resources/assets/wildfire_gender/lang/en_us.json +++ b/src/main/resources/assets/wildfire_gender/lang/en_us.json @@ -3,8 +3,6 @@ "key.wildfire_gender.gender_menu": "Female Gender Menu", "toast.wildfire_gender.get_started": "Press '%s' to get started!", - "wildfire_gender.hurt.female": "Female Player Hurt", - "wildfire_gender.player_list.title": "Female Gender Mod", "wildfire_gender.player_list.settings_button": "Settings", "wildfire_gender.player_list.sync_status": "Sync Status", diff --git a/src/main/resources/assets/wildfire_gender/lang/fr_fr.json b/src/main/resources/assets/wildfire_gender/lang/fr_fr.json index 2e463d78..c0466b48 100644 --- a/src/main/resources/assets/wildfire_gender/lang/fr_fr.json +++ b/src/main/resources/assets/wildfire_gender/lang/fr_fr.json @@ -2,8 +2,6 @@ "category.wildfire_gender.generic": "Wildfire's Female Gender Mod", "key.wildfire_gender.gender_menu": "Menu Genre Féminin", - "wildfire_gender.hurt.female": "Joueur Féminin Blessé", - "wildfire_gender.player_list.title": "Female Gender Mod", "wildfire_gender.player_list.settings_button": "Paramètres", "wildfire_gender.player_list.sync_status": "Sync Statut", diff --git a/src/main/resources/assets/wildfire_gender/lang/lol_us.json b/src/main/resources/assets/wildfire_gender/lang/lol_us.json index 5ffe53f4..7e5d07e2 100644 --- a/src/main/resources/assets/wildfire_gender/lang/lol_us.json +++ b/src/main/resources/assets/wildfire_gender/lang/lol_us.json @@ -2,8 +2,6 @@ "category.wildfire_gender.generic": "Women Gunda Mood", "key.wildfire_gender.gender_menu": "Women Gunda Mano", - "wildfire_gender.hurt.female": "Women kat hurtz", - "wildfire_gender.player_list.title": "Women Gunda Mood", "wildfire_gender.player_list.settings_button": "Setinz", "wildfire_gender.player_list.sync_status": "Sinc stauz", diff --git a/src/main/resources/assets/wildfire_gender/sounds.json b/src/main/resources/assets/wildfire_gender/sounds.json index d156c254..fda4c354 100644 --- a/src/main/resources/assets/wildfire_gender/sounds.json +++ b/src/main/resources/assets/wildfire_gender/sounds.json @@ -1,12 +1,5 @@ { - "female_hurt1": { - "category": "block", - "subtitle": "wildfire_gender.hurt.female", - "sounds": [ "wildfire_gender:female_damage" ] - }, - "female_hurt2": { - "category": "block", - "subtitle": "wildfire_gender.hurt.female", - "sounds": [ "wildfire_gender:female_damage2" ] + "female_hurt": { + "sounds": [ "wildfire_gender:female_damage", "wildfire_gender:female_damage2" ] } } \ No newline at end of file diff --git a/src/main/resources/wildfire_gender.mixins.json b/src/main/resources/wildfire_gender.mixins.json index 514d97fc..e6dd8f4e 100644 --- a/src/main/resources/wildfire_gender.mixins.json +++ b/src/main/resources/wildfire_gender.mixins.json @@ -4,7 +4,7 @@ "package": "com.wildfire.mixins", "compatibilityLevel": "JAVA_17", "mixins": [ - "PlayerEntityServerMixin" + "LivingEntityMixin" ], "client": [ "PlayerEntityMixin",