diff --git a/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java index 838cde900..57ae2a3fc 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java @@ -544,6 +544,14 @@ public class LivingEventHandler { return; } + GunData data = GunData.from(stack); + for (Perk.Type type : Perk.Type.values()) { + var instance = data.perk.getInstance(type); + if (instance != null) { + instance.perk().onKill(data, instance, attacker, event.getEntity(), source); + } + } + if (DamageTypeTool.isGunDamage(source) || source.is(ModDamageTypes.PROJECTILE_BOOM)) { handleClipPerks(stack); } @@ -560,15 +568,9 @@ public class LivingEventHandler { private static void handleClipPerks(ItemStack stack) { var data = GunData.from(stack); - int healClipLevel = data.perk.getLevel(ModPerks.HEAL_CLIP); - var tag = data.perk.getTag(ModPerks.HEAL_CLIP); - if (healClipLevel != 0) { - tag.putInt("HealClipTime", 80 + healClipLevel * 20); - } - int killClipLevel = data.perk.getLevel(ModPerks.KILL_CLIP); if (killClipLevel != 0) { - tag.putInt("KillClipReloadTime", 80); + data.perk.getTag(ModPerks.KILL_CLIP).putInt("KillClipReloadTime", 80); } data.save(); } diff --git a/src/main/java/com/atsuishio/superbwarfare/event/ReloadEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/ReloadEventHandler.java index 627565fbd..ece746439 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/ReloadEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/ReloadEventHandler.java @@ -4,14 +4,13 @@ import com.atsuishio.superbwarfare.api.event.ReloadEvent; import com.atsuishio.superbwarfare.init.ModPerks; import com.atsuishio.superbwarfare.item.gun.GunItem; import com.atsuishio.superbwarfare.item.gun.data.GunData; +import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.tools.GunsTool; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; -import java.util.List; - @EventBusSubscriber public class ReloadEventHandler { @@ -24,7 +23,14 @@ public class ReloadEventHandler { || player.level().isClientSide ) return; - handleHealClipPre(stack); + GunData data = GunData.from(stack); + for (Perk.Type type : Perk.Type.values()) { + var instance = data.perk.getInstance(type); + if (instance != null) { + instance.perk().preReload(data, instance, player); + } + } + handleKillClipPre(stack); handleKillingTallyPre(stack); handleDesperadoPre(stack); @@ -42,41 +48,18 @@ public class ReloadEventHandler { return; } - handleHealClipPost(player, stack); + GunData data = GunData.from(stack); + for (Perk.Type type : Perk.Type.values()) { + var instance = data.perk.getInstance(type); + if (instance != null) { + instance.perk().postReload(data, instance, player); + } + } + handleKillClipPost(stack); handleDesperadoPost(stack); } - private static void handleHealClipPre(ItemStack stack) { - var data = GunData.from(stack); - final var tag = data.tag(); - int time = GunsTool.getPerkIntTag(tag, "HealClipTime"); - if (time > 0) { - GunsTool.setPerkIntTag(tag, "HealClipTime", 0); - GunsTool.setPerkBooleanTag(tag, "HealClip", true); - } else { - GunsTool.setPerkBooleanTag(tag, "HealClip", false); - } - data.save(); - } - - private static void handleHealClipPost(Player player, ItemStack stack) { - var data = GunData.from(stack); - final var tag = data.tag(); - if (!GunsTool.getPerkBooleanTag(tag, "HealClip")) return; - - int healClipLevel = data.perk.getLevel(ModPerks.HEAL_CLIP); - if (healClipLevel == 0) { - healClipLevel = 1; - } - - player.heal(12.0f * (0.8f + 0.2f * healClipLevel)); - List players = player.level().getEntitiesOfClass(Player.class, player.getBoundingBox().inflate(5)) - .stream().filter(p -> p.isAlliedTo(player)).toList(); - int finalHealClipLevel = healClipLevel; - players.forEach(p -> p.heal(6.0f * (0.8f + 0.2f * finalHealClipLevel))); - } - private static void handleKillClipPre(ItemStack stack) { var data = GunData.from(stack); final var tag = data.tag(); diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java b/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java index 92e64fe66..7161a4e0c 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModPerks.java @@ -3,6 +3,7 @@ package com.atsuishio.superbwarfare.init; import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.perk.AmmoPerk; import com.atsuishio.superbwarfare.perk.Perk; +import com.atsuishio.superbwarfare.perk.functional.HealClip; import net.minecraft.resources.ResourceKey; import net.minecraft.world.effect.MobEffects; import net.neoforged.bus.api.IEventBus; @@ -52,7 +53,7 @@ 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", () -> new Perk("heal_clip", Perk.Type.FUNCTIONAL)); + 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)); diff --git a/src/main/java/com/atsuishio/superbwarfare/perk/Perk.java b/src/main/java/com/atsuishio/superbwarfare/perk/Perk.java index 544cd549d..53dd95dda 100644 --- a/src/main/java/com/atsuishio/superbwarfare/perk/Perk.java +++ b/src/main/java/com/atsuishio/superbwarfare/perk/Perk.java @@ -4,8 +4,12 @@ import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.item.PerkItem; import com.atsuishio.superbwarfare.item.gun.data.GunData; import net.minecraft.ChatFormatting; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.neoforged.neoforge.registries.DeferredHolder; +import org.jetbrains.annotations.Nullable; import java.util.function.BiFunction; @@ -54,6 +58,21 @@ public class Perk { return result.get(); } + public void tick(GunData data, PerkInstance instance, @Nullable Player player) { + } + + public void preReload(GunData data, PerkInstance instance, @Nullable Player player) { + } + + public void postReload(GunData data, PerkInstance instance, @Nullable Player player) { + } + + public void onKill(GunData data, PerkInstance instance, @Nullable Player player, LivingEntity target, DamageSource source) { + } + + public void onShoot() { + } + public enum Type { AMMO("Ammo", ChatFormatting.YELLOW), FUNCTIONAL("Functional", ChatFormatting.GREEN), diff --git a/src/main/java/com/atsuishio/superbwarfare/perk/functional/HealClip.java b/src/main/java/com/atsuishio/superbwarfare/perk/functional/HealClip.java new file mode 100644 index 000000000..84dcd4c4d --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/perk/functional/HealClip.java @@ -0,0 +1,69 @@ +package com.atsuishio.superbwarfare.perk.functional; + +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 com.atsuishio.superbwarfare.tools.DamageTypeTool; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class HealClip extends Perk { + + public HealClip() { + super("heal_clip", Perk.Type.FUNCTIONAL); + } + + @Override + public void onKill(GunData data, PerkInstance instance, @Nullable Player player, LivingEntity target, DamageSource source) { + super.onKill(data, instance, player, target, source); + + if (DamageTypeTool.isGunDamage(source) || source.is(ModDamageTypes.PROJECTILE_BOOM)) { + int healClipLevel = instance.level(); + if (healClipLevel != 0) { + data.perk.getTag(this).putInt("HealClipTime", 80 + healClipLevel * 20); + } + } + } + + @Override + public void preReload(GunData data, PerkInstance instance, @Nullable Player player) { + super.preReload(data, instance, player); + + ItemStack stack = data.stack; + int time = data.perk.getTag(this).getInt("HealClipTime"); + if (time > 0) { + data.perk.getTag(this).putInt("HealClipTime", 0); + data.perk.getTag(this).putBoolean("HealClip", true); + } else { + data.perk.getTag(this).putBoolean("HealClip", false); + } + } + + @Override + public void postReload(GunData data, PerkInstance instance, @Nullable Player player) { + super.postReload(data, instance, player); + + if (player == null) return; + + if (!data.perk.getTag(this).getBoolean("HealClip")) { + return; + } + + int healClipLevel = instance.level(); + if (healClipLevel == 0) { + healClipLevel = 1; + } + + player.heal(12.0f * (0.8f + 0.2f * healClipLevel)); + List players = player.level().getEntitiesOfClass(Player.class, player.getBoundingBox().inflate(5)) + .stream().filter(p -> p.isAlliedTo(player)).toList(); + int finalHealClipLevel = healClipLevel; + players.forEach(p -> p.heal(6.0f * (0.8f + 0.2f * finalHealClipLevel))); + } +}