diff --git a/src/main/java/com/atsuishio/superbwarfare/block/entity/FuMO25BlockEntity.java b/src/main/java/com/atsuishio/superbwarfare/block/entity/FuMO25BlockEntity.java index aad8581ad..5e86c9976 100644 --- a/src/main/java/com/atsuishio/superbwarfare/block/entity/FuMO25BlockEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/block/entity/FuMO25BlockEntity.java @@ -31,6 +31,7 @@ public class FuMO25BlockEntity extends BlockEntity implements MenuProvider { // 固定距离,以后有人改动这个需要自行解决GUI渲染问题 public static final int DEFAULT_RANGE = 96; public static final int MAX_RANGE = 128; + public static final int GLOW_RANGE = 64; public static final int DEFAULT_ENERGY_COST = 256; public static final int MAX_ENERGY_COST = 1024; @@ -106,6 +107,7 @@ public class FuMO25BlockEntity extends BlockEntity implements MenuProvider { } else { blockEntity.energyHandler.ifPresent(handler -> handler.extractEnergy(energyCost, false)); if (blockEntity.time > 0) { + blockEntity.setGlowEffect(); blockEntity.time--; blockEntity.setChanged(); } @@ -120,6 +122,15 @@ public class FuMO25BlockEntity extends BlockEntity implements MenuProvider { public static void clientTick(Level pLevel, BlockPos pPos, BlockState pState, FuMO25BlockEntity blockEntity) { + } + + private void setGlowEffect() { + if (this.type != FuncType.GLOW) return; + + Level level = this.level; + if (level == null) return; + + } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/EnergyVehicleEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/EnergyVehicleEntity.java index 2ce193de1..eb589405c 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/EnergyVehicleEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/EnergyVehicleEntity.java @@ -10,7 +10,9 @@ import net.minecraft.world.level.Level; import org.joml.Math; public class EnergyVehicleEntity extends VehicleEntity implements IChargeEntity { + public static final EntityDataAccessor ENERGY = SynchedEntityData.defineId(EnergyVehicleEntity.class, EntityDataSerializers.INT); + public EnergyVehicleEntity(EntityType pEntityType, Level pLevel) { super(pEntityType, pLevel); this.setEnergy(0); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/MobileVehicleEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/MobileVehicleEntity.java index 6be7f1db1..827d3d8a9 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/MobileVehicleEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/MobileVehicleEntity.java @@ -8,6 +8,7 @@ import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MoverType; @@ -20,7 +21,9 @@ import net.minecraft.world.phys.Vec3; import org.joml.Math; public class MobileVehicleEntity extends EnergyVehicleEntity { + public static final EntityDataAccessor POWER = SynchedEntityData.defineId(MobileVehicleEntity.class, EntityDataSerializers.FLOAT); + public boolean leftInputDown; public boolean rightInputDown; public boolean forwardInputDown; @@ -62,7 +65,6 @@ public class MobileVehicleEntity extends EnergyVehicleEntity { var frontBox = getBoundingBox().move(velocity.scale(0.5)); var velAdd = velocity.add(0, 0, 0).scale(0.9); for (var entity : level().getEntities(EntityTypeTest.forClass(Entity.class), frontBox, entity -> entity != this && entity != getFirstPassenger() && entity.getVehicle() == null)) { - double entitySize = entity.getBbWidth() * entity.getBbHeight(); double thisSize = this.getBbWidth() * this.getBbHeight(); double f = Math.min(entitySize / thisSize, 2); @@ -86,7 +88,7 @@ public class MobileVehicleEntity extends EnergyVehicleEntity { } public SoundEvent getEngineSound() { - return null; + return SoundEvents.EMPTY; } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/SpeedboatEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/SpeedboatEntity.java index 0899c3340..b2c0eb556 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/SpeedboatEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/SpeedboatEntity.java @@ -80,6 +80,7 @@ import java.util.List; import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle; public class SpeedboatEntity extends MobileVehicleEntity implements GeoEntity, IChargeEntity, IVehicleEntity, HasCustomInventoryScreen, ContainerEntity { + public static final EntityDataAccessor FIRE_ANIM = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.INT); public static final EntityDataAccessor DELTA_ROT = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.FLOAT); public static final EntityDataAccessor HEAT = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.INT); @@ -175,6 +176,7 @@ public class SpeedboatEntity extends MobileVehicleEntity implements GeoEntity, I return true; } + public double getSubmergedHeight(Entity entity) { for (FluidType fluidType : ForgeRegistries.FLUID_TYPES.get().getValues()) { if (entity.level().getFluidState(entity.blockPosition()).getFluidType() == fluidType) @@ -233,9 +235,9 @@ public class SpeedboatEntity extends MobileVehicleEntity implements GeoEntity, I this.heal(0.05f); if (this.level() instanceof ServerLevel serverLevel && this.isInWater() && this.getDeltaMovement().length() > 0.1) { - sendParticle(serverLevel, ParticleTypes.CLOUD, this.getX() + 0.5 * this.getDeltaMovement().x, this.getY() + getSubmergedHeight(this) - 0.2, this.getZ() + 0.5 * this.getDeltaMovement().z, (int)(2 + 4 * this.getDeltaMovement().length()), 0.65, 0, 0.65, 0, true); - sendParticle(serverLevel, ParticleTypes.BUBBLE_COLUMN_UP, this.getX() + 0.5 * this.getDeltaMovement().x, this.getY() + getSubmergedHeight(this) - 0.2, this.getZ() + 0.5 * this.getDeltaMovement().z, (int)(2 + 10 * this.getDeltaMovement().length()), 0.65, 0, 0.65, 0, true); - sendParticle(serverLevel, ParticleTypes.BUBBLE_COLUMN_UP, this.getX() - 4.5 * this.getLookAngle().x, this.getY() - 0.25, this.getZ() - 4.5 * this.getLookAngle().z, (int)(40 * Mth.abs(this.entityData.get(POWER))), 0.15, 0.15, 0.15, 0.02, true); + sendParticle(serverLevel, ParticleTypes.CLOUD, this.getX() + 0.5 * this.getDeltaMovement().x, this.getY() + getSubmergedHeight(this) - 0.2, this.getZ() + 0.5 * this.getDeltaMovement().z, (int) (2 + 4 * this.getDeltaMovement().length()), 0.65, 0, 0.65, 0, true); + sendParticle(serverLevel, ParticleTypes.BUBBLE_COLUMN_UP, this.getX() + 0.5 * this.getDeltaMovement().x, this.getY() + getSubmergedHeight(this) - 0.2, this.getZ() + 0.5 * this.getDeltaMovement().z, (int) (2 + 10 * this.getDeltaMovement().length()), 0.65, 0, 0.65, 0, true); + sendParticle(serverLevel, ParticleTypes.BUBBLE_COLUMN_UP, this.getX() - 4.5 * this.getLookAngle().x, this.getY() - 0.25, this.getZ() - 4.5 * this.getLookAngle().z, (int) (40 * Mth.abs(this.entityData.get(POWER))), 0.15, 0.15, 0.15, 0.02, true); } collideBlock(); @@ -442,6 +444,7 @@ public class SpeedboatEntity extends MobileVehicleEntity implements GeoEntity, I public void setRudderRot(float pRudderRot) { this.rudderRot = pRudderRot; } + @Override public SoundEvent getEngineSound() { return ModSounds.BOAT_ENGINE.get(); @@ -488,6 +491,7 @@ public class SpeedboatEntity extends MobileVehicleEntity implements GeoEntity, I } } } + @Override public void destroy() { Entity attacker = EntityFindUtil.findEntity(this.level(), this.entityData.get(LAST_ATTACKER_UUID)); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/VehicleEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/VehicleEntity.java index 172390bdb..e51f6fb2d 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/VehicleEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/VehicleEntity.java @@ -23,10 +23,11 @@ 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 HEALTH = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.FLOAT); protected static final EntityDataAccessor LAST_ATTACKER_UUID = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.STRING); + protected int interpolationSteps; protected double x; protected double y; @@ -61,17 +62,19 @@ public class VehicleEntity extends Entity { @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); + + ItemStack stack = player.getItemInHand(hand); + if (player.isShiftKeyDown() && stack.is(ModItems.CROWBAR.get())) { + ItemStack container = ContainerBlockItem.createInstance(this); + if (!player.addItem(container)) { + player.drop(container, false); } this.remove(RemovalReason.DISCARDED); this.discard(); - } else if (player.getMainHandItem().is(Items.IRON_INGOT)) { + } else if (stack.is(Items.IRON_INGOT)) { if (this.getHealth() < this.getMaxHealth()) { this.heal(Math.min(50, this.getMaxHealth())); - player.getMainHandItem().shrink(1); + stack.shrink(1); if (!this.level().isClientSide) { this.level().playSound(null, this, SoundEvents.IRON_GOLEM_REPAIR, this.getSoundSource(), 0.5f, 1); } @@ -159,7 +162,7 @@ public class VehicleEntity extends Entity { @Override public boolean isPushable() { - return false; + return super.isPushable(); } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/WheelChairEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/WheelChairEntity.java index 58ef14e68..0c835c8b3 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/WheelChairEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/WheelChairEntity.java @@ -35,6 +35,7 @@ import software.bernie.geckolib.util.GeckoLibUtil; import java.util.List; public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity, IVehicleEntity { + private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static final float MAX_HEALTH = 50; public static final int MAX_ENERGY = 24000; @@ -191,7 +192,7 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity, this.extraEnergy(1); } - if (passenger instanceof Player player && handBusyTime > 0) { + if (passenger instanceof Player player && player.level().isClientSide && this.handBusyTime > 0) { var localPlayer = Minecraft.getInstance().player; if (localPlayer != null && player.getUUID().equals(localPlayer.getUUID())) { localPlayer.handsBusy = true; @@ -212,10 +213,6 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity, this.setLeftWheelRot((float) (this.getLeftWheelRot() - 1 * s0) - 0.015f * Mth.clamp(0.4f * diffY, -5f, 5f)); this.setRightWheelRot((float) (this.getRightWheelRot() - 1 * s0) + 0.015f * Mth.clamp(0.4f * diffY, -5f, 5f)); -// if (entity instanceof Player player) { -// player.displayClientMessage(Component.literal("Angle:" + new java.text.DecimalFormat("##.##").format(this.getRightWheelRot())), true); -// } - this.setDeltaMovement(this.getDeltaMovement().add(Mth.sin(-this.getYRot() * 0.017453292F) * (this.onGround() ? 1 : 0.1) * this.entityData.get(POWER), 0.0, Mth.cos(this.getYRot() * 0.017453292F) * (this.onGround() ? 1 : 0.1) * this.entityData.get(POWER))); } @@ -226,7 +223,7 @@ public class WheelChairEntity extends MobileVehicleEntity implements GeoEntity, } player.causeFoodExhaustion(0.03F); - handBusyTime = 4; + this.handBusyTime = 4; this.forwardInputDown = false; this.backInputDown = false; } diff --git a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java index 75ac05d4d..c434f11fb 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java @@ -220,6 +220,8 @@ public class ClientEventHandler { if (level == null) return; ItemStack stack = player.getMainHandItem(); + if (!stack.is(ModTags.Items.GUN)) return; + var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO); int mode = GunsTool.getGunIntTag(stack, "FireMode"); @@ -1178,7 +1180,7 @@ public class ClientEventHandler { if (level > 0) { Entity seekingEntity = SeekTool.seekLivingEntity(player, player.level(), 32 + 8 * (level - 1), 25 / zoomFov); if (seekingEntity != null && seekingEntity.isAlive()) { - Vec3 targetVec = new Vec3(seekingEntity.getX() - player.getX(),seekingEntity.getEyeY() - player.getEyeY(), seekingEntity.getZ() - player.getZ()).normalize(); + Vec3 targetVec = new Vec3(seekingEntity.getX() - player.getX(), seekingEntity.getEyeY() - player.getEyeY(), seekingEntity.getZ() - player.getZ()).normalize(); Vec3 toVec = new Vec3(player.getViewVector(1).add(targetVec.scale(times)).toVector3f()); look(player, toVec); } @@ -1188,16 +1190,12 @@ public class ClientEventHandler { } if (stack.is(ModItems.MONITOR.get()) && stack.getOrCreateTag().getBoolean("Using") && stack.getOrCreateTag().getBoolean("Linked")) { - droneFovLerp = Mth.lerp(0.1 * Minecraft.getInstance().getDeltaFrameTime(), droneFovLerp, droneFov); - event.setFOV(event.getFOV() / droneFovLerp); } if (player.getVehicle() instanceof IVehicleEntity && !(player.getVehicle() instanceof ICannonEntity) && zoom) { - vehicleFovLerp = Mth.lerp(0.1 * Minecraft.getInstance().getDeltaFrameTime(), vehicleFovLerp, vehicleFov); - event.setFOV(event.getFOV() / vehicleFovLerp); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java index 45809347b..52f3f208d 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/LivingEventHandler.java @@ -4,10 +4,7 @@ import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.capability.LaserCapability; import com.atsuishio.superbwarfare.capability.ModCapabilities; import com.atsuishio.superbwarfare.config.common.GameplayConfig; -import com.atsuishio.superbwarfare.entity.ICannonEntity; -import com.atsuishio.superbwarfare.entity.ICustomKnockback; -import com.atsuishio.superbwarfare.entity.IVehicleEntity; -import com.atsuishio.superbwarfare.entity.TargetEntity; +import com.atsuishio.superbwarfare.entity.*; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.item.gun.GunItem; @@ -48,6 +45,7 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.network.PacketDistributor; import java.text.DecimalFormat; +import java.util.Objects; @Mod.EventBusSubscriber public class LivingEventHandler { @@ -320,8 +318,8 @@ public class LivingEventHandler { if (player instanceof ServerPlayer serverPlayer) { if (newStack.getItem() != oldStack.getItem() || newStack.getTag() == null || oldStack.getTag() == null - || !GunsTool.getGunData(newStack).hasUUID("UUID") || !GunsTool.getGunData(oldStack).hasUUID("UUID") - || !GunsTool.getGunData(newStack).getUUID("UUID").equals(GunsTool.getGunData(oldStack).getUUID("UUID")) +// || !GunsTool.getGunData(newStack).hasUUID("UUID") || !GunsTool.getGunData(oldStack).hasUUID("UUID") + || !Objects.equals(GunsTool.getGunUUID(newStack), GunsTool.getGunUUID(oldStack)) ) { if (oldStack.getItem() instanceof GunItem oldGun) { stopGunReloadSound(serverPlayer, oldGun); @@ -784,7 +782,7 @@ public class LivingEventHandler { if (level <= 0) return; if (entity.getHealth() < 100.0f) return; - event.setAmount((float) (event.getAmount() + entity.getHealth() * 0.00002f * Math.pow(level,2))); + event.setAmount((float) (event.getAmount() + entity.getHealth() * 0.00002f * Math.pow(level, 2))); } @SubscribeEvent @@ -794,4 +792,12 @@ public class LivingEventHandler { event.setStrength((float) knockback.superbWarfare$getKnockbackStrength()); } } + + @SubscribeEvent + public static void onEntityFall(LivingFallEvent event) { + LivingEntity living = event.getEntity(); + if (living.getVehicle() instanceof VehicleEntity) { + event.setCanceled(true); + } + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/event/PlayerEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/PlayerEventHandler.java index 83443a767..4f16bbe95 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/PlayerEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/PlayerEventHandler.java @@ -2,7 +2,6 @@ package com.atsuishio.superbwarfare.event; import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.config.common.GameplayConfig; -import com.atsuishio.superbwarfare.entity.VehicleEntity; import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.init.ModTags; @@ -21,13 +20,11 @@ import net.minecraft.util.Mth; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraftforge.event.AnvilUpdateEvent; import net.minecraftforge.event.TickEvent; -import net.minecraftforge.event.entity.living.LivingFallEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @@ -391,12 +388,4 @@ public class PlayerEventHandler { event.setMaterialCost(1); } } - - @SubscribeEvent - public static void onEntityFall(LivingFallEvent event) { - LivingEntity living = event.getEntity(); - if (living.getVehicle() instanceof VehicleEntity) { - event.setCanceled(true); - } - } } diff --git a/src/main/java/com/atsuishio/superbwarfare/item/ContainerBlockItem.java b/src/main/java/com/atsuishio/superbwarfare/item/ContainerBlockItem.java index 991fc3789..f96d69fbc 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/ContainerBlockItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/ContainerBlockItem.java @@ -101,9 +101,11 @@ public class ContainerBlockItem extends BlockItem implements GeoItem { public static ItemStack createAnnihilatorInstance() { return createInstance(ModEntities.ANNIHILATOR.get()); } + public static ItemStack createSpeedboatInstance() { return createInstance(ModEntities.SPEEDBOAT.get()); } + public static ItemStack createWheelChairInstance() { return createInstance(ModEntities.WHEEL_CHAIR.get()); } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/GunsTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/GunsTool.java index 4cd4e0182..50a10bd89 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/GunsTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/GunsTool.java @@ -17,6 +17,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.network.PacketDistributor; +import javax.annotation.Nullable; import java.io.InputStreamReader; import java.util.HashMap; import java.util.UUID; @@ -254,4 +255,13 @@ public class GunsTool { if (!data.contains(name)) return defaultValue; return data.getBoolean(name); } + + @Nullable + public static UUID getGunUUID(ItemStack stack) { + CompoundTag tag = stack.getTag(); + if (tag == null || !tag.contains("GunData")) return null; + CompoundTag data = tag.getCompound("GunData"); + if (!data.hasUUID("UUID")) return null; + return data.getUUID("UUID"); + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java index 211c64ee8..d8305f5b5 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java @@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.tools; import com.atsuishio.superbwarfare.entity.IVehicleEntity; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; +import net.minecraft.core.BlockPos; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ExperienceOrb; @@ -72,6 +73,16 @@ public class SeekTool { }).toList(); } + public static List getEntitiesWithinRange(BlockPos pos, Level level, double range) { + return StreamSupport.stream(EntityFindUtil.getEntities(level).getAll().spliterator(), false) + .filter(e -> e.distanceToSqr(pos.getX(), pos.getY(), pos.getZ()) <= range * range + && e.isAlive() + && !(e instanceof ItemEntity || e instanceof ExperienceOrb || e instanceof HangingEntity || e instanceof ProjectileEntity || e instanceof Projectile || e instanceof ArmorStand) + && (e instanceof LivingEntity || e instanceof IVehicleEntity) + && !(e instanceof Player player && (player.isCreative() || player.isSpectator()))) + .toList(); + } + private static double calculateAngle(Entity entityA, Entity entityB) { Vec3 start = new Vec3(entityA.getX() - entityB.getX(), entityA.getY() - entityB.getY(), entityA.getZ() - entityB.getZ()); Vec3 end = entityB.getLookAngle();