superb-warfare/src/main/java/net/mcreator/superbwarfare/event/LivingEventHandler.java
2024-07-27 02:53:50 +08:00

251 lines
12 KiB
Java

package net.mcreator.superbwarfare.event;
import net.mcreator.superbwarfare.ModUtils;
import net.mcreator.superbwarfare.entity.Target1Entity;
import net.mcreator.superbwarfare.init.ModDamageTypes;
import net.mcreator.superbwarfare.init.ModItems;
import net.mcreator.superbwarfare.init.ModSounds;
import net.mcreator.superbwarfare.init.ModTags;
import net.mcreator.superbwarfare.item.gun.GunItem;
import net.mcreator.superbwarfare.network.TargetModVariables;
import net.mcreator.superbwarfare.network.message.ClientIndicatorMessage;
import net.mcreator.superbwarfare.network.message.PlayerGunKillMessage;
import net.mcreator.superbwarfare.tools.SoundTool;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundStopSoundPacket;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageType;
import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.LivingEquipmentChangeEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.network.PacketDistributor;
@Mod.EventBusSubscriber
public class LivingEventHandler {
@SubscribeEvent
public static void onEntityHurt(LivingHurtEvent event) {
if (event == null || event.getEntity() == null) {
return;
}
renderDamageIndicator(event);
reduceBulletDamage(event, event.getSource(), event.getEntity(), event.getSource().getEntity(), event.getAmount());
}
@SubscribeEvent
public static void onEntityDeath(LivingDeathEvent event) {
if (event == null || event.getEntity() == null) {
return;
}
killIndication(event.getSource().getEntity());
handlePlayerKillEntity(event);
}
private static void reduceBulletDamage(LivingHurtEvent event, DamageSource damagesource, LivingEntity entity, Entity sourceentity, double amount) {
if (damagesource == null || entity == null || sourceentity == null) {
return;
}
double damage = amount;
ItemStack stack = sourceentity instanceof LivingEntity living ? living.getMainHandItem() : ItemStack.EMPTY;
if ((damagesource.is(ModDamageTypes.ARROW_IN_KNEE) || damagesource.is(ModDamageTypes.ARROW_IN_BRAIN)
&& stack.getItem() == ModItems.BOCEK.get())) {
stack.getOrCreateTag().putDouble("damagetotal", stack.getOrCreateTag().getDouble("damagetotal") + damage);
}
if ((damagesource.is(ModDamageTypes.PROJECTILE_BOOM) || damagesource.is(DamageTypes.ARROW))
&& (stack.getItem() == ModItems.M_79.get() || stack.getItem() == ModItems.RPG.get())
) {
stack.getOrCreateTag().putDouble("damagetotal", stack.getOrCreateTag().getDouble("damagetotal") + damage);
}
if (damagesource.is(ModDamageTypes.GUN_FIRE) || damagesource.is(ModDamageTypes.GUN_FIRE_HEADSHOT)) {
double distance = entity.position().distanceTo(sourceentity.position());
if (stack.is(ModTags.Items.SHOTGUN) || stack.getItem() == ModItems.BOCEK.get()) {
damage = reduceDamageByDistance(amount, distance, 0.03, 25);
} else if (stack.is(ModTags.Items.SNIPER_RIFLE)) {
damage = reduceDamageByDistance(amount, distance, 0.001, 200);
} else if (stack.is(ModTags.Items.HANDGUN)) {
damage = reduceDamageByDistance(amount, distance, 0.03, 50);
} else if (stack.is(ModTags.Items.SMG)) {
damage = reduceDamageByDistance(amount, distance, 0.03, 50);
} else if (stack.is(ModTags.Items.RIFLE)) {
damage = reduceDamageByDistance(amount, distance, 0.0025, 150);
}
event.setAmount((float) damage);
stack.getOrCreateTag().putDouble("damagetotal", stack.getOrCreateTag().getDouble("damagetotal") + damage);
}
if (entity instanceof Target1Entity && sourceentity instanceof Player player) {
player.displayClientMessage(Component.literal("Damage:" + new java.text.DecimalFormat("##.#").format(damage) + " Distance:" + new java.text.DecimalFormat("##.#").format((entity.position()).distanceTo((sourceentity.position()))) + "M"), false);
}
}
private static double reduceDamageByDistance(double amount, double distance, double rate, double minDistance) {
return amount / (1 + rate * Math.max(0, distance - minDistance));
}
private static void killIndication(Entity sourceEntity) {
if (sourceEntity == null) {
return;
}
if (!sourceEntity.level().isClientSide() && sourceEntity instanceof ServerPlayer player) {
SoundTool.playLocalSound(player, ModSounds.TARGET_DOWN.get(), 100f, 1f);
ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new ClientIndicatorMessage(2, 8));
}
}
private static void renderDamageIndicator(LivingHurtEvent event) {
if (event == null || event.getEntity() == null) {
return;
}
var damagesource = event.getSource();
var sourceEntity = damagesource.getEntity();
if (sourceEntity == null) {
return;
}
if (sourceEntity instanceof ServerPlayer player && (damagesource.is(DamageTypes.EXPLOSION) || damagesource.is(DamageTypes.PLAYER_EXPLOSION)
|| damagesource.is(ModDamageTypes.MINE) || damagesource.is(ModDamageTypes.PROJECTILE_BOOM))) {
SoundTool.playLocalSound(player, ModSounds.INDICATION.get(), 1f, 1f);
ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new ClientIndicatorMessage(0, 5));
}
}
/**
* 换弹时切换枪械,取消换弹音效播放
*/
@SubscribeEvent
public static void handleChangeSlot(LivingEquipmentChangeEvent event) {
if (event.getEntity() instanceof Player player && event.getSlot() == EquipmentSlot.MAINHAND) {
if (player.level().isClientSide) {
return;
}
ItemStack oldStack = event.getFrom();
ItemStack newStack = event.getTo();
if (player instanceof ServerPlayer serverPlayer) {
if (newStack.getItem() != oldStack.getItem()
|| newStack.getTag() == null || oldStack.getTag() == null
|| !newStack.getTag().hasUUID("gun_uuid") || !oldStack.getTag().hasUUID("gun_uuid")
|| !newStack.getTag().getUUID("gun_uuid").equals(oldStack.getTag().getUUID("gun_uuid"))
) {
if (oldStack.getItem() instanceof GunItem oldGun) {
stopGunReloadSound(serverPlayer, oldGun);
if (oldStack.getTag() == null) {
return;
}
var oldTags = oldStack.getTag();
if (oldTags.getInt("bolt_action_time") > 0) {
oldTags.putInt("bolt_action_anim", 0);
}
oldTags.putBoolean("is_normal_reloading", false);
oldTags.putBoolean("is_empty_reloading", false);
oldTags.putInt("gun_reloading_time", 0);
oldTags.putBoolean("force_stop", false);
oldTags.putBoolean("stop", false);
oldTags.putInt("reload_stage",0);
oldTags.putBoolean("reloading", false);
oldTags.putDouble("prepare", 0);
oldTags.putDouble("prepare_load", 0);
oldTags.putDouble("iterative", 0);
oldTags.putDouble("finish", 0);
oldTags.putBoolean("sentinel_is_charging", false);
oldTags.putInt("sentinel_charge_time", 0);
}
if (newStack.getItem() instanceof GunItem) {
newStack.getOrCreateTag().putBoolean("draw", true);
if (newStack.getOrCreateTag().getInt("bolt_action_time") > 0) {
newStack.getOrCreateTag().putInt("bolt_action_anim", 0);
}
newStack.getOrCreateTag().putBoolean("is_normal_reloading", false);
newStack.getOrCreateTag().putBoolean("is_empty_reloading", false);
newStack.getOrCreateTag().putInt("gun_reloading_time", 0);
newStack.getOrCreateTag().putBoolean("force_stop", false);
newStack.getOrCreateTag().putBoolean("stop", false);
newStack.getOrCreateTag().putInt("reload_stage",0);
newStack.getOrCreateTag().putBoolean("reloading", false);
newStack.getOrCreateTag().putDouble("prepare", 0);
newStack.getOrCreateTag().putDouble("prepare_load", 0);
newStack.getOrCreateTag().putDouble("iterative", 0);
newStack.getOrCreateTag().putDouble("finish", 0);
newStack.getOrCreateTag().putBoolean("sentinel_is_charging", false);
newStack.getOrCreateTag().putInt("sentinel_charge_time", 0);
double weight = newStack.getOrCreateTag().getDouble("weight");
if (weight == 0) {
player.getCooldowns().addCooldown(newStack.getItem(), 12);
} else if (weight == 1) {
player.getCooldowns().addCooldown(newStack.getItem(), 17);
} else if (weight == 2) {
player.getCooldowns().addCooldown(newStack.getItem(), 30);
}
}
}
}
}
}
private static void stopGunReloadSound(ServerPlayer player, GunItem gun) {
gun.getReloadSound().forEach(sound -> {
var clientboundstopsoundpacket = new ClientboundStopSoundPacket(sound.getLocation(), SoundSource.PLAYERS);
player.connection.send(clientboundstopsoundpacket);
});
}
private static void handlePlayerKillEntity(LivingDeathEvent event) {
LivingEntity entity = event.getEntity();
DamageSource source = event.getSource();
if (!TargetModVariables.MapVariables.get(entity.level()).pvpMode) {
return;
}
ResourceKey<DamageType> damageTypeResourceKey = source.typeHolder().unwrapKey().isPresent() ? source.typeHolder().unwrapKey().get() : DamageTypes.GENERIC;
ServerPlayer attacker = null;
if (source.getEntity() instanceof ServerPlayer player) {
attacker = player;
}
if (source.getDirectEntity() instanceof Projectile projectile && projectile.getOwner() instanceof ServerPlayer player) {
attacker = player;
}
if (attacker != null) {
if (source.is(ModDamageTypes.GUN_FIRE_HEADSHOT) || source.is(ModDamageTypes.ARROW_IN_BRAIN)) {
ModUtils.PACKET_HANDLER.send(PacketDistributor.ALL.noArg(), new PlayerGunKillMessage(attacker.getId(), entity.getId(), true, damageTypeResourceKey));
} else {
ModUtils.PACKET_HANDLER.send(PacketDistributor.ALL.noArg(), new PlayerGunKillMessage(attacker.getId(), entity.getId(), false, damageTypeResourceKey));
}
}
}
}