魔改projectile伤害判定方法

This commit is contained in:
17146 2025-06-30 15:50:53 +08:00 committed by Light_Quanta
parent 24a24e2243
commit c4d15c32c3
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
7 changed files with 63 additions and 133 deletions

View file

@ -21,8 +21,6 @@ import net.minecraft.core.Direction;
import net.minecraft.core.Holder;
import net.minecraft.core.particles.BlockParticleOption;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundSoundPacket;
import net.minecraft.network.syncher.EntityDataAccessor;
@ -39,11 +37,8 @@ import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.entity.monster.Ravager;
import net.minecraft.world.entity.monster.Vex;
import net.minecraft.world.entity.monster.Witch;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.item.ItemStack;
@ -55,7 +50,6 @@ import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.*;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.neoforged.neoforge.common.Tags;
import net.neoforged.neoforge.entity.IEntityWithComplexSpawn;
import net.neoforged.neoforge.entity.PartEntity;
import net.neoforged.neoforge.event.EventHooks;
import net.neoforged.neoforge.network.PacketDistributor;
@ -74,7 +68,7 @@ import java.util.function.Predicate;
import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle;
@SuppressWarnings({"unused", "UnusedReturnValue", "SuspiciousNameCombination"})
public class ProjectileEntity extends Projectile implements IEntityWithComplexSpawn, GeoEntity, CustomSyncMotionEntity {
public class ProjectileEntity extends Projectile implements GeoEntity, CustomSyncMotionEntity {
public static final EntityDataAccessor<Float> COLOR_R = SynchedEntityData.defineId(ProjectileEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> COLOR_G = SynchedEntityData.defineId(ProjectileEntity.class, EntityDataSerializers.FLOAT);
@ -98,15 +92,10 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
protected int shooterId;
private float damage = 1f;
private float headShot = 1f;
private float monsterMultiplier = 0.0f;
private float legShot = 0.5f;
private boolean beast = false;
private boolean zoom = false;
private float bypassArmorRate = 0.0f;
private float undeadMultiple = 1.0f;
private float illagerMultiple = 1.0f;
private int riotLevel = 0;
private int jhpLevel = 0;
private int heLevel = 0;
private int fireLevel = 0;
private boolean dragonBreath = false;
@ -115,6 +104,12 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
private final ArrayList<MobEffectInstance> mobEffects = new ArrayList<>();
private String gunItemId;
public static final Predicate<Entity> MONSTER_PREDICATE = entity -> entity instanceof Monster;
public static final Predicate<Entity> UNDEAD_PREDICATE = entity -> entity.getType().is(EntityTypeTags.UNDEAD);
public static final Predicate<Entity> RAIDERS_PREDICATE = entity -> entity.getType().is(EntityTypeTags.RAIDERS) || entity instanceof Vex;
private final Map<Predicate<Entity>, Float> damageModifiers = new HashMap<>(Map.of(MONSTER_PREDICATE, 1.0f));
public ProjectileEntity(EntityType<? extends ProjectileEntity> entityType, Level level) {
super(entityType, level);
this.noCulling = true;
@ -260,7 +255,7 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
}
if (heLevel > 0) {
explosionBullet(this, this.damage, heLevel, monsterMultiplier + 1, hitPos);
explosionBullet(this, this.damage, heLevel, this.damageModifiers.get(MONSTER_PREDICATE), hitPos);
}
return new EntityResult(entity, hitPos, headshot, legShot);
@ -350,44 +345,6 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
}
}
@Override
protected void readAdditionalSaveData(CompoundTag tag) {
this.damage = tag.getFloat("Damage");
this.headShot = tag.getFloat("HeadShot");
this.monsterMultiplier = tag.getFloat("MonsterMultiplier");
this.legShot = tag.getFloat("LegShot");
this.bypassArmorRate = tag.getFloat("BypassArmorRate");
this.undeadMultiple = tag.getFloat("UndeadMultiple");
this.illagerMultiple = tag.getFloat("IllagerMultiple");
this.knockback = tag.getFloat("Knockback");
this.beast = tag.getBoolean("Beast");
this.forceKnockback = tag.getBoolean("ForceKnockback");
if (tag.contains("GunId")) {
this.gunItemId = tag.getString("GunId");
}
}
@Override
protected void addAdditionalSaveData(CompoundTag tag) {
tag.putFloat("Damage", this.damage);
tag.putFloat("HeadShot", this.headShot);
tag.putFloat("MonsterMultiplier", this.monsterMultiplier);
tag.putFloat("LegShot", this.legShot);
tag.putFloat("BypassArmorRate", this.bypassArmorRate);
tag.putFloat("UndeadMultiple", this.undeadMultiple);
tag.putFloat("IllagerMultiple", this.illagerMultiple);
tag.putFloat("Knockback", this.knockback);
tag.putBoolean("Beast", this.beast);
tag.putBoolean("ForceKnockback", this.forceKnockback);
if (this.gunItemId != null) {
tag.putString("GunId", this.gunItemId);
}
}
@Override
protected void onHit(@Nullable HitResult result) {
if (result instanceof BlockHitResult blockHitResult) {
@ -420,7 +377,7 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
this.onHitBlock(hitVec, blockHitResult);
if (heLevel > 0) {
explosionBullet(this, this.damage, heLevel, monsterMultiplier + 1, hitVec);
explosionBullet(this, this.damage, heLevel, this.damageModifiers.get(MONSTER_PREDICATE), hitVec);
}
if (fireLevel > 0 && this.level() instanceof ServerLevel serverLevel) {
ParticleTool.sendParticle(serverLevel, ParticleTypes.LAVA, hitVec.x, hitVec.y, hitVec.z,
@ -533,8 +490,6 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
protected void onHitEntity(Entity entity, boolean headshot, boolean legShot) {
if (this.shooter == null) return;
float mMultiple = 1 + this.monsterMultiplier;
if (entity == null) return;
if (entity instanceof PartEntity<?> part) {
@ -542,38 +497,17 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
}
if (entity instanceof LivingEntity living) {
living.level().playSound(null, living.getOnPos(), ModSounds.MELEE_HIT.get(), SoundSource.PLAYERS, 1, (float) ((2 * org.joml.Math.random() - 1) * 0.1f + 1.0f));
}
living.level().playSound(null, living.getOnPos(), ModSounds.MELEE_HIT.get(), SoundSource.PLAYERS, 1, (float) (2 * Math.random() - 1) * 0.1f + 1.0f);
if (beast && entity instanceof LivingEntity living) {
if (beast) {
Beast.beastKill(this.shooter, living);
return;
}
if (entity instanceof Monster) {
this.damage *= mMultiple;
}
if (entity instanceof LivingEntity living && living.getType().is(EntityTypeTags.UNDEAD)) {
this.damage *= this.undeadMultiple;
}
if (entity instanceof LivingEntity living && (living.getType().is(EntityTypeTags.ILLAGER) || living instanceof Vex || living instanceof Ravager || living instanceof Witch)) {
this.damage *= this.illagerMultiple;
}
if (entity instanceof LivingEntity living && riotLevel > 0 && !entity.level().isClientSide()) {
living.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 20 + riotLevel * 10, (int) (riotLevel * 0.25), false, false), this.shooter);
living.addEffect(new MobEffectInstance(MobEffects.WEAKNESS, 20 + riotLevel * 10, (int) (riotLevel * 0.25), false, false), this.shooter);
}
if (entity instanceof LivingEntity living && jhpLevel > 0) {
this.damage *= (1.0f + 0.12f * jhpLevel) * ((float) (10 / (living.getAttributeValue(Attributes.ARMOR) + 10)) + 0.25f);
}
if (fireLevel > 0) {
if (!entity.level().isClientSide() && entity instanceof LivingEntity living) {
living.addEffect(new MobEffectInstance(ModMobEffects.BURN, 60 + fireLevel * 20, fireLevel, false, false), this.shooter);
for (var entry : this.damageModifiers.entrySet()) {
if (entry.getKey().test(entity)) {
this.damage *= entry.getValue();
}
}
@ -787,15 +721,6 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
}
}
@Override
public void readSpawnData(@NotNull RegistryFriendlyByteBuf additionalData) {
}
@Override
public void writeSpawnData(@NotNull RegistryFriendlyByteBuf buffer) {
}
public static class EntityResult {
private final Entity entity;
private final Vec3 hitVec;
@ -853,6 +778,10 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
return this.gunItemId;
}
public Map<Predicate<Entity>, Float> getDamageModifiers() {
return damageModifiers;
}
/**
* Builders
*/
@ -871,11 +800,6 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
return this;
}
public ProjectileEntity setMonsterMultiplier(float monsterMultiplier) {
this.monsterMultiplier = monsterMultiplier;
return this;
}
public ProjectileEntity legShot(float legShot) {
this.legShot = legShot;
return this;
@ -886,16 +810,6 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
return this;
}
public ProjectileEntity riotBullet(int riotLevel) {
this.riotLevel = riotLevel;
return this;
}
public ProjectileEntity jhpBullet(int jhpLevel) {
this.jhpLevel = jhpLevel;
return this;
}
public ProjectileEntity heBullet(int heLevel) {
this.heLevel = heLevel;
return this;
@ -917,16 +831,6 @@ public class ProjectileEntity extends Projectile implements IEntityWithComplexSp
return this;
}
public ProjectileEntity undeadMultiple(float undeadMultiple) {
this.undeadMultiple = undeadMultiple;
return this;
}
public ProjectileEntity illagerMultiple(float illagerMultiple) {
this.illagerMultiple = illagerMultiple;
return this;
}
public ProjectileEntity effect(ArrayList<MobEffectInstance> mobEffectInstances) {
this.mobEffects.addAll(mobEffectInstances);
return this;

View file

@ -47,9 +47,10 @@ public class AmmoPerk extends Perk {
}
if (!this.mobEffects.get().isEmpty()) {
int amplifier = this.getEffectAmplifier(instance);
int duration = this.getEffectDuration(instance);
ArrayList<MobEffectInstance> mobEffectInstances = new ArrayList<>();
for (MobEffect effect : this.mobEffects.get()) {
mobEffectInstances.add(new MobEffectInstance(Holder.direct(effect), 70 + 30 * level, amplifier));
mobEffectInstances.add(new MobEffectInstance(Holder.direct(effect), duration, amplifier));
}
projectile.effect(mobEffectInstances);
}
@ -59,6 +60,10 @@ public class AmmoPerk extends Perk {
return instance.level() - 1;
}
public int getEffectDuration(PerkInstance instance) {
return 70 + 30 * instance.level();
}
public double getModifiedVelocity(GunData data, PerkInstance instance) {
return data.velocity() * this.speedRate;
}

View file

@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.perk.ammo;
import com.atsuishio.superbwarfare.data.gun.GunData;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.init.ModMobEffects;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
@ -11,7 +12,13 @@ import net.minecraft.world.entity.Entity;
public class IncendiaryBullet extends AmmoPerk {
public IncendiaryBullet() {
super(new AmmoPerk.Builder("incendiary_bullet", Perk.Type.AMMO).bypassArmorRate(-0.4f).damageRate(0.7f).speedRate(0.75f).slug(false).rgb(230, 131, 65));
super(new AmmoPerk.Builder("incendiary_bullet", Perk.Type.AMMO).bypassArmorRate(-0.4f).damageRate(0.7f).speedRate(0.75f).slug(false).rgb(230, 131, 65)
.mobEffect(ModMobEffects.BURN));
}
@Override
public int getEffectDuration(PerkInstance instance) {
return 60 + 20 * instance.level();
}
@Override

View file

@ -1,11 +1,13 @@
package com.atsuishio.superbwarfare.perk.ammo;
import com.atsuishio.superbwarfare.data.gun.GunData;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.PerkInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.Attributes;
import org.jetbrains.annotations.Nullable;
public class JHPBullet extends AmmoPerk {
@ -14,9 +16,10 @@ public class JHPBullet extends AmmoPerk {
}
@Override
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
super.modifyProjectile(data, instance, entity);
if (!(entity instanceof ProjectileEntity projectile)) return;
projectile.jhpBullet(instance.level());
public float getModifiedDamage(float damage, GunData data, PerkInstance instance, @Nullable LivingEntity target, DamageSource source) {
if (target != null) {
return damage * (1.0f + 0.12f * instance.level()) * ((float) (10 / (target.getAttributeValue(Attributes.ARMOR) + 10)) + 0.25f);
}
return super.getModifiedDamage(damage, data, instance, null, source);
}
}

View file

@ -4,19 +4,30 @@ import com.atsuishio.superbwarfare.data.gun.GunData;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.PerkInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
public class RiotBullet extends AmmoPerk {
public RiotBullet() {
super(new Builder("riot_bullet", Type.AMMO).bypassArmorRate(-0.3f).damageRate(0.9f).speedRate(0.8f).slug(true).rgb(70, 35, 230));
super(new Builder("riot_bullet", Type.AMMO).bypassArmorRate(-0.3f).damageRate(0.9f).speedRate(0.8f).slug(true).rgb(70, 35, 230)
.mobEffect(MobEffects.MOVEMENT_SLOWDOWN::value).mobEffect(MobEffects.WEAKNESS::value));
}
@Override
public int getEffectAmplifier(PerkInstance instance) {
return (int) (instance.level() * 0.25);
}
@Override
public int getEffectDuration(PerkInstance instance) {
return 20 + instance.level() * 10;
}
@Override
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
super.modifyProjectile(data, instance, entity);
if (!(entity instanceof ProjectileEntity projectile)) return;
projectile.riotBullet(instance.level());
projectile.illagerMultiple(1.0f + 0.5f * instance.level());
projectile.getDamageModifiers().put(ProjectileEntity.RAIDERS_PREDICATE, 1.0f + 0.5f * instance.level());
}
}

View file

@ -1,7 +1,7 @@
package com.atsuishio.superbwarfare.perk.ammo;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.data.gun.GunData;
import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.PerkInstance;
@ -17,6 +17,6 @@ public class SilverBullet extends AmmoPerk {
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
super.modifyProjectile(data, instance, entity);
if (!(entity instanceof ProjectileEntity projectile)) return;
projectile.undeadMultiple(1.0f + 0.5f * instance.level());
projectile.getDamageModifiers().put(ProjectileEntity.UNDEAD_PREDICATE, 1.0f + 0.5f * instance.level());
}
}

View file

@ -17,9 +17,9 @@ public class MonsterHunter extends Perk {
@Override
public void modifyProjectile(GunData data, PerkInstance instance, Entity entity) {
float multiplier = 0.1f + 0.1f * instance.level();
float multiplier = 1.1f + 0.1f * instance.level();
if (entity instanceof ProjectileEntity projectile) {
projectile.setMonsterMultiplier(multiplier);
projectile.getDamageModifiers().put(ProjectileEntity.MONSTER_PREDICATE, multiplier);
} else if (entity instanceof JavelinMissileEntity projectile) {
projectile.setMonsterMultiplier(multiplier);
} else if (entity instanceof GunGrenadeEntity projectile) {