火炮适配射击诸元

This commit is contained in:
Atsuihsio 2025-02-23 17:49:38 +08:00
parent b78069fd31
commit c0f931f4bc
4 changed files with 245 additions and 55 deletions

View file

@ -22,6 +22,8 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -30,11 +32,13 @@ import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.MoverType;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.ProjectileUtil; import net.minecraft.world.entity.projectile.ProjectileUtil;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.phys.*; import net.minecraft.world.phys.*;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.network.NetworkHooks; import net.minecraftforge.network.NetworkHooks;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.PlayMessages; import net.minecraftforge.network.PlayMessages;
@ -60,6 +64,9 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity,
public static final EntityDataAccessor<Float> LASER_LEFT_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT); public static final EntityDataAccessor<Float> LASER_LEFT_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> LASER_MIDDLE_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT); public static final EntityDataAccessor<Float> LASER_MIDDLE_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> LASER_RIGHT_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT); public static final EntityDataAccessor<Float> LASER_RIGHT_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> PITCH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> YAW = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<String> SHOOTER_UUID = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.STRING);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public static final float MAX_HEALTH = VehicleConfig.ANNIHILATOR_HP.get(); public static final float MAX_HEALTH = VehicleConfig.ANNIHILATOR_HP.get();
@ -80,21 +87,78 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity,
protected void defineSynchedData() { protected void defineSynchedData() {
super.defineSynchedData(); super.defineSynchedData();
this.entityData.define(COOL_DOWN, 0); this.entityData.define(COOL_DOWN, 0);
this.entityData.define(SHOOTER_UUID, "none");
this.entityData.define(LASER_LEFT_LENGTH, 0f); this.entityData.define(LASER_LEFT_LENGTH, 0f);
this.entityData.define(LASER_MIDDLE_LENGTH, 0f); this.entityData.define(LASER_MIDDLE_LENGTH, 0f);
this.entityData.define(LASER_RIGHT_LENGTH, 0f); this.entityData.define(LASER_RIGHT_LENGTH, 0f);
this.entityData.define(PITCH, 0f);
this.entityData.define(YAW, 0f);
} }
@Override @Override
public void addAdditionalSaveData(CompoundTag compound) { public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound); super.addAdditionalSaveData(compound);
compound.putInt("CoolDown", this.entityData.get(COOL_DOWN)); compound.putInt("CoolDown", this.entityData.get(COOL_DOWN));
compound.putFloat("Pitch", this.entityData.get(PITCH));
compound.putFloat("Yaw", this.entityData.get(YAW));
} }
@Override @Override
public void readAdditionalSaveData(CompoundTag compound) { public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound); super.readAdditionalSaveData(compound);
this.entityData.set(COOL_DOWN, compound.getInt("CoolDown")); this.entityData.set(COOL_DOWN, compound.getInt("CoolDown"));
this.entityData.set(PITCH, compound.getFloat("Pitch"));
this.entityData.set(YAW, compound.getFloat("Yaw"));
}
@Override
public InteractionResult interact(Player player, InteractionHand hand) {
ItemStack stack = player.getMainHandItem();
if (player.getMainHandItem().getItem() == ModItems.FIRING_PARAMETERS.get() && player.isCrouching()) {
setTarget(player.getOffhandItem());
return InteractionResult.SUCCESS;
}
if (player.getOffhandItem().getItem() == ModItems.FIRING_PARAMETERS.get() && player.isCrouching()) {
setTarget(player.getOffhandItem());
return InteractionResult.SUCCESS;
}
if (stack.is(ModItems.CROWBAR.get()) && !player.isCrouching()) {
if (this.entityData.get(COOL_DOWN) == 0) {
vehicleShoot(player);
entityData.set(SHOOTER_UUID, player.getStringUUID());
}
return InteractionResult.SUCCESS;
}
return super.interact(player, hand);
}
public void setTarget(ItemStack stack) {
int targetX = stack.getOrCreateTag().getInt("TargetX");
int targetY = stack.getOrCreateTag().getInt("TargetY");
int targetZ = stack.getOrCreateTag().getInt("TargetZ");
this.look(new Vec3(targetX, targetY, targetZ));
}
private void look(Vec3 pTarget) {
float yRot = this.getYRot();
if (yRot < 0) {
yRot += 360;
}
yRot = yRot + 90 % 360;
var BarrelRoot = new Vector3d(4.95, 2.25, 0);
BarrelRoot.rotateY(-yRot * Mth.DEG_TO_RAD);
Vec3 vec3 = new Vec3(this.getX() + BarrelRoot.x, this.getY() + BarrelRoot.y, this.getZ() + BarrelRoot.z);
double d0 = pTarget.x - vec3.x;
double d1 = pTarget.y - vec3.y;
double d2 = pTarget.z - vec3.z;
double d3 = java.lang.Math.sqrt(d0 * d0 + d2 * d2);
entityData.set(YAW, Mth.wrapDegrees((float) (Mth.atan2(d2, d0) * 57.2957763671875) - 90.0F));
entityData.set(PITCH, Mth.wrapDegrees((float) (-(Mth.atan2(d1, d3) * 57.2957763671875))));
} }
@Override @Override
@ -224,11 +288,8 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity,
// } else { // } else {
// travel(); // travel();
// } // }
if (this.entityData.get(COOL_DOWN) == 20) {
Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0); this.level().playSound(null, this.getOnPos(), ModSounds.ANNIHILATOR_RELOAD.get(), SoundSource.PLAYERS, 1, 1);
if (passenger instanceof ServerPlayer serverPlayer && this.entityData.get(COOL_DOWN) == 20) {
SoundTool.playLocalSound(serverPlayer, ModSounds.ANNIHILATOR_RELOAD.get(), 1, 1);
} }
} }
@ -275,8 +336,13 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity,
if (this.entityData.get(COOL_DOWN) > 98) { if (this.entityData.get(COOL_DOWN) > 98) {
laserExplosion(hitPos); laserExplosion(hitPos);
} }
this.level().explode(this, hitPos.x, hitPos.y, hitPos.z, 5, ExplosionConfig.EXPLOSION_DESTROY.get() ? Level.ExplosionInteraction.BLOCK : Level.ExplosionInteraction.NONE);
if (this.getFirstPassenger() != null) {
this.level().explode(this.getFirstPassenger(), hitPos.x, hitPos.y, hitPos.z, 5, ExplosionConfig.EXPLOSION_DESTROY.get() ? Level.ExplosionInteraction.BLOCK : Level.ExplosionInteraction.NONE);
} else {
Entity shooter = EntityFindUtil.findEntity(this.level(), this.entityData.get(SHOOTER_UUID));
this.level().explode(shooter, hitPos.x, hitPos.y, hitPos.z, 5, ExplosionConfig.EXPLOSION_DESTROY.get() ? Level.ExplosionInteraction.BLOCK : Level.ExplosionInteraction.NONE);
}
} }
return (float) pos.distanceTo((Vec3.atLowerCornerOf(cannon.level().clip( return (float) pos.distanceTo((Vec3.atLowerCornerOf(cannon.level().clip(
@ -311,7 +377,15 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity,
if (hitResult.getType() == HitResult.Type.ENTITY) { if (hitResult.getType() == HitResult.Type.ENTITY) {
Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0); Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
Entity target = ((EntityHitResult) hitResult).getEntity(); Entity target = ((EntityHitResult) hitResult).getEntity();
target.hurt(ModDamageTypes.causeLaserDamage(this.level().registryAccess(), passenger, passenger), (float) 200);
if (passenger != null) {
target.hurt(ModDamageTypes.causeLaserDamage(this.level().registryAccess(), this, passenger), (float) 200);
} else {
Entity shooter = EntityFindUtil.findEntity(this.level(), this.entityData.get(SHOOTER_UUID));
target.hurt(ModDamageTypes.causeLaserDamage(this.level().registryAccess(), this, shooter), (float) 200);
}
target.invulnerableTime = 0; target.invulnerableTime = 0;
if (this.entityData.get(COOL_DOWN) > 98) { if (this.entityData.get(COOL_DOWN) > 98) {
laserExplosion(targetPos); laserExplosion(targetPos);
@ -326,13 +400,24 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity,
private void laserExplosion(Vec3 pos) { private void laserExplosion(Vec3 pos) {
Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0); Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
CustomExplosion explosion = new CustomExplosion(this.level(), passenger, if (passenger != null) {
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), passenger, passenger), 300f, CustomExplosion explosion = new CustomExplosion(this.level(), passenger,
pos.x, pos.y, pos.z, 15f, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1); ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, passenger), 300f,
explosion.explode(); pos.x, pos.y, pos.z, 15f, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1);
net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion); explosion.explode();
explosion.finalizeExplosion(false); ForgeEventFactory.onExplosionStart(this.level(), explosion);
ParticleTool.spawnHugeExplosionParticles(this.level(), pos); explosion.finalizeExplosion(false);
ParticleTool.spawnHugeExplosionParticles(this.level(), pos);
} else {
Entity shooter = EntityFindUtil.findEntity(this.level(), this.entityData.get(SHOOTER_UUID));
CustomExplosion explosion = new CustomExplosion(this.level(), shooter,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, shooter), 300f,
pos.x, pos.y, pos.z, 15f, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1);
explosion.explode();
ForgeEventFactory.onExplosionStart(this.level(), explosion);
explosion.finalizeExplosion(false);
ParticleTool.spawnHugeExplosionParticles(this.level(), pos);
}
} }
@Override @Override
@ -344,7 +429,7 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), attacker, attacker), 600f, ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), attacker, attacker), 600f,
this.getX(), this.getY(), this.getZ(), 15f, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1); this.getX(), this.getY(), this.getZ(), 15f, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1);
explosion.explode(); explosion.explode();
net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion); ForgeEventFactory.onExplosionStart(this.level(), explosion);
explosion.finalizeExplosion(false); explosion.finalizeExplosion(false);
ParticleTool.spawnHugeExplosionParticles(this.level(), this.position()); ParticleTool.spawnHugeExplosionParticles(this.level(), this.position());
} }
@ -404,39 +489,42 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity,
@Override @Override
public void travel() { public void travel() {
Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0); Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
if (!(passenger instanceof LivingEntity entity)) return;
if (this.getEnergy() <= 0) return; if (this.getEnergy() <= 0) return;
float yRot = this.getYRot(); if (passenger instanceof LivingEntity entity) {
if (yRot < 0) { float yRot = this.getYRot();
yRot += 360; if (yRot < 0) {
} yRot += 360;
yRot = yRot + 90 % 360; }
yRot = yRot + 90 % 360;
var BarrelRoot = new Vector3d(4.95, 2.25, 0); var BarrelRoot = new Vector3d(4.95, 2.25, 0);
BarrelRoot.rotateY(-yRot * Mth.DEG_TO_RAD); BarrelRoot.rotateY(-yRot * Mth.DEG_TO_RAD);
Vec3 barrelRootPos = new Vec3(this.getX() + BarrelRoot.x, this.getY() + BarrelRoot.y, this.getZ() + BarrelRoot.z); Vec3 barrelRootPos = new Vec3(this.getX() + BarrelRoot.x, this.getY() + BarrelRoot.y, this.getZ() + BarrelRoot.z);
Vec3 passengersEyePos = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ()); Vec3 passengersEyePos = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ());
Entity lookingAt = TraceTool.findLookingEntity(entity, 512); Entity lookingAt = TraceTool.findLookingEntity(entity, 512);
if (lookingAt == null) { if (lookingAt == null) {
HitResult result = entity.level().clip(new ClipContext(passengersEyePos, passengersEyePos.add(entity.getViewVector(1).scale(512)), HitResult result = entity.level().clip(new ClipContext(passengersEyePos, passengersEyePos.add(entity.getViewVector(1).scale(512)),
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, entity)); ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, entity));
Vec3 blockHitPos = result.getLocation(); Vec3 blockHitPos = result.getLocation();
barrelLookAt = new Vec3(blockHitPos.x - barrelRootPos.x, blockHitPos.y - barrelRootPos.y, blockHitPos.z - barrelRootPos.z); barrelLookAt = new Vec3(blockHitPos.x - barrelRootPos.x, blockHitPos.y - barrelRootPos.y, blockHitPos.z - barrelRootPos.z);
} else { } else {
barrelLookAt = new Vec3(lookingAt.getX() - barrelRootPos.x, lookingAt.getEyeY() - barrelRootPos.y, lookingAt.getZ() - barrelRootPos.z); barrelLookAt = new Vec3(lookingAt.getX() - barrelRootPos.x, lookingAt.getEyeY() - barrelRootPos.y, lookingAt.getZ() - barrelRootPos.z);
}
float offset = (float) VectorTool.calculateAngle(entity.getViewVector(1), barrelLookAt);
entityData.set(YAW, passenger.getYHeadRot());
entityData.set(PITCH, passenger.getXRot() - offset);
} }
float offset = (float) VectorTool.calculateAngle(entity.getViewVector(1), barrelLookAt); float diffY = Mth.wrapDegrees(entityData.get(YAW) - this.getYRot());
float diffX = Mth.wrapDegrees(entityData.get(PITCH) - this.getXRot());
float diffY = Math.clamp(-90f, 90f, Mth.wrapDegrees(entity.getYHeadRot() - this.getYRot()));
float diffX = entity.getXRot() - offset - this.getXRot();
diffX = diffX * 0.15f;
this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY, -0.6f, 0.6f)); this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY, -0.6f, 0.6f));
this.setXRot(Mth.clamp(this.getXRot() + Mth.clamp(diffX, -2f, 2f), -45, 5f)); this.setXRot(Mth.clamp(this.getXRot() + Mth.clamp(diffX, -2f, 2f), -45, 5f));

