diff --git a/gradle.properties b/gradle.properties index a42b701..a6c3f2f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ maven_group=io.gitlab.jfronny archives_base_name=combit fabric_version=0.45.0+1.18 -jfapi_version=2.2.1 +jfapi_version=2.2.2-1641673767 modrinth_id=oPRrsg3M curseforge_id=561742 \ No newline at end of file diff --git a/src/main/java/io/gitlab/jfronny/combit/Combit.java b/src/main/java/io/gitlab/jfronny/combit/Combit.java index bd44eb0..b5fca45 100644 --- a/src/main/java/io/gitlab/jfronny/combit/Combit.java +++ b/src/main/java/io/gitlab/jfronny/combit/Combit.java @@ -42,7 +42,8 @@ public class Combit implements ModInitializer { if (attacker != null && idMatches(getId(attacker), CombitConfig.attackerWhitelist)) return ActionResult.PASS; - entity.timeUntilRegen = CombitConfig.iFrameInterval; + if (CombitConfig.iFrameInterval >= 0) + entity.timeUntilRegen = CombitConfig.iFrameInterval; return ActionResult.PASS; }); diff --git a/src/main/java/io/gitlab/jfronny/combit/CombitConfig.java b/src/main/java/io/gitlab/jfronny/combit/CombitConfig.java index c008351..d2897ce 100644 --- a/src/main/java/io/gitlab/jfronny/combit/CombitConfig.java +++ b/src/main/java/io/gitlab/jfronny/combit/CombitConfig.java @@ -1,16 +1,16 @@ package io.gitlab.jfronny.combit; -import io.gitlab.jfronny.libjf.config.api.Entry; -import io.gitlab.jfronny.libjf.config.api.JfConfig; +import io.gitlab.jfronny.libjf.config.api.*; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.entity.damage.DamageSource; import java.util.HashSet; public class CombitConfig implements JfConfig { // Invulnerability - @Entry(min = 0) public static Integer iFrameInterval = 0; - @Entry(max = 1) public static Double attackCancelThreshold = 0.1; - @Entry(max = 1) public static Double knockbackCancelThreshold = 0.75; + @Entry public static Integer iFrameInterval = 0; + @Entry(min=Double.MIN_VALUE, max = 1) public static Double attackCancelThreshold = 0.1; + @Entry(min=Double.MIN_VALUE, max = 1) public static Double knockbackCancelThreshold = 0.75; @Entry public static HashSet attackerWhitelist = null; @Entry public static HashSet damageSourceWhitelist = null; @Entry public static HashSet targetEntityWhitelist = null; @@ -24,6 +24,82 @@ public class CombitConfig implements JfConfig { @Entry public static Double cooldownProgressPerTickOverride = Double.MIN_VALUE; @Entry public static Double weaponAttackDamageFactor = 0.6; @Entry public static Double axeAttackDamageFactor = 0.5; + // Knockback + @Entry public static Double snowballKnockbackFactor = -1.0; + @Entry public static Float snowballDamage = 1.0f; + @Entry public static Double eggKnockbackFactor = -1.0; + @Entry public static Float eggDamage = 1.0f; + @Entry public static Double fishingBobberPullFactor = 2.0; // Debug @Entry public static Boolean debug = FabricLoader.getInstance().isDevelopmentEnvironment(); + + @Verifier public static void validate() { + if (attackerWhitelist == null) { + attackerWhitelist = new HashSet<>(); + attackerWhitelist.add("minecraft:slime"); + attackerWhitelist.add("minecraft:magma_cube"); + attackerWhitelist.add("tconstruct:blueslime"); + attackerWhitelist.add("thaumcraft:thaumslime"); + } + if (targetEntityWhitelist == null) { + targetEntityWhitelist = new HashSet<>(); + } + if (damageSourceWhitelist == null) { + damageSourceWhitelist = new HashSet<>(); + damageSourceWhitelist.add(DamageSource.IN_FIRE.getName()); + damageSourceWhitelist.add(DamageSource.LIGHTNING_BOLT.getName()); + damageSourceWhitelist.add(DamageSource.LAVA.getName()); + damageSourceWhitelist.add(DamageSource.HOT_FLOOR.getName()); + damageSourceWhitelist.add(DamageSource.IN_WALL.getName()); + damageSourceWhitelist.add(DamageSource.CACTUS.getName()); + damageSourceWhitelist.add(DamageSource.OUT_OF_WORLD.getName()); + damageSourceWhitelist.add(DamageSource.SWEET_BERRY_BUSH.getName()); + } + if (entityHealthBlacklist == null) { + entityHealthBlacklist = new HashSet<>(); + entityHealthBlacklist.add("minecraft:player"); + } + } + + @Preset public static void v189() { + iFrameInterval = -1; + attackCancelThreshold = 0.1; + knockbackCancelThreshold = 0.75; + attackerWhitelist = null; + damageSourceWhitelist = null; + targetEntityWhitelist = null; + excludeAllMobs = false; + excludePlayers = false; + entityHealthFactor = 1.0; + entityHealthBlacklist = null; + cooldownProgressOverride = 0.8; + cooldownProgressPerTickOverride = Double.MIN_VALUE; + weaponAttackDamageFactor = 1.0; + axeAttackDamageFactor = 0.5; + snowballKnockbackFactor = 1.0; + snowballDamage = 0.0f; + eggKnockbackFactor = 1.0; + eggDamage = 0.0f; + fishingBobberPullFactor = 1.0; + } + + @Preset public static void noInvulnerability() { + iFrameInterval = 0; + } + + @Preset public static void disable() { + iFrameInterval = -1; + excludeAllMobs = true; + excludePlayers = true; + entityHealthFactor = 1.0; + cooldownProgressOverride = -1.0; + cooldownProgressPerTickOverride = -1.0; + weaponAttackDamageFactor = 1.0; + axeAttackDamageFactor = 1.0; + snowballKnockbackFactor = 0.0; + snowballDamage = 0f; + eggKnockbackFactor = 0.0; + eggDamage = 0.0f; + fishingBobberPullFactor = 1.0; + } } diff --git a/src/main/java/io/gitlab/jfronny/combit/CombitConfigValidator.java b/src/main/java/io/gitlab/jfronny/combit/CombitConfigValidator.java deleted file mode 100644 index d0473d4..0000000 --- a/src/main/java/io/gitlab/jfronny/combit/CombitConfigValidator.java +++ /dev/null @@ -1,46 +0,0 @@ -package io.gitlab.jfronny.combit; - -import io.gitlab.jfronny.libjf.config.api.ConfigHolder; -import io.gitlab.jfronny.libjf.unsafe.UltraEarlyInit; -import net.minecraft.entity.damage.DamageSource; - -import java.util.HashSet; - -public class CombitConfigValidator implements UltraEarlyInit { - @Override - public void init() { - boolean changed = false; - if (CombitConfig.attackerWhitelist == null) { - changed = true; - CombitConfig.attackerWhitelist = new HashSet<>(); - CombitConfig.attackerWhitelist.add("minecraft:slime"); - CombitConfig.attackerWhitelist.add("minecraft:magma_cube"); - CombitConfig.attackerWhitelist.add("tconstruct:blueslime"); - CombitConfig.attackerWhitelist.add("thaumcraft:thaumslime"); - } - if (CombitConfig.targetEntityWhitelist == null) { - changed = true; - CombitConfig.targetEntityWhitelist = new HashSet<>(); - } - if (CombitConfig.damageSourceWhitelist == null) { - changed = true; - CombitConfig.damageSourceWhitelist = new HashSet<>(); - CombitConfig.damageSourceWhitelist.add(DamageSource.IN_FIRE.getName()); - CombitConfig.damageSourceWhitelist.add(DamageSource.LIGHTNING_BOLT.getName()); - CombitConfig.damageSourceWhitelist.add(DamageSource.LAVA.getName()); - CombitConfig.damageSourceWhitelist.add(DamageSource.HOT_FLOOR.getName()); - CombitConfig.damageSourceWhitelist.add(DamageSource.IN_WALL.getName()); - CombitConfig.damageSourceWhitelist.add(DamageSource.CACTUS.getName()); - CombitConfig.damageSourceWhitelist.add(DamageSource.OUT_OF_WORLD.getName()); - CombitConfig.damageSourceWhitelist.add(DamageSource.SWEET_BERRY_BUSH.getName()); - } - if (CombitConfig.entityHealthBlacklist == null) { - changed = true; - CombitConfig.entityHealthBlacklist = new HashSet<>(); - CombitConfig.entityHealthBlacklist.add("minecraft:player"); - } - if (changed) { - ConfigHolder.getInstance().getRegistered().get("combit").write(); - } - } -} diff --git a/src/main/java/io/gitlab/jfronny/combit/mixin/EggEntityMixin.java b/src/main/java/io/gitlab/jfronny/combit/mixin/EggEntityMixin.java new file mode 100644 index 0000000..b12de4e --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/combit/mixin/EggEntityMixin.java @@ -0,0 +1,36 @@ +package io.gitlab.jfronny.combit.mixin; + +import io.gitlab.jfronny.combit.CombitConfig; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.thrown.EggEntity; +import net.minecraft.entity.projectile.thrown.ThrownItemEntity; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.world.World; +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; + +@Mixin(EggEntity.class) +public abstract class EggEntityMixin extends ThrownItemEntity { + public EggEntityMixin(EntityType entityType, World world) { + super(entityType, world); + } + + @Inject(method = "onEntityHit(Lnet/minecraft/util/hit/EntityHitResult;)V", at = @At("TAIL")) + private void onEntityHit(EntityHitResult entityHitResult, CallbackInfo ci) { + Entity e = entityHitResult.getEntity(); + if (!(e instanceof PlayerEntity pe) || !pe.getAbilities().invulnerable) { + if (CombitConfig.eggKnockbackFactor != 0) { + e.setVelocity(e.getVelocity().add(this.getVelocity().normalize().multiply(CombitConfig.eggKnockbackFactor))); + e.velocityModified = true; + } + if (CombitConfig.eggDamage > 0) { + e.damage(DamageSource.thrownProjectile(this, this.getOwner()), CombitConfig.eggDamage); + } + } + } +} diff --git a/src/main/java/io/gitlab/jfronny/combit/mixin/FishingBobberEntityMixin.java b/src/main/java/io/gitlab/jfronny/combit/mixin/FishingBobberEntityMixin.java new file mode 100644 index 0000000..999983c --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/combit/mixin/FishingBobberEntityMixin.java @@ -0,0 +1,23 @@ +package io.gitlab.jfronny.combit.mixin; + +import io.gitlab.jfronny.combit.CombitConfig; +import net.minecraft.entity.Entity; +import net.minecraft.entity.projectile.FishingBobberEntity; +import net.minecraft.util.math.Vec3d; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(FishingBobberEntity.class) +public class FishingBobberEntityMixin { + @Redirect(method = "pullHookedEntity(Lnet/minecraft/entity/Entity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/Vec3d;multiply(D)Lnet/minecraft/util/math/Vec3d;")) + private Vec3d modifyMultiply(Vec3d instance, double value) { + return instance.multiply(value * CombitConfig.fishingBobberPullFactor); + } + + @Redirect(method = "pullHookedEntity(Lnet/minecraft/entity/Entity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;setVelocity(Lnet/minecraft/util/math/Vec3d;)V")) + private void setVelocityModified(Entity instance, Vec3d velocity) { + instance.setVelocity(velocity); + instance.velocityModified = true; + } +} diff --git a/src/main/java/io/gitlab/jfronny/combit/mixin/SnowballEntityMixin.java b/src/main/java/io/gitlab/jfronny/combit/mixin/SnowballEntityMixin.java new file mode 100644 index 0000000..9d31bb3 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/combit/mixin/SnowballEntityMixin.java @@ -0,0 +1,36 @@ +package io.gitlab.jfronny.combit.mixin; + +import io.gitlab.jfronny.combit.CombitConfig; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.thrown.SnowballEntity; +import net.minecraft.entity.projectile.thrown.ThrownItemEntity; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.world.World; +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; + +@Mixin(SnowballEntity.class) +public abstract class SnowballEntityMixin extends ThrownItemEntity { + public SnowballEntityMixin(EntityType entityType, World world) { + super(entityType, world); + } + + @Inject(method = "onEntityHit(Lnet/minecraft/util/hit/EntityHitResult;)V", at = @At("TAIL")) + private void onEntityHit(EntityHitResult entityHitResult, CallbackInfo ci) { + Entity e = entityHitResult.getEntity(); + if (!(e instanceof PlayerEntity pe) || !pe.getAbilities().invulnerable) { + if (CombitConfig.snowballKnockbackFactor != 0) { + e.setVelocity(e.getVelocity().add(this.getVelocity().normalize().multiply(CombitConfig.snowballKnockbackFactor))); + e.velocityModified = true; + } + if (CombitConfig.snowballDamage > 0) { + e.damage(DamageSource.thrownProjectile(this, this.getOwner()), CombitConfig.snowballDamage); + } + } + } +} diff --git a/src/main/resources/assets/combit/lang/en_us.json b/src/main/resources/assets/combit/lang/en_us.json index bc57965..311e365 100644 --- a/src/main/resources/assets/combit/lang/en_us.json +++ b/src/main/resources/assets/combit/lang/en_us.json @@ -32,6 +32,21 @@ "combit.jfconfig.axeAttackDamageFactor": "Axe Attack Damage Factor", "combit.jfconfig.axeAttackDamageFactor.tooltip": "Factor to multiply to the attack damage of axes", + "combit.jfconfig.snowballKnockbackFactor": "Snowball Knockback Factor", + "combit.jfconfig.snowballKnockbackFactor.tooltip": "The multiplier for knockback from snowballs (may be negative, 0 to disable)", + "combit.jfconfig.snowballDamage": "Snowball Damage", + "combit.jfconfig.snowballDamage.tooltip": "The amount of damage snowballs should cause", + "combit.jfconfig.eggKnockbackFactor": "Egg Knockback Factor", + "combit.jfconfig.eggKnockbackFactor.tooltip": "The multiplier for knockback from eggs (may be negative, 0 to disable)", + "combit.jfconfig.eggDamage": "Egg Damage", + "combit.jfconfig.eggDamage.tooltip": "The amount of damage eggs should cause", + "combit.jfconfig.fishingBobberPullFactor": "Fishing Bobber Pull Factor", + "combit.jfconfig.fishingBobberPullFactor.tooltip": "The multiplier for pulling through fishing rods (may be negative, 1 to disable)", + "combit.jfconfig.debug": "Debug", - "combit.jfconfig.debug.tooltip": "Enable Debug Logging" + "combit.jfconfig.debug.tooltip": "Enable Debug Logging", + + "combit.jfconfig.v189": "Minecraft 1.8.9", + "combit.jfconfig.noInvulnerability": "No Invulnerability", + "combit.jfconfig.disable": "Disable" } \ No newline at end of file diff --git a/src/main/resources/combit.mixins.json b/src/main/resources/combit.mixins.json index 6f8e6cd..da6b255 100644 --- a/src/main/resources/combit.mixins.json +++ b/src/main/resources/combit.mixins.json @@ -4,9 +4,12 @@ "package": "io.gitlab.jfronny.combit.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ + "EggEntityMixin", + "FishingBobberEntityMixin", "LivingEntityMixin", "MiningToolItemMixin", - "PlayerEntityMixin" + "PlayerEntityMixin", + "SnowballEntityMixin" ], "client": [ "InGameHudMixin" diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 94971fd..02e6b97 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -17,9 +17,6 @@ ], "libjf:config": [ "io.gitlab.jfronny.combit.CombitConfig" - ], - "libjf:early": [ - "io.gitlab.jfronny.combit.CombitConfigValidator" ] }, "mixins": [