From ad5a50e45187e0304c150be3e6f16532f186c171 Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Sat, 22 Feb 2025 23:59:35 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=86=99=E8=BD=BD=E5=85=B7=E4=BC=A4?= =?UTF-8?q?=E5=AE=B3=E5=85=8D=E7=96=AB=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../superbwarfare/entity/MortarEntity.java | 5 +- .../entity/vehicle/Ah6Entity.java | 84 ++++------ .../entity/vehicle/AnnihilatorEntity.java | 80 +++------ .../entity/vehicle/Bmp2Entity.java | 85 ++++------ .../entity/vehicle/DroneEntity.java | 2 + .../entity/vehicle/LaserTowerEntity.java | 84 ++++------ .../entity/vehicle/Lav150Entity.java | 85 ++++------ .../entity/vehicle/Mk42Entity.java | 84 +++------- .../entity/vehicle/Mle1934Entity.java | 84 +++------- .../entity/vehicle/SpeedboatEntity.java | 85 ++++------ .../entity/vehicle/Tom6Entity.java | 15 +- .../entity/vehicle/VehicleEntity.java | 46 ++--- .../entity/vehicle/WheelChairEntity.java | 5 +- .../entity/vehicle/damage/DamageModifier.java | 157 ++++++++++++++++++ .../entity/vehicle/damage/DamageModify.java | 73 ++++++++ 15 files changed, 499 insertions(+), 475 deletions(-) create mode 100644 src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModifier.java create mode 100644 src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModify.java diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/MortarEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/MortarEntity.java index 0bb3b7826..ff108d8c5 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/MortarEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/MortarEntity.java @@ -93,9 +93,12 @@ public class MortarEntity extends VehicleEntity implements GeoEntity, AnimatedEn @Override public boolean hurt(DamageSource source, float amount) { - super.hurt(source, amount); this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1); + + amount = damageModifier.compute(source, amount); + super.hurt(source, amount); this.hurt(amount, source.getEntity(), true); + return true; } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java index e9367fdf7..a4e116b3f 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java @@ -6,6 +6,7 @@ import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.entity.projectile.FlareDecoyEntity; import com.atsuishio.superbwarfare.entity.projectile.HeliRocketEntity; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.network.message.ShakeClientMessage; import com.atsuishio.superbwarfare.tools.CustomExplosion; @@ -132,69 +133,39 @@ public class Ah6Entity extends ContainerMobileEntity implements GeoEntity, IHeli @Override public boolean hurt(DamageSource source, float amount) { - super.hurt(source, amount); if (this.level() instanceof ServerLevel serverLevel) { sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), this.getX(), this.getY() + 2.5, this.getZ(), 4, 0.2, 0.2, 0.2, 0.2, false); } - - if (source.is(DamageTypes.ARROW)) { - amount *= 0.1f; - } - if (source.is(DamageTypes.TRIDENT)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.MOB_ATTACK)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.MOB_ATTACK_NO_AGGRO)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.MOB_PROJECTILE)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.PLAYER_ATTACK)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.LAVA)) { - amount *= 2f; - } - if (source.is(DamageTypes.EXPLOSION)) { - amount *= 2f; - } - if (source.is(DamageTypes.PLAYER_EXPLOSION)) { - amount *= 2f; - } - - if (source.is(ModDamageTypes.CUSTOM_EXPLOSION)) { - amount *= 1f; - } - if (source.is(ModDamageTypes.PROJECTILE_BOOM)) { - amount *= 1f; - } - if (source.is(ModDamageTypes.MINE)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.LUNGE_MINE)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.CANNON_FIRE)) { - amount *= 0.4f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE)) { - amount *= 0.08f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE_ABSOLUTE)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.VEHICLE_STRIKE)) { - amount *= 5f; - } - this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1); - this.hurt(Math.max(amount - 2, 0), source.getEntity(), true); + + amount = getDamageModifier().compute(source, amount); + super.hurt(source, amount); + this.hurt(amount, source.getEntity(), true); + return true; } + @Override + public DamageModifier getDamageModifier() { + return super.getDamageModifier() + .multiply(0.1f, DamageTypes.ARROW) + .multiply(0.2f, DamageTypes.TRIDENT) + .multiply(0.2f, DamageTypes.MOB_ATTACK) + .multiply(0.2f, DamageTypes.MOB_ATTACK_NO_AGGRO) + .multiply(0.2f, DamageTypes.MOB_PROJECTILE) + .multiply(0.2f, DamageTypes.PLAYER_ATTACK) + .multiply(2, DamageTypes.LAVA) + .multiply(2, DamageTypes.EXPLOSION) + .multiply(2, DamageTypes.PLAYER_EXPLOSION) + .multiply(0.5f, ModDamageTypes.MINE) + .multiply(0.5f, ModDamageTypes.LUNGE_MINE) + .multiply(0.4f, ModDamageTypes.CANNON_FIRE) + .multiply(0.08f, ModTags.DamageTypes.PROJECTILE) + .multiply(0.5f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE) + .multiply(5, ModDamageTypes.VEHICLE_STRIKE) + .reduce(2); + } + @Override public void baseTick() { propellerRotO = this.getPropellerRot(); @@ -809,6 +780,7 @@ public class Ah6Entity extends ContainerMobileEntity implements GeoEntity, IHeli public ResourceLocation getVehicleIcon() { return ModUtils.loc("textures/vehicle_icon/ah_6_icon.png"); } + @Override public boolean allowFreeCam() { return true; diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java index 5c9d23f26..90735cced 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java @@ -3,6 +3,7 @@ package com.atsuishio.superbwarfare.entity.vehicle; import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.network.message.ShakeClientMessage; import com.atsuishio.superbwarfare.tools.*; @@ -117,66 +118,39 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity, @Override public boolean hurt(DamageSource source, float amount) { - super.hurt(source, amount); if (this.level() instanceof ServerLevel serverLevel) { sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), this.getX(), this.getY() + 2.5, this.getZ(), 4, 0.2, 0.2, 0.2, 0.2, false); } - - if (source.is(DamageTypes.ARROW)) { - amount *= 0f; - } - if (source.is(DamageTypes.TRIDENT)) { - amount *= 0f; - } - if (source.is(DamageTypes.MOB_ATTACK)) { - amount *= 0f; - } - if (source.is(DamageTypes.MOB_ATTACK_NO_AGGRO)) { - amount *= 0f; - } - if (source.is(DamageTypes.MOB_PROJECTILE)) { - amount *= 0f; - } - if (source.is(DamageTypes.PLAYER_ATTACK)) { - amount *= 0f; - } - if (source.is(DamageTypes.EXPLOSION)) { - amount *= 0.75f; - } - if (source.is(DamageTypes.PLAYER_EXPLOSION)) { - amount *= 0.75f; - } - - if (source.is(ModDamageTypes.CUSTOM_EXPLOSION)) { - amount *= 0.2f; - } - if (source.is(ModDamageTypes.PROJECTILE_BOOM)) { - amount *= 0.2f; - } - if (source.is(ModDamageTypes.MINE)) { - amount *= 0.1f; - } - if (source.is(ModDamageTypes.LUNGE_MINE)) { - amount *= 0.12f; - } - if (source.is(ModDamageTypes.CANNON_FIRE)) { - amount *= 0.22f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE)) { - amount *= 0f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE_ABSOLUTE)) { - amount *= 0.15f; - } - if (source.is(ModDamageTypes.VEHICLE_STRIKE)) { - amount *= 0f; - } - this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1); - this.hurt(Math.max(amount - 10, 0), source.getEntity(), true); + + amount = damageModifier.compute(source, amount); + super.hurt(source, amount); + this.hurt(amount, source.getEntity(), true); + return true; } + @Override + public DamageModifier getDamageModifier() { + return super.getDamageModifier() + .immuneTo(DamageTypes.ARROW) + .immuneTo(DamageTypes.TRIDENT) + .immuneTo(DamageTypes.MOB_ATTACK) + .immuneTo(DamageTypes.MOB_ATTACK_NO_AGGRO) + .immuneTo(DamageTypes.MOB_PROJECTILE) + .immuneTo(DamageTypes.PLAYER_ATTACK) + .immuneTo(ModTags.DamageTypes.PROJECTILE) + .immuneTo(ModDamageTypes.VEHICLE_STRIKE) + .multiply(0.75f, DamageTypes.EXPLOSION) + .multiply(0.2f, ModDamageTypes.CUSTOM_EXPLOSION) + .multiply(0.2f, ModDamageTypes.PROJECTILE_BOOM) + .multiply(0.1f, ModDamageTypes.MINE) + .multiply(0.12f, ModDamageTypes.LUNGE_MINE) + .multiply(0.22f, ModDamageTypes.CANNON_FIRE) + .multiply(0.15f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE) + .reduce(10); + } + @Override public Vec3 getDeltaMovement() { return new Vec3(0, Math.min(super.getDeltaMovement().y, 0), 0); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Bmp2Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Bmp2Entity.java index 6db13b609..ebbabe801 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Bmp2Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Bmp2Entity.java @@ -6,6 +6,7 @@ import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import com.atsuishio.superbwarfare.entity.projectile.SmallCannonShellEntity; import com.atsuishio.superbwarfare.entity.projectile.WgMissileEntity; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.network.ModVariables; import com.atsuishio.superbwarfare.network.message.ShakeClientMessage; @@ -138,69 +139,41 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ILan @Override public boolean hurt(DamageSource source, float amount) { - super.hurt(source, amount); if (this.level() instanceof ServerLevel serverLevel) { sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), this.getX(), this.getY() + 2.5, this.getZ(), 4, 0.2, 0.2, 0.2, 0.2, false); } - - if (source.is(DamageTypes.ARROW)) { - amount *= 0.3f; - } - if (source.is(DamageTypes.TRIDENT)) { - amount *= 0.3f; - } - if (source.is(DamageTypes.MOB_ATTACK)) { - amount *= 0.5f; - } - if (source.is(DamageTypes.MOB_ATTACK_NO_AGGRO)) { - amount *= 0.4f; - } - if (source.is(DamageTypes.MOB_PROJECTILE)) { - amount *= 0.3f; - } - if (source.is(DamageTypes.PLAYER_ATTACK)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.LAVA)) { - amount *= 2.5f; - } - if (source.is(DamageTypes.EXPLOSION)) { - amount *= 1.2f; - } - if (source.is(DamageTypes.PLAYER_EXPLOSION)) { - amount *= 1.2f; - } - - if (source.is(ModDamageTypes.CUSTOM_EXPLOSION)) { - amount *= 0.4f; - } - if (source.is(ModDamageTypes.PROJECTILE_BOOM)) { - amount *= 0.4f; - } - if (source.is(ModDamageTypes.MINE)) { - amount *= 0.14f; - } - if (source.is(ModDamageTypes.LUNGE_MINE)) { - amount *= 0.18f; - } - if (source.is(ModDamageTypes.CANNON_FIRE)) { - amount *= 0.3f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE)) { - amount *= 0.02f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE_ABSOLUTE)) { - amount *= 0.14f; - } - if (source.is(ModDamageTypes.VEHICLE_STRIKE)) { - amount *= 1.7f; - } - this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1); - this.hurt(Math.max(amount - 8, 0), source.getEntity(), true); + + amount = damageModifier.compute(source, amount); + super.hurt(source, amount); + this.hurt(amount, source.getEntity(), true); + return true; } + @Override + public DamageModifier getDamageModifier() { + return super.getDamageModifier() + .multiply(0.3f, DamageTypes.ARROW) + .multiply(0.3f, DamageTypes.TRIDENT) + .multiply(0.5f, DamageTypes.MOB_ATTACK) + .multiply(0.4f, DamageTypes.MOB_ATTACK_NO_AGGRO) + .multiply(0.3f, DamageTypes.MOB_PROJECTILE) + .multiply(0.2f, DamageTypes.PLAYER_ATTACK) + .multiply(2.5f, DamageTypes.LAVA) + .multiply(1.2f, DamageTypes.EXPLOSION) + .multiply(1.2f, DamageTypes.PLAYER_EXPLOSION) + .multiply(0.4f, ModDamageTypes.CUSTOM_EXPLOSION) + .multiply(0.4f, ModDamageTypes.PROJECTILE_BOOM) + .multiply(0.14f, ModDamageTypes.MINE) + .multiply(0.18f, ModDamageTypes.LUNGE_MINE) + .multiply(0.3f, ModDamageTypes.CANNON_FIRE) + .multiply(0.02f, ModTags.DamageTypes.PROJECTILE) + .multiply(0.14f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE) + .multiply(1.7f, ModDamageTypes.VEHICLE_STRIKE) + .reduce(8); + } + @Override protected void playStepSound(BlockPos pPos, BlockState pState) { this.playSound(ModSounds.BMP_STEP.get(), Mth.abs(this.entityData.get(POWER)) * 8, random.nextFloat() * 0.15f + 1f); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java index 19228832a..82a1787a3 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java @@ -107,8 +107,10 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { @Override public boolean hurt(DamageSource source, float amount) { + amount = damageModifier.compute(source, amount); super.hurt(source, amount); this.hurt(amount, source.getEntity(), false); + return true; } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/LaserTowerEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/LaserTowerEntity.java index b5df5b951..6824b7e79 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/LaserTowerEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/LaserTowerEntity.java @@ -1,5 +1,6 @@ package com.atsuishio.superbwarfare.entity.vehicle; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.ContainerBlockItem; import com.atsuishio.superbwarfare.tools.CustomExplosion; @@ -142,69 +143,40 @@ public class LaserTowerEntity extends EnergyVehicleEntity implements GeoEntity, @Override public boolean hurt(DamageSource source, float amount) { - super.hurt(source, amount); if (this.level() instanceof ServerLevel serverLevel) { sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), this.getX(), this.getY() + 0.8, this.getZ(), 4, 0.1, 0.1, 0.1, 0.2, false); } - - if (source.is(DamageTypes.ARROW)) { - amount *= 0.1f; - } - if (source.is(DamageTypes.TRIDENT)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.MOB_ATTACK)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.MOB_ATTACK_NO_AGGRO)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.MOB_PROJECTILE)) { - amount *= 0.4f; - } - if (source.is(DamageTypes.PLAYER_ATTACK)) { - amount *= 0.4f; - } - if (source.is(DamageTypes.LAVA)) { - amount *= 1f; - } - if (source.is(DamageTypes.EXPLOSION)) { - amount *= 1.5f; - } - if (source.is(DamageTypes.PLAYER_EXPLOSION)) { - amount *= 1.5f; - } - - if (source.is(ModDamageTypes.CUSTOM_EXPLOSION)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.PROJECTILE_BOOM)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.MINE)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.LUNGE_MINE)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.CANNON_FIRE)) { - amount *= 0.6f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE)) { - amount *= 0.5f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE_ABSOLUTE)) { - amount *= 0.8f; - } - if (source.is(ModDamageTypes.VEHICLE_STRIKE)) { - amount *= 2f; - } - this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1); - this.hurt(Math.max(amount - 1, 0), source.getEntity(), true); + + amount = damageModifier.compute(source, amount); + super.hurt(source, amount); + this.hurt(amount, source.getEntity(), true); + return true; } + @Override + public DamageModifier getDamageModifier() { + return super.getDamageModifier() + .multiply(0.1f, DamageTypes.ARROW) + .multiply(0.2f, DamageTypes.TRIDENT) + .multiply(0.2f, DamageTypes.MOB_ATTACK) + .multiply(0.2f, DamageTypes.MOB_ATTACK_NO_AGGRO) + .multiply(0.4f, DamageTypes.MOB_PROJECTILE) + .multiply(0.4f, DamageTypes.PLAYER_ATTACK) + .multiply(1.5f, DamageTypes.EXPLOSION) + .multiply(1.5f, DamageTypes.PLAYER_EXPLOSION) + .multiply(0.5f, ModDamageTypes.CUSTOM_EXPLOSION) + .multiply(0.5f, ModDamageTypes.PROJECTILE_BOOM) + .multiply(0.5f, ModDamageTypes.MINE) + .multiply(0.5f, ModDamageTypes.LUNGE_MINE) + .multiply(0.6f, ModDamageTypes.CANNON_FIRE) + .multiply(0.5f, ModTags.DamageTypes.PROJECTILE) + .multiply(0.8f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE) + .multiply(2f, ModDamageTypes.VEHICLE_STRIKE) + .reduce(1); + } + @Override public InteractionResult interact(Player player, InteractionHand hand) { ItemStack stack = player.getMainHandItem(); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java index 02fb119f4..054a1e1c8 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java @@ -5,6 +5,7 @@ import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import com.atsuishio.superbwarfare.entity.projectile.SmallCannonShellEntity; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.network.ModVariables; import com.atsuishio.superbwarfare.network.message.ShakeClientMessage; @@ -135,69 +136,41 @@ public class Lav150Entity extends ContainerMobileEntity implements GeoEntity, IL @Override public boolean hurt(DamageSource source, float amount) { - super.hurt(source, amount); if (this.level() instanceof ServerLevel serverLevel) { sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), this.getX(), this.getY() + 2.5, this.getZ(), 4, 0.2, 0.2, 0.2, 0.2, false); } - - if (source.is(DamageTypes.ARROW)) { - amount *= 0.3f; - } - if (source.is(DamageTypes.TRIDENT)) { - amount *= 0.3f; - } - if (source.is(DamageTypes.MOB_ATTACK)) { - amount *= 0.5f; - } - if (source.is(DamageTypes.MOB_ATTACK_NO_AGGRO)) { - amount *= 0.4f; - } - if (source.is(DamageTypes.MOB_PROJECTILE)) { - amount *= 0.3f; - } - if (source.is(DamageTypes.PLAYER_ATTACK)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.LAVA)) { - amount *= 2.5f; - } - if (source.is(DamageTypes.EXPLOSION)) { - amount *= 1.2f; - } - if (source.is(DamageTypes.PLAYER_EXPLOSION)) { - amount *= 1.2f; - } - - if (source.is(ModDamageTypes.CUSTOM_EXPLOSION)) { - amount *= 0.4f; - } - if (source.is(ModDamageTypes.PROJECTILE_BOOM)) { - amount *= 0.4f; - } - if (source.is(ModDamageTypes.MINE)) { - amount *= 0.15f; - } - if (source.is(ModDamageTypes.LUNGE_MINE)) { - amount *= 0.2f; - } - if (source.is(ModDamageTypes.CANNON_FIRE)) { - amount *= 0.3f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE)) { - amount *= 0.05f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE_ABSOLUTE)) { - amount *= 0.17f; - } - if (source.is(ModDamageTypes.VEHICLE_STRIKE)) { - amount *= 2f; - } - this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1); - this.hurt(Math.max(amount - 7, 0), source.getEntity(), true); + + amount = damageModifier.compute(source, amount); + super.hurt(source, amount); + this.hurt(amount, source.getEntity(), true); + return true; } + @Override + public DamageModifier getDamageModifier() { + return super.getDamageModifier() + .multiply(0.3f, DamageTypes.ARROW) + .multiply(0.3f, DamageTypes.TRIDENT) + .multiply(0.5f, DamageTypes.MOB_ATTACK) + .multiply(0.4f, DamageTypes.MOB_ATTACK_NO_AGGRO) + .multiply(0.3f, DamageTypes.MOB_PROJECTILE) + .multiply(0.2f, DamageTypes.PLAYER_ATTACK) + .multiply(2.5f, DamageTypes.LAVA) + .multiply(1.2f, DamageTypes.EXPLOSION) + .multiply(1.2f, DamageTypes.PLAYER_EXPLOSION) + .multiply(0.4f, ModDamageTypes.CUSTOM_EXPLOSION) + .multiply(0.4f, ModDamageTypes.PROJECTILE_BOOM) + .multiply(0.15f, ModDamageTypes.MINE) + .multiply(0.2f, ModDamageTypes.LUNGE_MINE) + .multiply(0.3f, ModDamageTypes.CANNON_FIRE) + .multiply(0.05f, ModTags.DamageTypes.PROJECTILE) + .multiply(0.17f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE) + .multiply(2f, ModDamageTypes.VEHICLE_STRIKE) + .reduce(7); + } + public double getSubmergedHeight(Entity entity) { for (FluidType fluidType : ForgeRegistries.FLUID_TYPES.get().getValues()) { if (entity.level().getFluidState(entity.blockPosition()).getFluidType() == fluidType) diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mk42Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mk42Entity.java index ca051105a..38826473d 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mk42Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mk42Entity.java @@ -4,6 +4,7 @@ import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.entity.projectile.CannonShellEntity; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.common.ammo.CannonShellItem; import com.atsuishio.superbwarfare.network.message.ShakeClientMessage; @@ -103,70 +104,39 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, ICannonEntit @Override public boolean hurt(DamageSource source, float amount) { - super.hurt(source, amount); if (this.level() instanceof ServerLevel serverLevel) { sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), this.getX(), this.getY() + 2.5, this.getZ(), 4, 0.2, 0.2, 0.2, 0.2, false); } - - if (source.is(DamageTypes.ARROW)) { - amount *= 0.1f; - } - if (source.is(DamageTypes.TRIDENT)) { - amount *= 0.1f; - } - if (source.is(DamageTypes.MOB_ATTACK)) { - amount *= 0.3f; - } - if (source.is(DamageTypes.MOB_ATTACK_NO_AGGRO)) { - amount *= 0.15f; - } - if (source.is(DamageTypes.MOB_PROJECTILE)) { - amount *= 0.15f; - } - if (source.is(DamageTypes.PLAYER_ATTACK)) { - amount *= 0.1f; - - } - if (source.is(DamageTypes.LAVA)) { - amount *= 2.5f; - } - if (source.is(DamageTypes.EXPLOSION)) { - amount *= 1f; - } - if (source.is(DamageTypes.PLAYER_EXPLOSION)) { - amount *= 1f; - } - - if (source.is(ModDamageTypes.CUSTOM_EXPLOSION)) { - amount *= 0.4f; - } - if (source.is(ModDamageTypes.PROJECTILE_BOOM)) { - amount *= 0.4f; - } - if (source.is(ModDamageTypes.MINE)) { - amount *= 0.14f; - } - if (source.is(ModDamageTypes.LUNGE_MINE)) { - amount *= 0.14f; - } - if (source.is(ModDamageTypes.CANNON_FIRE)) { - amount *= 0.3f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE)) { - amount *= 0.02f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE_ABSOLUTE)) { - amount *= 0.14f; - } - if (source.is(ModDamageTypes.VEHICLE_STRIKE)) { - amount *= 1.7f; - } - this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1); - this.hurt(Math.max(amount - 8, 0), source.getEntity(), true); + + amount = damageModifier.compute(source, amount); + super.hurt(source, amount); + this.hurt(amount, source.getEntity(), true); + return true; } + @Override + public DamageModifier getDamageModifier() { + return super.getDamageModifier() + .multiply(0.1f, DamageTypes.ARROW) + .multiply(0.1f, DamageTypes.TRIDENT) + .multiply(0.3f, DamageTypes.MOB_ATTACK) + .multiply(0.15f, DamageTypes.MOB_ATTACK_NO_AGGRO) + .multiply(0.15f, DamageTypes.MOB_PROJECTILE) + .multiply(0.1f, DamageTypes.PLAYER_ATTACK) + .multiply(2.5f, DamageTypes.LAVA) + .multiply(0.4f, ModDamageTypes.CUSTOM_EXPLOSION) + .multiply(0.4f, ModDamageTypes.PROJECTILE_BOOM) + .multiply(0.14f, ModDamageTypes.MINE) + .multiply(0.14f, ModDamageTypes.LUNGE_MINE) + .multiply(0.3f, ModDamageTypes.CANNON_FIRE) + .multiply(0.02f, ModTags.DamageTypes.PROJECTILE) + .multiply(0.14f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE) + .multiply(1.7f, ModDamageTypes.VEHICLE_STRIKE) + .reduce(8); + } + @Override public Vec3 getDeltaMovement() { return new Vec3(0, Math.min(super.getDeltaMovement().y, 0), 0); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mle1934Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mle1934Entity.java index fe841207e..cb47d4cff 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mle1934Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Mle1934Entity.java @@ -4,6 +4,7 @@ import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.entity.projectile.CannonShellEntity; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.common.ammo.CannonShellItem; import com.atsuishio.superbwarfare.network.message.ShakeClientMessage; @@ -113,70 +114,39 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, ICannonEn @Override public boolean hurt(DamageSource source, float amount) { - super.hurt(source, amount); if (this.level() instanceof ServerLevel serverLevel) { sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), this.getX(), this.getY() + 2.5, this.getZ(), 4, 0.2, 0.2, 0.2, 0.2, false); } - - if (source.is(DamageTypes.ARROW)) { - amount *= 0.1f; - } - if (source.is(DamageTypes.TRIDENT)) { - amount *= 0.1f; - } - if (source.is(DamageTypes.MOB_ATTACK)) { - amount *= 0.3f; - } - if (source.is(DamageTypes.MOB_ATTACK_NO_AGGRO)) { - amount *= 0.15f; - } - if (source.is(DamageTypes.MOB_PROJECTILE)) { - amount *= 0.15f; - } - if (source.is(DamageTypes.PLAYER_ATTACK)) { - amount *= 0.1f; - - } - if (source.is(DamageTypes.LAVA)) { - amount *= 2.5f; - } - if (source.is(DamageTypes.EXPLOSION)) { - amount *= 1f; - } - if (source.is(DamageTypes.PLAYER_EXPLOSION)) { - amount *= 1f; - } - - if (source.is(ModDamageTypes.CUSTOM_EXPLOSION)) { - amount *= 0.4f; - } - if (source.is(ModDamageTypes.PROJECTILE_BOOM)) { - amount *= 0.4f; - } - if (source.is(ModDamageTypes.MINE)) { - amount *= 0.14f; - } - if (source.is(ModDamageTypes.LUNGE_MINE)) { - amount *= 0.14f; - } - if (source.is(ModDamageTypes.CANNON_FIRE)) { - amount *= 0.3f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE)) { - amount *= 0.02f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE_ABSOLUTE)) { - amount *= 0.14f; - } - if (source.is(ModDamageTypes.VEHICLE_STRIKE)) { - amount *= 1.7f; - } - this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1); - this.hurt(Math.max(amount - 8, 0), source.getEntity(), true); + + amount = damageModifier.compute(source, amount); + super.hurt(source, amount); + this.hurt(amount, source.getEntity(), true); + return true; } + @Override + public DamageModifier getDamageModifier() { + return super.getDamageModifier() + .multiply(0.1f, DamageTypes.ARROW) + .multiply(0.1f, DamageTypes.TRIDENT) + .multiply(0.3f, DamageTypes.MOB_ATTACK) + .multiply(0.15f, DamageTypes.MOB_ATTACK_NO_AGGRO) + .multiply(0.15f, DamageTypes.MOB_PROJECTILE) + .multiply(0.1f, DamageTypes.PLAYER_ATTACK) + .multiply(2.5f, DamageTypes.LAVA) + .multiply(0.4f, ModDamageTypes.CUSTOM_EXPLOSION) + .multiply(0.4f, ModDamageTypes.PROJECTILE_BOOM) + .multiply(0.14f, ModDamageTypes.MINE) + .multiply(0.14f, ModDamageTypes.LUNGE_MINE) + .multiply(0.3f, ModDamageTypes.CANNON_FIRE) + .multiply(0.02f, ModTags.DamageTypes.PROJECTILE) + .multiply(0.14f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE) + .multiply(1.7f, ModDamageTypes.VEHICLE_STRIKE) + .reduce(8); + } + @Override public Vec3 getDeltaMovement() { return new Vec3(0, Math.min(super.getDeltaMovement().y, 0), 0); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/SpeedboatEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/SpeedboatEntity.java index 026060143..c6ad86108 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/SpeedboatEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/SpeedboatEntity.java @@ -4,6 +4,7 @@ import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.network.ModVariables; import com.atsuishio.superbwarfare.network.message.ShakeClientMessage; @@ -114,69 +115,41 @@ public class SpeedboatEntity extends ContainerMobileEntity implements GeoEntity, @Override public boolean hurt(DamageSource source, float amount) { - super.hurt(source, amount); if (this.level() instanceof ServerLevel serverLevel) { sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), this.getX(), this.getY() + 2.5, this.getZ(), 4, 0.2, 0.2, 0.2, 0.2, false); } - - if (source.is(DamageTypes.ARROW)) { - amount *= 0.1f; - } - if (source.is(DamageTypes.TRIDENT)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.MOB_ATTACK)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.MOB_ATTACK_NO_AGGRO)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.MOB_PROJECTILE)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.PLAYER_ATTACK)) { - amount *= 0.2f; - } - if (source.is(DamageTypes.LAVA)) { - amount *= 2f; - } - if (source.is(DamageTypes.EXPLOSION)) { - amount *= 2f; - } - if (source.is(DamageTypes.PLAYER_EXPLOSION)) { - amount *= 2f; - } - - if (source.is(ModDamageTypes.CUSTOM_EXPLOSION)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.PROJECTILE_BOOM)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.MINE)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.LUNGE_MINE)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.CANNON_FIRE)) { - amount *= 0.6f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE)) { - amount *= 0.08f; - } - if (source.is(ModTags.DamageTypes.PROJECTILE_ABSOLUTE)) { - amount *= 0.5f; - } - if (source.is(ModDamageTypes.VEHICLE_STRIKE)) { - amount *= 5f; - } - this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1); - this.hurt(Math.max(amount - 2, 0), source.getEntity(), true); + + amount = damageModifier.compute(source, amount); + super.hurt(source, amount); + this.hurt(amount, source.getEntity(), true); + return true; } + @Override + public DamageModifier getDamageModifier() { + return super.getDamageModifier() + .multiply(0.1f, DamageTypes.ARROW) + .multiply(0.2f, DamageTypes.TRIDENT) + .multiply(0.2f, DamageTypes.MOB_ATTACK) + .multiply(0.2f, DamageTypes.MOB_ATTACK_NO_AGGRO) + .multiply(0.2f, DamageTypes.MOB_PROJECTILE) + .multiply(0.2f, DamageTypes.PLAYER_ATTACK) + .multiply(2f, DamageTypes.LAVA) + .multiply(2f, DamageTypes.EXPLOSION) + .multiply(2f, DamageTypes.PLAYER_EXPLOSION) + .multiply(0.5f, ModDamageTypes.CUSTOM_EXPLOSION) + .multiply(0.5f, ModDamageTypes.PROJECTILE_BOOM) + .multiply(0.5f, ModDamageTypes.MINE) + .multiply(0.5f, ModDamageTypes.LUNGE_MINE) + .multiply(0.6f, ModDamageTypes.CANNON_FIRE) + .multiply(0.08f, ModTags.DamageTypes.PROJECTILE) + .multiply(0.5f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE) + .multiply(5f, ModDamageTypes.VEHICLE_STRIKE) + .reduce(2); + } + @Override public void baseTick() { turretYRotO = this.getTurretYRot(); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java index d2f821539..39ba55878 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java @@ -4,6 +4,7 @@ import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModEntities; import com.atsuishio.superbwarfare.init.ModSounds; @@ -97,15 +98,21 @@ public class Tom6Entity extends MobileVehicleEntity implements GeoEntity { @Override public boolean hurt(DamageSource source, float amount) { - super.hurt(source, amount); - if (source.is(ModDamageTypes.VEHICLE_STRIKE)) { - amount *= 2f; - } this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1); + + amount = damageModifier.compute(source, amount); this.hurt(amount, source.getEntity(), true); + super.hurt(source, amount); + return true; } + @Override + public DamageModifier getDamageModifier() { + return super.getDamageModifier() + .multiply(2, ModDamageTypes.VEHICLE_STRIKE); + } + @Override public InteractionResult interact(Player player, InteractionHand hand) { if (player.getMainHandItem().is(Items.MELON) && !entityData.get(MELON)) { diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/VehicleEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/VehicleEntity.java index 587c6dc0b..2303735e4 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/VehicleEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/VehicleEntity.java @@ -1,6 +1,7 @@ package com.atsuishio.superbwarfare.entity.vehicle; import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModParticleTypes; @@ -154,35 +155,36 @@ public class VehicleEntity extends Entity { @Override public boolean hurt(DamageSource source, float amount) { - if (source.getDirectEntity() instanceof ThrownPotion || source.getDirectEntity() instanceof AreaEffectCloud) - return false; - if (source.is(DamageTypes.FALL)) - return false; - if (source.is(DamageTypes.CACTUS)) - return false; - if (source.is(DamageTypes.DROWN)) - return false; - if (source.is(DamageTypes.DRAGON_BREATH)) - return false; - if (source.is(DamageTypes.WITHER)) - return false; - if (source.is(DamageTypes.WITHER_SKULL)) - return false; - if (source.is(ModDamageTypes.VEHICLE_STRIKE)) { - amount -= 8; - crash = true; - } else { - crash = false; - } if (source.getEntity() != null) { this.entityData.set(LAST_ATTACKER_UUID, source.getEntity().getStringUUID()); } - lastHurtTick = 0; - repairCoolDown = 200; + if (amount > 0) { + lastHurtTick = 0; + repairCoolDown = 200; + } return super.hurt(source, amount); } + protected final DamageModifier damageModifier = this.getDamageModifier(); + + /** + * 控制载具伤害免疫 + * + * @return DamageModifier + */ + public DamageModifier getDamageModifier() { + return new DamageModifier() + .immuneTo(source -> source.getDirectEntity() instanceof ThrownPotion || source.getDirectEntity() instanceof AreaEffectCloud) + .immuneTo(DamageTypes.FALL) + .immuneTo(DamageTypes.CACTUS) + .immuneTo(DamageTypes.DROWN) + .immuneTo(DamageTypes.DRAGON_BREATH) + .immuneTo(DamageTypes.WITHER) + .immuneTo(DamageTypes.WITHER_SKULL) + .reduce(8, ModDamageTypes.VEHICLE_STRIKE); + } + public void heal(float pHealAmount) { if (this.level() instanceof ServerLevel) { this.setHealth(this.getHealth() + pHealAmount); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/WheelChairEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/WheelChairEntity.java index 69c90b634..06b07eadd 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/WheelChairEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/WheelChairEntity.java @@ -104,9 +104,12 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity { @Override public boolean hurt(DamageSource source, float amount) { - super.hurt(source, amount); this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1); + + amount = damageModifier.compute(source, amount); + super.hurt(source, amount); this.hurt(amount, source.getEntity(), true); + return true; } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModifier.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModifier.java new file mode 100644 index 000000000..b9fa3c5b2 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModifier.java @@ -0,0 +1,157 @@ +package com.atsuishio.superbwarfare.entity.vehicle.damage; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.tags.TagKey; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.damagesource.DamageType; +import org.apache.commons.compress.utils.Lists; + +import java.util.List; +import java.util.function.Function; + +public class DamageModifier { + + private final List list = Lists.newArrayList(); + + /** + * 免疫所有伤害 + */ + public DamageModifier immuneTo() { + list.add(new DamageModify(DamageModify.ReduceType.IMMUNITY, 0, (TagKey) null)); + return this; + } + + /** + * 免疫指定类型的伤害 + * + * @param sourceTagKey 伤害类型 + */ + public DamageModifier immuneTo(TagKey sourceTagKey) { + list.add(new DamageModify(DamageModify.ReduceType.IMMUNITY, 0, sourceTagKey)); + return this; + } + + /** + * 免疫指定类型的伤害 + * + * @param sourceKey 伤害类型 + */ + public DamageModifier immuneTo(ResourceKey sourceKey) { + list.add(new DamageModify(DamageModify.ReduceType.IMMUNITY, 0, sourceKey)); + return this; + } + + /** + * 免疫指定类型的伤害 + * + * @param condition 伤害来源判定条件 + */ + public DamageModifier immuneTo(Function condition) { + list.add(new DamageModify(DamageModify.ReduceType.IMMUNITY, 0, condition)); + return this; + } + + /** + * 固定减少所有伤害一定数值 + * + * @param value 要减少的数值 + */ + public DamageModifier reduce(float value) { + list.add(new DamageModify(DamageModify.ReduceType.REDUCE, value, (TagKey) null)); + return this; + } + + /** + * 固定减少指定类型的伤害一定数值 + * + * @param value 要减少的数值 + * @param sourceTagKey 伤害类型 + */ + public DamageModifier reduce(float value, TagKey sourceTagKey) { + list.add(new DamageModify(DamageModify.ReduceType.REDUCE, value, sourceTagKey)); + return this; + } + + /** + * 固定减少指定类型的伤害一定数值 + * + * @param value 要减少的数值 + * @param sourceKey 伤害类型 + */ + public DamageModifier reduce(float value, ResourceKey sourceKey) { + list.add(new DamageModify(DamageModify.ReduceType.REDUCE, value, sourceKey)); + return this; + } + + /** + * 固定减少指定类型的伤害一定数值 + * + * @param value 要减少的数值 + * @param condition 伤害来源判定条件 + */ + public DamageModifier reduce(float value, Function condition) { + list.add(new DamageModify(DamageModify.ReduceType.REDUCE, value, condition)); + return this; + } + + /** + * 将所有类型的伤害乘以指定数值 + * + * @param value 要乘以的数值 + */ + public DamageModifier multiply(float value) { + list.add(new DamageModify(DamageModify.ReduceType.MULTIPLY, value, (TagKey) null)); + return this; + } + + /** + * 将指定类型的伤害乘以指定数值 + * + * @param value 要乘以的数值 + * @param sourceTagKey 伤害类型 + */ + public DamageModifier multiply(float value, TagKey sourceTagKey) { + list.add(new DamageModify(DamageModify.ReduceType.MULTIPLY, value, sourceTagKey)); + return this; + } + + /** + * 将指定类型的伤害乘以指定数值 + * + * @param value 要乘以的数值 + * @param sourceKey 伤害类型 + */ + public DamageModifier multiply(float value, ResourceKey sourceKey) { + list.add(new DamageModify(DamageModify.ReduceType.MULTIPLY, value, sourceKey)); + return this; + } + + /** + * 将指定类型的伤害乘以指定数值 + * + * @param value 要乘以的数值 + * @param condition 伤害来源判定条件 + */ + public DamageModifier multiply(float value, Function condition) { + list.add(new DamageModify(DamageModify.ReduceType.MULTIPLY, value, condition)); + return this; + } + + /** + * 计算减伤后的伤害值 + * + * @param source 伤害来源 + * @param damage 原伤害值 + * @return 减伤后的伤害值 + */ + public float compute(DamageSource source, float damage) { + for (DamageModify damageModify : list) { + if (damageModify.match(source)) { + damage = damageModify.compute(damage); + + if (damage <= 0) return 0; + } + } + return damage; + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModify.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModify.java new file mode 100644 index 000000000..fc0d38f30 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModify.java @@ -0,0 +1,73 @@ +package com.atsuishio.superbwarfare.entity.vehicle.damage; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.tags.TagKey; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.damagesource.DamageType; + +import java.util.function.Function; + +public class DamageModify { + public enum ReduceType { + IMMUNITY, // 完全免疫 + REDUCE, // 固定数值减伤 + MULTIPLY, // 乘以指定倍数 + } + + private final float value; + private final ReduceType type; + + private TagKey sourceTagKey = null; + private ResourceKey sourceKey = null; + private Function condition = null; + + public DamageModify(ReduceType type, float value, TagKey sourceTagKey) { + this.type = type; + this.value = value; + this.sourceTagKey = sourceTagKey; + } + + public DamageModify(ReduceType type, float value, ResourceKey sourceKey) { + this.type = type; + this.value = value; + this.sourceKey = sourceKey; + } + + public DamageModify(ReduceType type, float value, Function condition) { + this.type = type; + this.value = value; + this.condition = condition; + } + + /** + * 判断指定伤害来源是否符合指定条件,若未指定条件则默认符合 + * + * @param source 伤害来源 + * @return 伤害来源是否符合条件 + */ + public boolean match(DamageSource source) { + if (condition != null) { + return condition.apply(source); + } else if (sourceTagKey != null) { + return source.is(sourceTagKey); + } else if (sourceKey != null) { + return source.is(sourceKey); + } else { + return true; + } + } + + /** + * 计算减伤后的伤害值 + * + * @param damage 原伤害值 + * @return 计算后的伤害值 + */ + public float compute(float damage) { + return switch (type) { + case IMMUNITY -> 0; + case REDUCE -> Math.max(damage - value, 0); + case MULTIPLY -> damage * value; + }; + } +}