Skip to content

Commit

Permalink
Add client-sided hurt sounds, remove now redundant hurt packet
Browse files Browse the repository at this point in the history
  • Loading branch information
celestialfault committed Apr 13, 2023
1 parent cf9fd80 commit b2abdc9
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 195 deletions.
67 changes: 0 additions & 67 deletions src/main/java/com/wildfire/main/ClientEventHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import com.wildfire.main.networking.PacketSendGenderInfo;
import com.wildfire.main.networking.PacketSync;

import java.util.Set;
import java.util.UUID;

import net.fabricmc.api.EnvType;
Expand All @@ -31,20 +30,12 @@
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.sound.EntityTrackingSoundInstance;
import net.minecraft.client.util.InputUtil;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf;
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;

Expand All @@ -58,7 +49,6 @@ public class ClientEventHandler {
public static void registerClientEvents() {
ClientEntityEvents.ENTITY_LOAD.register(ClientEventHandler::onEntityLoad);
ClientTickEvents.END_CLIENT_TICK.register(ClientEventHandler::onTick);
ClientPlayNetworking.registerGlobalReceiver(WildfireGender.id("hurt"), ClientEventHandler::hurtPacket);
ClientPlayNetworking.registerGlobalReceiver(WildfireGender.id("sync"), PacketSync::handle);
}

Expand Down Expand Up @@ -103,61 +93,4 @@ private static void onEntityLoad(Entity entity, ClientWorld world) {
WildfireGender.loadGenderInfoAsync(uuid, uuid.equals(MinecraftClient.getInstance().player.getUuid()));
}
}

private static void hurtPacket(MinecraftClient client, ClientPlayNetworkHandler handler, PacketByteBuf buf, PacketSender packetSender) {
if(client.world == null) {
WildfireGender.LOGGER.warn("Received hurt packet while the world was unset; discarding");
return;
}

PlayerEntity player = client.world.getPlayerByUuid(buf.readUuid());
if(player == null) return;
GenderPlayer.Gender gender = buf.readEnumConstant(GenderPlayer.Gender.class);
if(!buf.readBoolean()) return;

final SoundEvent hurtSound = (gender.hasFemaleHurtSounds()
? (Math.random() > 0.5f ? WildfireSounds.FEMALE_HURT1 : WildfireSounds.FEMALE_HURT2)
: null);
if(hurtSound == null) return;

client.execute(() -> {
long randomLong = player.getRandom().nextLong();
float pitch = (player.getRandom().nextFloat() - player.getRandom().nextFloat()) * 0.2F + 1.0F;
client.getSoundManager().play(new EntityTrackingSoundInstance(hurtSound, SoundCategory.PLAYERS, 1f, pitch, player, randomLong));
});
}

//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<SoundEvent> 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);
}
}*/
}
20 changes: 13 additions & 7 deletions src/main/java/com/wildfire/main/GenderPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -270,26 +272,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, null);

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;
public @Nullable SoundEvent getHurtSound() {
return hurtSound;
}

public boolean canHaveBreasts() {
return this != MALE;
return canHaveBreasts;
}
}
}
12 changes: 3 additions & 9 deletions src/main/java/com/wildfire/main/WildfireSounds.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,11 @@
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.sound.SoundEvent;
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 SoundEvent FEMALE_HURT = SoundEvent.of(WildfireGender.id("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);
}
}
82 changes: 82 additions & 0 deletions src/main/java/com/wildfire/mixins/LivingEntityMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
Wildfire's Female Gender Mod is a female gender mod created for Minecraft.
Copyright (C) 2022 WildfireRomeo
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 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 <https://www.gnu.org/licenses/>.
*/

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.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;

@Mixin(LivingEntity.class)
public class LivingEntityMixin {
@Environment(EnvType.CLIENT)
@Inject(
method = "handleStatus",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/LivingEntity;damage(Lnet/minecraft/entity/damage/DamageSource;F)Z"
)
)
public void wildfiregender$clientGenderHurtSound(byte status, CallbackInfo ci) {
if((LivingEntity)(Object)this instanceof PlayerEntity player) {
// Only act on the client player; the server will send the hurt sound separately for other players
// in the below mixin
if(!player.world.isClient() || player != MinecraftClient.getInstance().player) return;
wildfiregender$playHurtSound(player);
}
}

@Inject(
method = "damage",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/LivingEntity;playHurtSound(Lnet/minecraft/entity/damage/DamageSource;)V"
)
)
public void wildfiregender$serverGenderHurtSound(DamageSource source, float amount, CallbackInfoReturnable<Boolean> cir) {
if((LivingEntity)(Object)this instanceof PlayerEntity player) {
// While this is never called client-side for the client player due to ClientPlayerEntity overriding this
// method, it is called client-side for *other* players; as such, we need to check this to ensure we don't
// play double hurt sounds when the mod is installed on the server as well.
if(player.world.isClient()) return;
wildfiregender$playHurtSound(player);
}
}

private void wildfiregender$playHurtSound(PlayerEntity player) {
GenderPlayer genderPlayer = WildfireGender.getPlayerById(player.getUuid());
if(genderPlayer == null) 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);
}
}
}
24 changes: 4 additions & 20 deletions src/main/java/com/wildfire/mixins/PlayerEntityMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.wildfire.mixins;

import com.mojang.authlib.GameProfile;
import com.wildfire.api.IGenderArmor;
import com.wildfire.main.GenderPlayer;
Expand All @@ -37,27 +39,12 @@
@Environment(EnvType.CLIENT)
@Mixin(value = PlayerEntity.class, priority = 900)
public abstract class PlayerEntityMixin extends LivingEntity {

public float wfg_femaleBreast;
public float wfg_preBounce;

float bounceVel = 0;
float targetBounce = 0;
float preY = 0;

boolean justSneaking = false;
boolean alreadySleeping = false;

public PlayerEntityMixin(World world, BlockPos pos, float yaw, GameProfile profile) {
super(EntityType.PLAYER, world);
}

@Inject(at = @At("TAIL"), method = "tick")
public void onTick(CallbackInfo info) {
tickWildfire();
}

public void tickWildfire() {
public void wildfiregender$tickBreastPhysics(CallbackInfo info) {
if(!this.world.isClient()) return;
GenderPlayer aPlr = WildfireGender.getPlayerById(this.getUuid());
if(aPlr == null) return;
Expand All @@ -66,8 +53,5 @@ public void tickWildfire() {

aPlr.getLeftBreastPhysics().update(plr, armor);
aPlr.getRightBreastPhysics().update(plr, armor);


}

}
}
76 changes: 0 additions & 76 deletions src/main/java/com/wildfire/mixins/PlayerEntityServerMixin.java

This file was deleted.

0 comments on commit b2abdc9

Please sign in to comment.