I made a basic homing arrow, which I am going to refine further, but as of now I have the problem of the Arrow not rendering properly.
It works fine on the server side, but on the client it always appears as if the arrow was flying normally, until it synchs and teleports around.
[https://gemoo.com/tools/upload-video/share/661346070437036032?codeId=MpmzxaW0pBpE1&card=661346066800603136&origin=videolinkgenerator]
the white particles are created by the entity every tick on the server side and represent its actual flying path.
My best guess is that this behaviour is caused, because minecraft appears to try to predict the projectiles path on the client side instead of constantly synching (perhaps something to do with it implementing the TracableEntity interface??).
I am thinking I need help with either
1. Getting the client to use my custom Tick function in its path prediction, or
2. (the less elegant solution) getting the game to synch up the direction, position and movement etc. every tick.
Note that my custom arrow class extends AbstractArrow.
everything important it does:
private static final EntityDataAccessor<Integer> TARGET_ENTITY = SynchedEntityData.defineId(ReachArrow.class, EntityDataSerializers.INT);
@Override
public void addAdditionalSaveData(CompoundTag pCompound) {
super.addAdditionalSaveData(pCompound);
pCompound.putInt("TargetEntity", this.getTargetEntity());
}
@Override
public void readAdditionalSaveData(CompoundTag pCompound) {
super.readAdditionalSaveData(pCompound);
this.setTargetEntity(pCompound.getInt("TargetEntity"));
}
@Override
protected void defineSynchedData() {
super.defineSynchedData();
this.entityData.define(TARGET_ENTITY, -1);
}
@Override
public void shootFromRotation(Entity pShooter, float pX, float pY, float pZ, float pVelocity, float pInaccuracy) {
LivingEntity target = ReachArrow.findNearestTarget(this.level(),(LivingEntity) pShooter,50d);
if(pShooter instanceof LivingEntity && target !=null){
//pShooter.sendSystemMessage(Component.literal("setting id "+target.getId()+" as target"));
setTargetEntity(target.getId());
//pShooter.sendSystemMessage(Component.literal("target set"));
}
super.shootFromRotation(pShooter, pX, pY, pZ, pVelocity, pInaccuracy);
}
public static LivingEntity findNearestTarget(Level world, LivingEntity shooter, double range) {
AABB searchBox = shooter.getBoundingBox().inflate(range);
List<LivingEntity> potentialTargets = world.getEntitiesOfClass(LivingEntity.class, searchBox, EntitySelector.NO_SPECTATORS);
LivingEntity nearestTarget = null;
double closestDistance = Double.MAX_VALUE;
for (LivingEntity potentialTarget : potentialTargets) {
if (potentialTarget != shooter && potentialTarget.isAlive()) {
double distance = shooter.distanceToSqr(potentialTarget);
if (distance < closestDistance) {
closestDistance = distance;
nearestTarget = potentialTarget;
}
}
}
return nearestTarget;
}
I tried fixing the problem by storing the Target using SynchedEntityData, which not only didn't fix the problem, but also added unwanted, blue particles to the arrow (like on tipped arrow)
Thank you in advance for any help or hints, I am quite new at this so you could probably help me a lot. :)