View file

@ -24,6 +24,8 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.*; import net.minecraft.world.entity.*;
@ -79,12 +81,56 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, ICannonEntit
public void addAdditionalSaveData(CompoundTag compound) { public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound); super.addAdditionalSaveData(compound);
compound.putInt("CoolDown", this.entityData.get(COOL_DOWN)); compound.putInt("CoolDown", this.entityData.get(COOL_DOWN));
compound.putFloat("Pitch", this.entityData.get(PITCH));
compound.putFloat("Yaw", this.entityData.get(YAW));
} }
@Override @Override
protected void readAdditionalSaveData(CompoundTag compound) { protected void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound); super.readAdditionalSaveData(compound);
this.entityData.set(COOL_DOWN, compound.getInt("CoolDown")); this.entityData.set(COOL_DOWN, compound.getInt("CoolDown"));
this.entityData.set(PITCH, compound.getFloat("Pitch"));
this.entityData.set(YAW, compound.getFloat("Yaw"));
}
@Override
public InteractionResult interact(Player player, InteractionHand hand) {
ItemStack stack = player.getMainHandItem();
if (player.getMainHandItem().getItem() == ModItems.FIRING_PARAMETERS.get() && player.isCrouching()) {
setTarget(player.getOffhandItem());
return InteractionResult.SUCCESS;
}
if (player.getOffhandItem().getItem() == ModItems.FIRING_PARAMETERS.get() && player.isCrouching()) {
setTarget(player.getOffhandItem());
return InteractionResult.SUCCESS;
}
if (stack.getItem() instanceof CannonShellItem) {
if (this.entityData.get(COOL_DOWN) == 0) {
vehicleShoot(player);
}
return InteractionResult.SUCCESS;
}
return super.interact(player, hand);
}
public void setTarget(ItemStack stack) {
int targetX = stack.getOrCreateTag().getInt("TargetX");
int targetY = stack.getOrCreateTag().getInt("TargetY");
int targetZ = stack.getOrCreateTag().getInt("TargetZ");
this.look(new Vec3(targetX, targetY, targetZ));
}
private void look(Vec3 pTarget) {
Vec3 vec3 = this.getEyePosition();
double d0 = pTarget.x - vec3.x;
double d1 = pTarget.y - vec3.y;
double d2 = pTarget.z - vec3.z;
double d3 = java.lang.Math.sqrt(d0 * d0 + d2 * d2);
double distance = pTarget.distanceTo(vec3);
entityData.set(YAW, Mth.wrapDegrees((float) (Mth.atan2(d2, d0) * 57.2957763671875) - 90.0F));
entityData.set(PITCH, Mth.wrapDegrees((float) (-(Mth.atan2(d1, d3) * 57.2957763671875))) - (float) (distance * 0.008f));
} }
@Override @Override
@ -314,19 +360,20 @@ public class Mk42Entity extends VehicleEntity implements GeoEntity, ICannonEntit
} }
} }
@Override @Override
public void travel() { public void travel() {
Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0); Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
float diffY = 0; if (passenger != null) {
float diffX = 0; entityData.set(YAW, passenger.getYHeadRot());
entityData.set(PITCH, passenger.getXRot() - 1.3f);
if (passenger instanceof Player player) {
diffY = Math.clamp(-90f, 90f, Mth.wrapDegrees(passenger.getYHeadRot() - this.getYRot()));
diffX = passenger.getXRot() - 1.3f - this.getXRot();
diffX = diffX * 0.15f;
this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY, -1.75f, 1.75f));
this.setXRot(Mth.clamp(this.getXRot() + Mth.clamp(diffX, -3f, 3f), -85, 16.3f));
} }
float diffY = Mth.wrapDegrees(entityData.get(YAW) - this.getYRot());
float diffX = Mth.wrapDegrees(entityData.get(PITCH) - this.getXRot());
this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY, -1.75f, 1.75f));
this.setXRot(Mth.clamp(this.getXRot() + Mth.clamp(0.5f * diffX, -3f, 3f), -85, 16.3f));
} }
protected void clampRotation(Entity entity) { protected void clampRotation(Entity entity) {

View file

@ -24,6 +24,8 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.*; import net.minecraft.world.entity.*;
@ -56,6 +58,8 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, ICannonEn
public static final EntityDataAccessor<Integer> COOL_DOWN = SynchedEntityData.defineId(Mle1934Entity.class, EntityDataSerializers.INT); public static final EntityDataAccessor<Integer> COOL_DOWN = SynchedEntityData.defineId(Mle1934Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> TYPE = SynchedEntityData.defineId(Mle1934Entity.class, EntityDataSerializers.INT); public static final EntityDataAccessor<Integer> TYPE = SynchedEntityData.defineId(Mle1934Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Float> PITCH = SynchedEntityData.defineId(Mle1934Entity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> YAW = SynchedEntityData.defineId(Mle1934Entity.class, EntityDataSerializers.FLOAT);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public static final float MAX_HEALTH = VehicleConfig.MLE1934_HP.get(); public static final float MAX_HEALTH = VehicleConfig.MLE1934_HP.get();
@ -72,6 +76,8 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, ICannonEn
super.defineSynchedData(); super.defineSynchedData();
this.entityData.define(COOL_DOWN, 0); this.entityData.define(COOL_DOWN, 0);
this.entityData.define(TYPE, 0); this.entityData.define(TYPE, 0);
this.entityData.define(PITCH, 0f);
this.entityData.define(YAW, 0f);
} }
@Override @Override
@ -79,6 +85,8 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, ICannonEn
super.addAdditionalSaveData(compound); super.addAdditionalSaveData(compound);
compound.putInt("CoolDown", this.entityData.get(COOL_DOWN)); compound.putInt("CoolDown", this.entityData.get(COOL_DOWN));
compound.putInt("Type", this.entityData.get(TYPE)); compound.putInt("Type", this.entityData.get(TYPE));
compound.putFloat("Pitch", this.entityData.get(PITCH));
compound.putFloat("Yaw", this.entityData.get(YAW));
} }
@Override @Override
@ -86,6 +94,48 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, ICannonEn
super.readAdditionalSaveData(compound); super.readAdditionalSaveData(compound);
this.entityData.set(COOL_DOWN, compound.getInt("CoolDown")); this.entityData.set(COOL_DOWN, compound.getInt("CoolDown"));
this.entityData.set(TYPE, compound.getInt("Type")); this.entityData.set(TYPE, compound.getInt("Type"));
this.entityData.set(PITCH, compound.getFloat("Pitch"));
this.entityData.set(YAW, compound.getFloat("Yaw"));
}
@Override
public InteractionResult interact(Player player, InteractionHand hand) {
ItemStack stack = player.getMainHandItem();
if (player.getMainHandItem().getItem() == ModItems.FIRING_PARAMETERS.get() && player.isCrouching()) {
setTarget(player.getOffhandItem());
return InteractionResult.SUCCESS;
}
if (player.getOffhandItem().getItem() == ModItems.FIRING_PARAMETERS.get() && player.isCrouching()) {
setTarget(player.getOffhandItem());
return InteractionResult.SUCCESS;
}
if (stack.getItem() instanceof CannonShellItem) {
if (this.entityData.get(COOL_DOWN) == 0) {
vehicleShoot(player);
}
return InteractionResult.SUCCESS;
}
return super.interact(player, hand);
}
public void setTarget(ItemStack stack) {
int targetX = stack.getOrCreateTag().getInt("TargetX");
int targetY = stack.getOrCreateTag().getInt("TargetY");
int targetZ = stack.getOrCreateTag().getInt("TargetZ");
this.look(new Vec3(targetX, targetY, targetZ));
}
private void look(Vec3 pTarget) {
Vec3 vec3 = this.getEyePosition();
double d0 = pTarget.x - vec3.x;
double d1 = pTarget.y - vec3.y;
double d2 = pTarget.z - vec3.z;
double d3 = java.lang.Math.sqrt(d0 * d0 + d2 * d2);
double distance = pTarget.distanceTo(vec3);
entityData.set(YAW, Mth.wrapDegrees((float) (Mth.atan2(d2, d0) * 57.2957763671875) - 90.0F));
entityData.set(PITCH, Mth.wrapDegrees((float) (-(Mth.atan2(d1, d3) * 57.2957763671875))) - (float) (distance * 0.008f));
} }
@Override @Override
@ -404,15 +454,16 @@ public class Mle1934Entity extends VehicleEntity implements GeoEntity, ICannonEn
@Override @Override
public void travel() { public void travel() {
Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0); Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
if (!(passenger instanceof LivingEntity entity)) return; if (passenger != null) {
entityData.set(YAW, passenger.getYHeadRot());
entityData.set(PITCH, passenger.getXRot() - 1.2f);
}
float diffY = Math.clamp(-90f, 90f, Mth.wrapDegrees(entity.getYHeadRot() - this.getYRot())); float diffY = Mth.wrapDegrees(entityData.get(YAW) - this.getYRot());
float diffX = entity.getXRot() - 1.2f - this.getXRot(); float diffX = Mth.wrapDegrees(entityData.get(PITCH) - this.getXRot());
diffX = diffX * 0.15f;
this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY, -1.25f, 1.25f)); this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY, -1.25f, 1.25f));
this.setXRot(Mth.clamp(this.getXRot() + Mth.clamp(diffX, -2f, 2f), -30, 4)); this.setXRot(Mth.clamp(this.getXRot() + Mth.clamp(0.5f * diffX, -2f, 2f), -30, 4f));
} }
protected void clampRotation(Entity entity) { protected void clampRotation(Entity entity) {

View file

@ -202,11 +202,15 @@ public class MobileVehicleEntity extends EnergyVehicleEntity {
double f = Math.min(entitySize / thisSize, 2); double f = Math.min(entitySize / thisSize, 2);
double f1 = Math.min(thisSize / entitySize, 2); double f1 = Math.min(thisSize / entitySize, 2);
this.push(-f * velAdd.x, -f * velAdd.y, -f * velAdd.z); this.pushNew(-f * velAdd.x, -f * velAdd.y, -f * velAdd.z);
entity.push(f1 * velAdd.x, f1 * velAdd.y, f1 * velAdd.z); entity.push(f1 * velAdd.x, f1 * velAdd.y, f1 * velAdd.z);
} }
} }
public void pushNew(double pX, double pY, double pZ) {
this.setDeltaMovement(this.getDeltaMovement().add(pX, pY, pZ));
}
/** /**
* 撞击实体并造成伤害 * 撞击实体并造成伤害
* *
@ -246,7 +250,7 @@ public class MobileVehicleEntity extends EnergyVehicleEntity {
this.level().playSound(null, this, ModSounds.VEHICLE_STRIKE.get(), this.getSoundSource(), 1, 1); this.level().playSound(null, this, ModSounds.VEHICLE_STRIKE.get(), this.getSoundSource(), 1, 1);
} }
if (!(entity instanceof TargetEntity)) { if (!(entity instanceof TargetEntity)) {
this.push(-f * velAdd.x, -f * velAdd.y, -f * velAdd.z); this.pushNew(-f * velAdd.x, -f * velAdd.y, -f * velAdd.z);
} }
entity.push(f1 * velAdd.x, f1 * velAdd.y, f1 * velAdd.z); entity.push(f1 * velAdd.x, f1 * velAdd.y, f1 * velAdd.z);
entity.hurt(ModDamageTypes.causeVehicleStrikeDamage(this.level().registryAccess(), this, this.getFirstPassenger() == null ? this : this.getFirstPassenger()), (float) (thisSize * 20 * ((velocity.length() - 0.3) * (velocity.length() - 0.3)))); entity.hurt(ModDamageTypes.causeVehicleStrikeDamage(this.level().registryAccess(), this, this.getFirstPassenger() == null ? this : this.getFirstPassenger()), (float) (thisSize * 20 * ((velocity.length() - 0.3) * (velocity.length() - 0.3))));