From 3d1cf74f01ca63145e52b46bf4c4936ebec29b0e Mon Sep 17 00:00:00 2001 From: 17146 <1714673995@qq.com> Date: Tue, 24 Dec 2024 20:42:12 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=87=BB=E9=80=80=E5=88=A4?= =?UTF-8?q?=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/ICustomKnockback.java | 19 ++++++++++ .../entity/projectile/ProjectileEntity.java | 32 +++++++++++------ .../event/LivingEventHandler.java | 9 +++++ .../mixins/LivingEntityMixin.java | 36 ++++++++----------- 4 files changed, 63 insertions(+), 33 deletions(-) create mode 100644 src/main/java/com/atsuishio/superbwarfare/entity/ICustomKnockback.java diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/ICustomKnockback.java b/src/main/java/com/atsuishio/superbwarfare/entity/ICustomKnockback.java new file mode 100644 index 000000000..a2fb4e274 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/entity/ICustomKnockback.java @@ -0,0 +1,19 @@ +package com.atsuishio.superbwarfare.entity; + +import net.minecraft.world.entity.LivingEntity; + +/** + * Codes Based On @TACZ + */ +public interface ICustomKnockback { + + static ICustomKnockback getInstance(LivingEntity entity) { + return (ICustomKnockback) entity; + } + + void superbWarfare$setKnockbackStrength(double strength); + + void superbWarfare$resetKnockbackStrength(); + + double superbWarfare$getKnockbackStrength(); +} diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/ProjectileEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/ProjectileEntity.java index 67c5a8401..97fb55f9e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/ProjectileEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/ProjectileEntity.java @@ -99,6 +99,7 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa private boolean fireBullet = false; private int fireLevel = 0; private boolean dragonBreath = false; + private double knockback = 0.05; private final ArrayList mobEffects = new ArrayList<>(); public ProjectileEntity(EntityType p_i50159_1_, Level p_i50159_2_) { @@ -133,16 +134,13 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa for (Entity entity : entities) { if (entity.equals(this.shooter)) continue; - if (entity.equals(this.shooter.getVehicle())) continue; - if (entity instanceof TargetEntity && entity.getEntityData().get(TargetEntity.DOWN_TIME) > 0) continue; EntityResult result = this.getHitResult(entity, startVec, endVec); if (result == null) continue; Vec3 hitPos = result.getHitPos(); - if (hitPos == null) continue; double distanceToHit = startVec.distanceTo(hitPos); @@ -221,12 +219,12 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa boolean headshot = false; boolean legShot = false; float eyeHeight = entity.getEyeHeight(); - float BodyHeight = entity.getBbHeight(); + float bodyHeight = entity.getBbHeight(); if ((eyeHeight - 0.35) < hitBoxPos.y && hitBoxPos.y < (eyeHeight + 0.4) && !(entity instanceof ClaymoreEntity || entity instanceof MortarEntity || entity instanceof IVehicleEntity || entity instanceof DroneEntity)) { headshot = true; } - if (hitBoxPos.y < (0.33 * BodyHeight) && !(entity instanceof ClaymoreEntity || entity instanceof MortarEntity || + if (hitBoxPos.y < (0.33 * bodyHeight) && !(entity instanceof ClaymoreEntity || entity instanceof MortarEntity || entity instanceof IVehicleEntity || entity instanceof DroneEntity)) { legShot = true; } @@ -310,12 +308,10 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa @Override protected void readAdditionalSaveData(CompoundTag compoundTag) { - } @Override protected void addAdditionalSaveData(CompoundTag compoundTag) { - } protected void onProjectileTick() { @@ -518,13 +514,11 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new ClientIndicatorMessage(1, 5)); } - - performDamage(entity, this.damage, true); + performOnHit(entity, this.damage, true, this.knockback); } else { if (!this.shooter.level().isClientSide() && this.shooter instanceof ServerPlayer player) { var holder = Holder.direct(ModSounds.INDICATION.get()); player.connection.send(new ClientboundSoundPacket(holder, SoundSource.PLAYERS, player.getX(), player.getY(), player.getZ(), 1f, 1f, player.level().random.nextLong())); - ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new ClientIndicatorMessage(0, 5)); } @@ -540,7 +534,7 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa this.damage *= this.legShot; } - performDamage(entity, this.damage, false); + performOnHit(entity, this.damage, false, this.knockback); } if (!this.mobEffects.isEmpty() && entity instanceof LivingEntity living) { @@ -552,6 +546,17 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa this.discard(); } + public void performOnHit(Entity entity, float damage, boolean headshot, double knockback) { + if (entity instanceof LivingEntity living) { + ICustomKnockback iCustomKnockback = ICustomKnockback.getInstance(living); + iCustomKnockback.superbWarfare$setKnockbackStrength(knockback); + performDamage(entity, damage, headshot); + iCustomKnockback.superbWarfare$resetKnockbackStrength(); + } else { + performDamage(entity, damage, headshot); + } + } + protected void explosionBulletBlock(Entity projectile, float damage, int heLevel, float monsterMultiple, Vec3 hitVec) { CustomExplosion explosion = new CustomExplosion(projectile.level(), projectile, ModDamageTypes.causeProjectileBoomDamage(projectile.level().registryAccess(), projectile, this.getShooter()), (float) ((0.9 * damage) * (1 + 0.1 * heLevel)), @@ -857,4 +862,9 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa this.entityData.set(COLOR_G, rgb[1]); this.entityData.set(COLOR_B, rgb[2]); } + + public ProjectileEntity knockback(double knockback) { + this.knockback = knockback; + return this; + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java index 2e64d18d2..71f5c98a0 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java @@ -5,6 +5,7 @@ import com.atsuishio.superbwarfare.capability.LaserCapability; import com.atsuishio.superbwarfare.capability.ModCapabilities; import com.atsuishio.superbwarfare.config.common.GameplayConfig; import com.atsuishio.superbwarfare.entity.ICannonEntity; +import com.atsuishio.superbwarfare.entity.ICustomKnockback; import com.atsuishio.superbwarfare.entity.IVehicleEntity; import com.atsuishio.superbwarfare.entity.TargetEntity; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; @@ -785,4 +786,12 @@ public class LivingEventHandler { event.setAmount(event.getAmount() * (1.15f + 0.05f * level)); } + + @SubscribeEvent + public static void onKnockback(LivingKnockBackEvent event) { + ICustomKnockback knockback = ICustomKnockback.getInstance(event.getEntity()); + if (knockback.superbWarfare$getKnockbackStrength() >= 0) { + event.setStrength((float) knockback.superbWarfare$getKnockbackStrength()); + } + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/mixins/LivingEntityMixin.java b/src/main/java/com/atsuishio/superbwarfare/mixins/LivingEntityMixin.java index 845e27a4b..fc776815b 100644 --- a/src/main/java/com/atsuishio/superbwarfare/mixins/LivingEntityMixin.java +++ b/src/main/java/com/atsuishio/superbwarfare/mixins/LivingEntityMixin.java @@ -1,36 +1,28 @@ package com.atsuishio.superbwarfare.mixins; -import com.atsuishio.superbwarfare.init.ModDamageTypes; -import net.minecraft.world.damagesource.DamageSource; +import com.atsuishio.superbwarfare.entity.ICustomKnockback; import net.minecraft.world.entity.LivingEntity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(LivingEntity.class) -public class LivingEntityMixin { +public class LivingEntityMixin implements ICustomKnockback { @Unique - private DamageSource target$source; + private double superbwarfare$knockbackStrength = 0; - @Inject(method = "hurt", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;knockback(DDD)V")) - private void capture(DamageSource source, float amount, CallbackInfoReturnable cir) { - this.target$source = source; + @Override + public void superbWarfare$setKnockbackStrength(double strength) { + this.superbwarfare$knockbackStrength = strength; } - @ModifyArg(method = "hurt", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;knockback(DDD)V"), index = 0) - private double modifyApplyKnockbackArgs(double original) { - if (this.target$source.is(ModDamageTypes.GUN_FIRE) || this.target$source.is(ModDamageTypes.GUN_FIRE_HEADSHOT) - || this.target$source.is(ModDamageTypes.SHOCK) || this.target$source.is(ModDamageTypes.GUN_FIRE_ABSOLUTE) - || this.target$source.is(ModDamageTypes.GUN_FIRE_HEADSHOT_ABSOLUTE) || this.target$source.is(ModDamageTypes.BURN)) { - return 0.05 * original; - } - if (this.target$source.is(ModDamageTypes.LASER) || this.target$source.is(ModDamageTypes.LASER_HEADSHOT)) { - return -original; - } - return original; + @Override + public void superbWarfare$resetKnockbackStrength() { + this.superbwarfare$knockbackStrength = -1; + } + + @Override + public double superbWarfare$getKnockbackStrength() { + return this.superbwarfare$knockbackStrength; } } \ No newline at end of file