Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

no gravity entities with correct trajectory and accurate multishot crossbow trajectories #3818

Merged
merged 7 commits into from
Jul 12, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ private void onTick(TickEvent.Pre event) {
UUID owner = ((ProjectileEntityAccessor) e).getOwnerUuid();
if (owner != null && owner.equals(mc.player.getUuid())) continue;
}
if (!simulator.set(e, accurate.get(), 0.5D)) continue;
if (!simulator.set(e, accurate.get(), 0.5D, false)) continue;
for (int i = 0; i < (simulationSteps.get() > 0 ? simulationSteps.get() : Integer.MAX_VALUE); i++) {
points.add(vec3s.get().set(simulator.pos));
if (simulator.tick() != null) break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ public class Trajectories extends Module {
private final Pool<Vector3d> vec3s = new Pool<>(Vector3d::new);
private final List<Path> paths = new ArrayList<>();

private final double multishotOffset = Math.toRadians(10); // accurate-ish offset of crossbow multishot in radians (10° degrees)
xNasuni marked this conversation as resolved.
Show resolved Hide resolved

public Trajectories() {
super(Categories.Render, "trajectories", "Predicts the trajectory of throwable items.");
}
Expand Down Expand Up @@ -146,19 +148,25 @@ private void calculatePath(PlayerEntity player, double tickDelta) {
getEmptyPath().calculate();

if (itemStack.getItem() instanceof CrossbowItem && EnchantmentHelper.getLevel(Enchantments.MULTISHOT, itemStack) > 0) {
if (!simulator.set(player, itemStack, -10, accurate.get(), tickDelta)) return;
if (!simulator.set(player, itemStack, multishotOffset, accurate.get(), tickDelta)) return; // left multishot arrow
getEmptyPath().calculate();

if (!simulator.set(player, itemStack, 10, accurate.get(), tickDelta)) return;
if (!simulator.set(player, itemStack, -multishotOffset, accurate.get(), tickDelta)) return; // right multishot arrow
getEmptyPath().calculate();
}
}

private void calculateFiredPath(Entity entity, double tickDelta) {
for (Path path : paths) path.clear();

if (entity.hasNoGravity()) {
if (!simulator.set(entity, accurate.get(), tickDelta, true)) return;
getEmptyPath().calculate();
return;
}

// Calculate paths
if (!simulator.set(entity, accurate.get(), tickDelta)) return;
if (!simulator.set(entity, accurate.get(), tickDelta, false)) return;
xNasuni marked this conversation as resolved.
Show resolved Hide resolved
getEmptyPath().calculate();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,21 +114,41 @@ public void set(Entity user, double roll, double speed, double simulated, double
this.waterDrag = waterDrag;
}

public boolean set(Entity entity, boolean accurate, double tickDelta) {
public boolean set(Entity entity, boolean accurate, double tickDelta, boolean noGravity) {
// skip entities in ground
if (entity instanceof PersistentProjectileEntity && ((ProjectileInGroundAccessor) entity).getInGround()) return false;

if (entity instanceof ArrowEntity arrow) {
// im not sure if arrow.getVelocity().length() is correct but it works ¯\_(ツ)_/¯
set(entity, arrow.getVelocity().length(), 0.05000000074505806, 0.6, accurate, tickDelta);
double gravity = 0.05000000074505806;
if (noGravity) {
xNasuni marked this conversation as resolved.
Show resolved Hide resolved
gravity = 0;
}
set(entity, arrow.getVelocity().length(), gravity, 0.6, accurate, tickDelta);
} else if (entity instanceof EnderPearlEntity || entity instanceof SnowballEntity || entity instanceof EggEntity) {
set(entity, 1.5, 0.03, 0.8, accurate, tickDelta);
double gravity = 0.03;
if (noGravity) {
gravity = 0;
}
set(entity, 1.5, gravity, 0.8, accurate, tickDelta);
} else if (entity instanceof TridentEntity) {
set(entity, 2.5, 0.05000000074505806, 0.99, accurate, tickDelta);
double gravity = 0.05000000074505806;
if (noGravity) {
gravity = 0;
}
set(entity, 2.5, gravity, 0.99, accurate, tickDelta);
} else if (entity instanceof ExperienceBottleEntity) {
set(entity, 0.7, 0.07, 0.8, accurate, tickDelta);
double gravity = 0.07;
if (noGravity) {
gravity = 0;
}
set(entity, 0.7, gravity, 0.8, accurate, tickDelta);
} else if (entity instanceof ThrownEntity) {
set(entity, 0.5, 0.05, 0.8, accurate, tickDelta);
double gravity = 0.05;
if (noGravity) {
gravity = 0;
}
set(entity, 0.5, gravity, 0.8, accurate, tickDelta);
} else if (entity instanceof WitherSkullEntity || entity instanceof FireballEntity || entity instanceof DragonFireballEntity) {
set(entity, 0.95, 0, 0.8, accurate, tickDelta);
}
Expand Down