From 20a6276ef9cdab77f38b87aa799711dc1dcdc1f9 Mon Sep 17 00:00:00 2001 From: Minh Date: Thu, 19 Sep 2024 20:01:25 +0700 Subject: [PATCH] Critical Chance Events --- gradle.properties | 2 +- .../event/ArrowCriticalChanceEvent.java | 21 ++++++++++ .../attribute/event/CriticalChanceEvent.java | 26 ++++++++++++ .../api/attribute/event/package-info.java | 7 ++++ .../attribute/ManasCoreAttributeHandler.java | 40 ++++++++++++------- 5 files changed, 81 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/github/manasmods/manascore/api/attribute/event/ArrowCriticalChanceEvent.java create mode 100644 src/main/java/com/github/manasmods/manascore/api/attribute/event/CriticalChanceEvent.java create mode 100644 src/main/java/com/github/manasmods/manascore/api/attribute/event/package-info.java diff --git a/gradle.properties b/gradle.properties index 5f5295be..8f0e2979 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ forgeVersion=43.3.5 # Parchment Version parchmentVersion=2022.11.27 # Mod Information see https://mcforge.readthedocs.io/en/1.18.x/gettingstarted/versioning/#examples -modVersion=2.1.3.8 +modVersion=2.1.3.9 modId=manascore # Mixin Extras mixinExtrasVersion=0.3.2 diff --git a/src/main/java/com/github/manasmods/manascore/api/attribute/event/ArrowCriticalChanceEvent.java b/src/main/java/com/github/manasmods/manascore/api/attribute/event/ArrowCriticalChanceEvent.java new file mode 100644 index 00000000..ea26b3d6 --- /dev/null +++ b/src/main/java/com/github/manasmods/manascore/api/attribute/event/ArrowCriticalChanceEvent.java @@ -0,0 +1,21 @@ +package com.github.manasmods.manascore.api.attribute.event; + +import lombok.Getter; +import lombok.Setter; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.projectile.Projectile; +import net.minecraftforge.event.entity.living.LivingEvent; +import net.minecraftforge.eventbus.api.Cancelable; + +@Getter +@Cancelable +public class ArrowCriticalChanceEvent extends LivingEvent { + @Setter + private double critChance; + private final Projectile arrow; + public ArrowCriticalChanceEvent(LivingEntity owner, Projectile arrow, double critChance) { + super(owner); + this.arrow = arrow; + this.critChance = critChance; + } +} diff --git a/src/main/java/com/github/manasmods/manascore/api/attribute/event/CriticalChanceEvent.java b/src/main/java/com/github/manasmods/manascore/api/attribute/event/CriticalChanceEvent.java new file mode 100644 index 00000000..ac6eb8bc --- /dev/null +++ b/src/main/java/com/github/manasmods/manascore/api/attribute/event/CriticalChanceEvent.java @@ -0,0 +1,26 @@ +package com.github.manasmods.manascore.api.attribute.event; + +import lombok.Getter; +import lombok.Setter; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraftforge.event.entity.living.LivingEvent; +import net.minecraftforge.eventbus.api.Cancelable; + +@Getter +@Cancelable +public class CriticalChanceEvent extends LivingEvent { + @Setter + private float damageModifier; + @Setter + private double critChance; + private final float oldDamageModifier; + private final Entity target; + + public CriticalChanceEvent(LivingEntity attacker, Entity target, float damageModifier, double critChance) { + super(attacker); + this.target = target; + this.oldDamageModifier = damageModifier; + this.critChance = critChance; + } +} diff --git a/src/main/java/com/github/manasmods/manascore/api/attribute/event/package-info.java b/src/main/java/com/github/manasmods/manascore/api/attribute/event/package-info.java new file mode 100644 index 00000000..dba08950 --- /dev/null +++ b/src/main/java/com/github/manasmods/manascore/api/attribute/event/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package com.github.manasmods.manascore.api.attribute.event; + +import com.github.manasmods.manascore.api.util.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/com/github/manasmods/manascore/attribute/ManasCoreAttributeHandler.java b/src/main/java/com/github/manasmods/manascore/attribute/ManasCoreAttributeHandler.java index 399dd5f0..a2a34e14 100644 --- a/src/main/java/com/github/manasmods/manascore/attribute/ManasCoreAttributeHandler.java +++ b/src/main/java/com/github/manasmods/manascore/attribute/ManasCoreAttributeHandler.java @@ -5,6 +5,8 @@ package com.github.manasmods.manascore.attribute; import com.github.manasmods.manascore.ManasCore; +import com.github.manasmods.manascore.api.attribute.event.ArrowCriticalChanceEvent; +import com.github.manasmods.manascore.api.attribute.event.CriticalChanceEvent; import net.minecraft.core.BlockPos; import net.minecraft.network.protocol.game.ClientboundAnimatePacket; import net.minecraft.server.level.ServerLevel; @@ -15,6 +17,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.phys.Vec3; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.EntityJoinLevelEvent; import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent; import net.minecraftforge.event.entity.living.LivingFallEvent; @@ -65,14 +68,17 @@ public static void modifyFallDamage(final LivingFallEvent e) { public static void applyEntityCrit(final LivingHurtEvent e) { if (!(e.getSource().getDirectEntity() instanceof LivingEntity entity)) return; // Direct attack if (entity instanceof Player) return; // Players have their own Critical Event - double critChance = entity.getAttributeValue(ManasCoreAttributes.CRIT_CHANCE.get()) / 100; // Convert to % + LivingEntity target = e.getEntity(); - RandomSource rand = entity.getRandom(); - if (rand.nextFloat() > critChance) return; + double critChance = entity.getAttributeValue(ManasCoreAttributes.CRIT_CHANCE.get()) / 100; // Convert to % float critMultiplier = (float) entity.getAttributeValue(ManasCoreAttributes.CRIT_MULTIPLIER.get()); - e.setAmount(e.getAmount() * critMultiplier); + CriticalChanceEvent event = new CriticalChanceEvent(entity, target, critMultiplier, critChance); + if (MinecraftForge.EVENT_BUS.post(event)) return; + + RandomSource random = entity.getRandom(); + if (random.nextFloat() > event.getCritChance()) return; + e.setAmount(e.getAmount() * event.getDamageModifier()); - LivingEntity target = e.getEntity(); target.getLevel().playSound(null, target.getX(), target.getY(), target.getZ(), SoundEvents.PLAYER_ATTACK_CRIT, entity.getSoundSource(), 1.0F, 1.0F); if (entity.getLevel() instanceof ServerLevel level) @@ -81,16 +87,19 @@ public static void applyEntityCrit(final LivingHurtEvent e) { @SubscribeEvent(priority = EventPriority.HIGH) public static void modifyCrit(final CriticalHitEvent e) { - double critChance = e.getEntity().getAttributeValue(ManasCoreAttributes.CRIT_CHANCE.get()) / 100; // convert to % - RandomSource rand = e.getEntity().getRandom(); - - // Exit if this hit isn't a crit - if (rand.nextFloat() > critChance && !e.isVanillaCritical()) return; + if (e.isVanillaCritical()) { + e.setDamageModifier(e.getDamageModifier() * (float) e.getEntity().getAttributeValue(ManasCoreAttributes.CRIT_MULTIPLIER.get())); + return; + } + double critChance = e.getEntity().getAttributeValue(ManasCoreAttributes.CRIT_CHANCE.get()) / 100; // convert to % float critMultiplier = (float) e.getEntity().getAttributeValue(ManasCoreAttributes.CRIT_MULTIPLIER.get()); - float critModifier = e.getDamageModifier() * critMultiplier; + CriticalChanceEvent event = new CriticalChanceEvent(e.getEntity(), e.getTarget(), e.getDamageModifier() * critMultiplier, critChance); + if (MinecraftForge.EVENT_BUS.post(event)) return; - e.setDamageModifier(critModifier); + RandomSource random = e.getEntity().getRandom(); + if (random.nextFloat() > event.getCritChance()) return; // Exit if this hit isn't a crit + e.setDamageModifier(event.getDamageModifier()); e.setResult(Event.Result.ALLOW); } @@ -100,11 +109,14 @@ public static void modifyArrowCrit(final EntityJoinLevelEvent e) { if (!(e.getEntity() instanceof AbstractArrow arrow)) return; if (arrow.getPersistentData().getBoolean("manascore.crit.calc.done")) return; if (!(arrow.getOwner() instanceof LivingEntity owner)) return; + // Check if current arrow is a crit arrow if (!arrow.isCritArrow()) { double critChance = owner.getAttributeValue(ManasCoreAttributes.CRIT_CHANCE.get()); - RandomSource rand = owner.getRandom(); - arrow.setCritArrow(rand.nextDouble() <= critChance); + ArrowCriticalChanceEvent event = new ArrowCriticalChanceEvent(owner, arrow, critChance); + + if (MinecraftForge.EVENT_BUS.post(event)) return; + arrow.setCritArrow(owner.getRandom().nextDouble() <= event.getCritChance()); } arrow.getPersistentData().putBoolean("manascore.crit.calc.done", true); }