From 90e76d7c92c0bec517713d5bc2da884db3dce75e Mon Sep 17 00:00:00 2001 From: 17146 <1714673995@qq.com> Date: Wed, 7 May 2025 13:09:14 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=88=B6=E9=83=A8=E5=88=86=E5=8A=9F?= =?UTF-8?q?=E8=83=BDperk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/LivingEventHandler.java | 79 +------------------ .../superbwarfare/init/ModPerks.java | 9 ++- .../superbwarfare/item/gun/GunItem.java | 23 ------ .../atsuishio/superbwarfare/perk/Perk.java | 4 + .../perk/functional/FieldDoctor.java | 44 +++++++++++ .../perk/functional/FourthTimesCharm.java | 58 ++++++++++++++ .../perk/functional/Subsistence.java | 57 +++++++++++++ 7 files changed, 172 insertions(+), 102 deletions(-) create mode 100644 src/main/java/com/atsuishio/superbwarfare/perk/functional/FieldDoctor.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/perk/functional/FourthTimesCharm.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/perk/functional/Subsistence.java diff --git a/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java index 1314a8a42..e28970feb 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java @@ -7,7 +7,6 @@ import com.atsuishio.superbwarfare.config.server.MiscConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.entity.ICustomKnockback; import com.atsuishio.superbwarfare.entity.TargetEntity; -import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import com.atsuishio.superbwarfare.entity.vehicle.LaserTowerEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.ContainerMobileVehicleEntity; @@ -496,22 +495,11 @@ public class LivingEventHandler { if (instance != null) { instance.perk().onHit(damage, data, instance, event.getEntity(), source); damage = instance.perk().getModifiedDamage(damage, data, instance, event.getEntity(), source); - } - } - - if (source.getDirectEntity() instanceof ProjectileEntity projectile) { - if (data.perk.getLevel(ModPerks.FOURTH_TIMES_CHARM) > 0) { - float bypassArmorRate = projectile.getBypassArmorRate(); - if (bypassArmorRate >= 1.0f && source.is(ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE)) { - handleFourthTimesCharm(stack); - } else if (source.is(ModDamageTypes.GUN_FIRE_HEADSHOT)) { - handleFourthTimesCharm(stack); + if (instance.perk().shouldCancelHurtEvent(damage, data, instance, event.getEntity(), source)) { + event.setCanceled(true); + return; } } - - if (!projectile.isZoom()) { - handleFieldDoctor(stack, event, attacker); - } } event.setAmount(damage); @@ -544,67 +532,6 @@ public class LivingEventHandler { instance.perk().onKill(data, instance, event.getEntity(), source); } } - - if (DamageTypeTool.isGunDamage(source)) { - handleSubsistence(stack, attacker); - } - } - - private static void handleFourthTimesCharm(ItemStack stack) { - var data = GunData.from(stack); - int level = data.perk.getLevel(ModPerks.FOURTH_TIMES_CHARM); - if (level == 0) return; - final var tag = data.perk.getTag(ModPerks.FOURTH_TIMES_CHARM); - - int fourthTimesCharmTick = tag.getInt("FourthTimesCharmTick"); - if (fourthTimesCharmTick <= 0) { - tag.putInt("FourthTimesCharmTick", 40 + 10 * level); - tag.putInt("FourthTimesCharmCount", 1); - } else { - int count = tag.getInt("FourthTimesCharmCount"); - if (count < 4) { - tag.putInt("FourthTimesCharmCount", Math.min(4, count + 1)); - } - } - - data.save(); - } - - private static void handleSubsistence(ItemStack stack, Player player) { - var data = GunData.from(stack); - int level = data.perk.getLevel(ModPerks.SUBSISTENCE); - if (level == 0) return; - - float rate = level * 0.1f + (stack.is(ModTags.Items.SMG) || stack.is(ModTags.Items.RIFLE) ? 0.07f : 0f); - - int mag = data.magazine(); - int ammo = data.ammo.get(); - int ammoReload = (int) Math.min(mag, mag * rate); - int ammoNeed = Math.min(mag - ammo, ammoReload); - - boolean flag = player.isCreative() || InventoryTool.hasCreativeAmmoBox(player); - - int ammoFinal = Math.min(data.countBackupAmmo(player), ammoNeed); - if (flag) { - ammoFinal = ammoNeed; - } else { - data.consumeBackupAmmo(player, ammoFinal); - } - data.ammo.set(Math.min(mag, ammo + ammoFinal)); - - data.save(); - } - - - private static void handleFieldDoctor(ItemStack stack, LivingIncomingDamageEvent event, Player player) { - var data = GunData.from(stack); - int level = data.perk.getLevel(ModPerks.FIELD_DOCTOR); - if (level == 0) return; - - if (event.getEntity().isAlliedTo(player)) { - event.getEntity().heal(event.getAmount() * Math.min(1.0f, 0.25f + 0.05f * level)); - event.setCanceled(true); - } } @SubscribeEvent diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java b/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java index ae0adabe9..7aed99670 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java @@ -4,7 +4,10 @@ import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.perk.AmmoPerk; import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.damage.*; +import com.atsuishio.superbwarfare.perk.functional.FieldDoctor; +import com.atsuishio.superbwarfare.perk.functional.FourthTimesCharm; import com.atsuishio.superbwarfare.perk.functional.HealClip; +import com.atsuishio.superbwarfare.perk.functional.Subsistence; import net.minecraft.resources.ResourceKey; import net.minecraft.world.effect.MobEffects; import net.neoforged.bus.api.IEventBus; @@ -55,9 +58,9 @@ public class ModPerks { public static final DeferredRegister FUNC_PERKS = DeferredRegister.create(Mod.loc("perk"), Mod.MODID); public static final DeferredHolder HEAL_CLIP = FUNC_PERKS.register("heal_clip", HealClip::new); - public static final DeferredHolder FOURTH_TIMES_CHARM = FUNC_PERKS.register("fourth_times_charm", () -> new Perk("fourth_times_charm", Perk.Type.FUNCTIONAL)); - public static final DeferredHolder SUBSISTENCE = FUNC_PERKS.register("subsistence", () -> new Perk("subsistence", Perk.Type.FUNCTIONAL)); - public static final DeferredHolder FIELD_DOCTOR = FUNC_PERKS.register("field_doctor", () -> new Perk("field_doctor", Perk.Type.FUNCTIONAL)); + public static final DeferredHolder FOURTH_TIMES_CHARM = FUNC_PERKS.register("fourth_times_charm", FourthTimesCharm::new); + public static final DeferredHolder SUBSISTENCE = FUNC_PERKS.register("subsistence", Subsistence::new); + public static final DeferredHolder FIELD_DOCTOR = FUNC_PERKS.register("field_doctor", FieldDoctor::new); public static final DeferredHolder REGENERATION = FUNC_PERKS.register("regeneration", () -> new Perk("regeneration", Perk.Type.FUNCTIONAL)); public static final DeferredHolder TURBO_CHARGER = FUNC_PERKS.register("turbo_charger", () -> new Perk("turbo_charger", Perk.Type.FUNCTIONAL)); public static final DeferredHolder POWERFUL_ATTRACTION = FUNC_PERKS.register("powerful_attraction", () -> new Perk("powerful_attraction", Perk.Type.FUNCTIONAL)); diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/GunItem.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/GunItem.java index d575f4cc1..db74dd215 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/GunItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/GunItem.java @@ -100,7 +100,6 @@ public abstract class GunItem extends Item implements CustomRendererItem { instance.perk().tick(data, instance, living); } } - handleGunPerks(data); var hasBulletInBarrel = gunItem.hasBulletInBarrel(stack); var ammoCount = data.ammo.get(); @@ -197,28 +196,6 @@ public abstract class GunItem extends Item implements CustomRendererItem { return false; } - - private void handleGunPerks(GunData data) { - var perk = data.perk; - - perk.reduceCooldown(ModPerks.FOURTH_TIMES_CHARM, "FourthTimesCharmTick"); - - if (perk.getLevel(ModPerks.FOURTH_TIMES_CHARM) > 0) { - var tag = data.perk.getTag(ModPerks.FOURTH_TIMES_CHARM); - int count = perk.getTag(ModPerks.FOURTH_TIMES_CHARM).getInt("FourthTimesCharmCount"); - - if (count >= 4) { - tag.remove("FourthTimesCharmTick"); - tag.remove("FourthTimesCharmCount"); - - int mag = data.magazine(); - data.ammo.set(Math.min(mag, data.ammo.get() + 2)); - } - } - - data.save(); - } - public boolean canApplyPerk(Perk perk) { return true; } diff --git a/src/main/java/com/atsuishio/superbwarfare/perk/Perk.java b/src/main/java/com/atsuishio/superbwarfare/perk/Perk.java index a1182afe8..a6ec0ef62 100644 --- a/src/main/java/com/atsuishio/superbwarfare/perk/Perk.java +++ b/src/main/java/com/atsuishio/superbwarfare/perk/Perk.java @@ -83,6 +83,10 @@ public class Perk { public void onChangeSlot(GunData data, PerkInstance instance, @Nullable LivingEntity living) { } + public boolean shouldCancelHurtEvent(float damage, GunData data, PerkInstance instance, LivingEntity target, DamageSource source) { + return false; + } + public enum Type { AMMO("Ammo", ChatFormatting.YELLOW), FUNCTIONAL("Functional", ChatFormatting.GREEN), diff --git a/src/main/java/com/atsuishio/superbwarfare/perk/functional/FieldDoctor.java b/src/main/java/com/atsuishio/superbwarfare/perk/functional/FieldDoctor.java new file mode 100644 index 000000000..d6885a33a --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/perk/functional/FieldDoctor.java @@ -0,0 +1,44 @@ +package com.atsuishio.superbwarfare.perk.functional; + +import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; +import com.atsuishio.superbwarfare.item.gun.data.GunData; +import com.atsuishio.superbwarfare.perk.Perk; +import com.atsuishio.superbwarfare.perk.PerkInstance; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.Projectile; + +public class FieldDoctor extends Perk { + + public FieldDoctor() { + super("field_doctor", Perk.Type.FUNCTIONAL); + } + + @Override + public void onHit(float damage, GunData data, PerkInstance instance, LivingEntity target, DamageSource source) { + if (!trigger(target, source)) { + return; + } + target.heal(damage * Math.min(1.0f, 0.25f + 0.05f * instance.level())); + } + + @Override + public boolean shouldCancelHurtEvent(float damage, GunData data, PerkInstance instance, LivingEntity target, DamageSource source) { + return trigger(target, source); + } + + public boolean trigger(LivingEntity target, DamageSource source) { + if (source.getDirectEntity() instanceof ProjectileEntity projectile && !projectile.isZoom()) { + Player attacker = null; + if (source.getEntity() instanceof Player player) { + attacker = player; + } + if (source.getDirectEntity() instanceof Projectile p && p.getOwner() instanceof Player player) { + attacker = player; + } + return attacker != null && target != null && target.isAlliedTo(attacker); + } + return false; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/perk/functional/FourthTimesCharm.java b/src/main/java/com/atsuishio/superbwarfare/perk/functional/FourthTimesCharm.java new file mode 100644 index 000000000..5a7d86cb6 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/perk/functional/FourthTimesCharm.java @@ -0,0 +1,58 @@ +package com.atsuishio.superbwarfare.perk.functional; + +import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; +import com.atsuishio.superbwarfare.init.ModDamageTypes; +import com.atsuishio.superbwarfare.item.gun.data.GunData; +import com.atsuishio.superbwarfare.perk.Perk; +import com.atsuishio.superbwarfare.perk.PerkInstance; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.LivingEntity; +import org.jetbrains.annotations.Nullable; + +public class FourthTimesCharm extends Perk { + + public FourthTimesCharm() { + super("fourth_times_charm", Perk.Type.FUNCTIONAL); + } + + @Override + public void tick(GunData data, PerkInstance instance, @Nullable LivingEntity living) { + data.perk.reduceCooldown(this, "FourthTimesCharmTick"); + + var tag = data.perk.getTag(this); + int count = tag.getInt("FourthTimesCharmCount"); + + if (count >= 4) { + tag.remove("FourthTimesCharmTick"); + tag.remove("FourthTimesCharmCount"); + + int mag = data.magazine(); + data.ammo.set(Math.min(mag, data.ammo.get() + 2)); + } + } + + @Override + public void onHit(float damage, GunData data, PerkInstance instance, LivingEntity target, DamageSource source) { + if (source.getDirectEntity() instanceof ProjectileEntity projectile) { + float bypassArmorRate = projectile.getBypassArmorRate(); + if (bypassArmorRate >= 1.0f && source.is(ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE)) { + handleFourthTimesCharm(data, instance); + } else if (source.is(ModDamageTypes.GUN_FIRE_HEADSHOT)) { + handleFourthTimesCharm(data, instance); + } + } + } + + public void handleFourthTimesCharm(GunData data, PerkInstance instance) { + int fourthTimesCharmTick = data.perk.getTag(this).getInt("FourthTimesCharmTick"); + if (fourthTimesCharmTick <= 0) { + data.perk.getTag(this).putInt("FourthTimesCharmTick", 40 + 10 * instance.level()); + data.perk.getTag(this).putInt("FourthTimesCharmCount", 1); + } else { + int count = data.perk.getTag(this).getInt("FourthTimesCharmCount"); + if (count < 4) { + data.perk.getTag(this).putInt("FourthTimesCharmCount", Math.min(4, count + 1)); + } + } + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/perk/functional/Subsistence.java b/src/main/java/com/atsuishio/superbwarfare/perk/functional/Subsistence.java new file mode 100644 index 000000000..0743b9483 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/perk/functional/Subsistence.java @@ -0,0 +1,57 @@ +package com.atsuishio.superbwarfare.perk.functional; + +import com.atsuishio.superbwarfare.init.ModAttachments; +import com.atsuishio.superbwarfare.init.ModTags; +import com.atsuishio.superbwarfare.item.gun.data.GunData; +import com.atsuishio.superbwarfare.perk.Perk; +import com.atsuishio.superbwarfare.perk.PerkInstance; +import com.atsuishio.superbwarfare.tools.DamageTypeTool; +import com.atsuishio.superbwarfare.tools.InventoryTool; +import net.minecraft.world.damagesource.DamageSource; +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; + +public class Subsistence extends Perk { + + public Subsistence() { + super("subsistence", Perk.Type.FUNCTIONAL); + } + + @Override + public void onKill(GunData data, PerkInstance instance, LivingEntity target, DamageSource source) { + Player attacker = null; + if (source.getEntity() instanceof Player player) { + attacker = player; + } + if (source.getDirectEntity() instanceof Projectile p && p.getOwner() instanceof Player player) { + attacker = player; + } + + if (DamageTypeTool.isGunDamage(source) && attacker != null) { + ItemStack stack = data.stack; + + float rate = instance.level() * (0.1f + (stack.is(ModTags.Items.SMG) || stack.is(ModTags.Items.RIFLE) ? 0.07f : 0f)); + + var cap = attacker.getData(ModAttachments.PLAYER_VARIABLE).watch(); + + int mag = data.magazine(); + int ammo = data.ammo.get(); + int ammoReload = (int) Math.min(mag, mag * rate); + int ammoNeed = Math.min(mag - ammo, ammoReload); + + boolean flag = attacker.isCreative() || InventoryTool.hasCreativeAmmoBox(attacker); + + int ammoFinal = Math.min(data.countBackupAmmo(attacker), ammoNeed); + if (flag) { + ammoFinal = ammoNeed; + } else { + data.consumeBackupAmmo(attacker, ammoFinal); + } + data.ammo.set(Math.min(mag, ammo + ammoFinal)); + + cap.sync(attacker); + } + } +}