244 lines
8.7 KiB
Java
244 lines
8.7 KiB
Java
package com.atsuishio.superbwarfare.entity;
|
|
|
|
import com.atsuishio.superbwarfare.init.ModItems;
|
|
import com.atsuishio.superbwarfare.item.ContainerBlockItem;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.network.syncher.EntityDataAccessor;
|
|
import net.minecraft.network.syncher.EntityDataSerializers;
|
|
import net.minecraft.network.syncher.SynchedEntityData;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
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.DamageTypes;
|
|
import net.minecraft.world.entity.AreaEffectCloud;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.entity.EntityType;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.entity.projectile.ThrownPotion;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.Items;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import org.joml.Math;
|
|
|
|
|
|
public class VehicleEntity extends Entity {
|
|
public static final EntityDataAccessor<Float> HEALTH = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.FLOAT);
|
|
protected static final EntityDataAccessor<String> LAST_ATTACKER_UUID = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.STRING);
|
|
protected int interpolationSteps;
|
|
protected double x;
|
|
protected double y;
|
|
protected double z;
|
|
protected double serverYRot;
|
|
protected double serverXRot;
|
|
|
|
public VehicleEntity(EntityType<?> pEntityType, Level pLevel) {
|
|
super(pEntityType, pLevel);
|
|
this.setHealth(this.getMaxHealth());
|
|
}
|
|
|
|
@Override
|
|
protected void defineSynchedData() {
|
|
this.entityData.define(HEALTH, this.getMaxHealth());
|
|
this.entityData.define(LAST_ATTACKER_UUID, "undefined");
|
|
}
|
|
|
|
@Override
|
|
protected void readAdditionalSaveData(CompoundTag compound) {
|
|
this.entityData.set(LAST_ATTACKER_UUID, compound.getString("LastAttacker"));
|
|
this.entityData.set(HEALTH, compound.getFloat("Health"));
|
|
|
|
}
|
|
|
|
@Override
|
|
public void addAdditionalSaveData(CompoundTag compound) {
|
|
compound.putFloat("Health", this.entityData.get(HEALTH));
|
|
compound.putString("LastAttacker", this.entityData.get(LAST_ATTACKER_UUID));
|
|
}
|
|
|
|
@Override
|
|
public InteractionResult interact(Player player, InteractionHand hand) {
|
|
if (player.getVehicle() == this) return InteractionResult.PASS;
|
|
if (player.isShiftKeyDown() && player.getMainHandItem().is(ModItems.CROWBAR.get())) {
|
|
ItemStack stack = ContainerBlockItem.createInstance(this);
|
|
if (!player.addItem(stack)) {
|
|
player.drop(stack, false);
|
|
}
|
|
this.remove(RemovalReason.DISCARDED);
|
|
this.discard();
|
|
} else if (player.getMainHandItem().is(Items.IRON_INGOT)) {
|
|
if (this.getHealth() < this.getMaxHealth()) {
|
|
this.heal(Math.min(50, this.getMaxHealth()));
|
|
player.getMainHandItem().shrink(1);
|
|
if (!this.level().isClientSide) {
|
|
this.level().playSound(null, this, SoundEvents.IRON_GOLEM_REPAIR, this.getSoundSource(), 0.5f, 1);
|
|
}
|
|
} else if (!this.level().isClientSide) {
|
|
if (this.getFirstPassenger() == null) {
|
|
player.setXRot(this.getXRot());
|
|
player.setYRot(this.getYRot());
|
|
return player.startRiding(this) ? InteractionResult.CONSUME : InteractionResult.PASS;
|
|
} else if (!(this.getFirstPassenger() instanceof Player)) {
|
|
this.getFirstPassenger().stopRiding();
|
|
player.setXRot(this.getXRot());
|
|
player.setYRot(this.getYRot());
|
|
return player.startRiding(this) ? InteractionResult.CONSUME : InteractionResult.PASS;
|
|
}
|
|
}
|
|
} else if (!this.level().isClientSide) {
|
|
if (this.getFirstPassenger() == null) {
|
|
player.setXRot(this.getXRot());
|
|
player.setYRot(this.getYRot());
|
|
return player.startRiding(this) ? InteractionResult.CONSUME : InteractionResult.PASS;
|
|
} else if (!(this.getFirstPassenger() instanceof Player)) {
|
|
this.getFirstPassenger().stopRiding();
|
|
player.setXRot(this.getXRot());
|
|
player.setYRot(this.getYRot());
|
|
return player.startRiding(this) ? InteractionResult.CONSUME : InteractionResult.PASS;
|
|
}
|
|
}
|
|
return InteractionResult.PASS;
|
|
}
|
|
|
|
@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.LIGHTNING_BOLT))
|
|
return false;
|
|
if (source.is(DamageTypes.FALLING_ANVIL))
|
|
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(DamageTypes.ON_FIRE))
|
|
return false;
|
|
if (source.is(DamageTypes.IN_FIRE))
|
|
return false;
|
|
if (source.getEntity() != null) {
|
|
this.entityData.set(LAST_ATTACKER_UUID, source.getEntity().getStringUUID());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public void heal(float pHealAmount) {
|
|
this.setHealth(this.getHealth() + pHealAmount);
|
|
}
|
|
|
|
public void hurt(float pHealAmount) {
|
|
this.setHealth(this.getHealth() - pHealAmount);
|
|
}
|
|
|
|
public float getHealth() {
|
|
return this.entityData.get(HEALTH);
|
|
}
|
|
|
|
public void setHealth(float pHealth) {
|
|
this.entityData.set(HEALTH, Mth.clamp(pHealth, 0.0F, this.getMaxHealth()));
|
|
}
|
|
|
|
public float getMaxHealth() {
|
|
return 50;
|
|
}
|
|
|
|
@Override
|
|
public boolean canBeCollidedWith() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean isPushable() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean isPickable() {
|
|
return !this.isRemoved();
|
|
}
|
|
|
|
@Override
|
|
public void baseTick() {
|
|
super.baseTick();
|
|
|
|
float delta = Math.abs(getYRot() - yRotO);
|
|
while (getYRot() > 180F) {
|
|
setYRot(getYRot() - 360F);
|
|
yRotO = getYRot() - delta;
|
|
}
|
|
while (getYRot() <= -180F) {
|
|
setYRot(getYRot() + 360F);
|
|
yRotO = delta + getYRot();
|
|
}
|
|
|
|
handleClientSync();
|
|
|
|
if (this.getHealth() <= 0) {
|
|
this.ejectPassengers();
|
|
destroy();
|
|
}
|
|
|
|
travel();
|
|
this.refreshDimensions();
|
|
}
|
|
|
|
public void destroy() {
|
|
}
|
|
|
|
public void travel() {
|
|
}
|
|
|
|
protected void handleClientSync() {
|
|
if (isControlledByLocalInstance()) {
|
|
interpolationSteps = 0;
|
|
syncPacketPositionCodec(getX(), getY(), getZ());
|
|
}
|
|
if (interpolationSteps <= 0) {
|
|
return;
|
|
}
|
|
double interpolatedX = getX() + (x - getX()) / (double) interpolationSteps;
|
|
double interpolatedY = getY() + (y - getY()) / (double) interpolationSteps;
|
|
double interpolatedZ = getZ() + (z - getZ()) / (double) interpolationSteps;
|
|
double interpolatedYaw = Mth.wrapDegrees(serverYRot - (double) getYRot());
|
|
setYRot(getYRot() + (float) interpolatedYaw / (float) interpolationSteps);
|
|
setXRot(getXRot() + (float) (serverXRot - (double) getXRot()) / (float) interpolationSteps);
|
|
|
|
setPos(interpolatedX, interpolatedY, interpolatedZ);
|
|
setRot(getYRot(), getXRot());
|
|
|
|
--interpolationSteps;
|
|
}
|
|
|
|
@Override
|
|
public void lerpTo(double x, double y, double z, float yaw, float pitch, int interpolationSteps, boolean interpolate) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
serverYRot = yaw;
|
|
serverXRot = pitch;
|
|
this.interpolationSteps = 10;
|
|
}
|
|
|
|
public static double calculateAngle(Vec3 move, Vec3 view) {
|
|
move = move.multiply(1, 0, 1).normalize();
|
|
view = view.multiply(1, 0, 1).normalize();
|
|
|
|
double startLength = move.length();
|
|
double endLength = view.length();
|
|
if (startLength > 0.0D && endLength > 0.0D) {
|
|
return Math.toDegrees(Math.acos(Mth.clamp(move.dot(view) / (startLength * endLength), -1, 1)));
|
|
} else {
|
|
return 0.0D;
|
|
}
|
|
}
|
|
}
|