Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/main/java/edn/stratodonut/trackwork/TrackworkUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.valkyrienskies.core.api.world.PhysLevel;

import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -71,8 +72,11 @@ public record ClipResult(@Nonnull Vector3dc trackTangent, @Nullable Vector3dc su
throw new IllegalArgumentException(String.format("Invalid clip order. Must be 0, 1 or 2, received %d", order));
}

long[] ignoredIds = Arrays.copyOf(ignoreWheelIds, ignoreWheelIds.length + 1);
ignoredIds[ignoredIds.length - 1] = ship.getId();

Optional<ReducedRayCastResult> accumResult = points
.map(p -> physLevel.rayCast(p, normal, clipVector.length(), ignoreWheelIds))
.map(p -> physLevel.rayCast(p, normal, clipVector.length(), ignoredIds))
.filter(Objects::nonNull)
.filter(result -> result.getHitBody().getId() != ship.getId())
.map(result -> new ReducedRayCastResult(result.getDistance(), result.getVelocity()))
Expand Down
68 changes: 53 additions & 15 deletions src/main/java/edn/stratodonut/trackwork/wheel/WheelEntity.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
package edn.stratodonut.trackwork.wheel;

import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.apache.logging.log4j.core.jmx.Server;
import org.jetbrains.annotations.NotNull;
import org.joml.Matrix3d;
import org.joml.Quaterniond;
import org.joml.Quaterniondc;
import org.joml.Vector3d;
import org.joml.Vector3dc;
import org.valkyrienskies.core.api.ships.properties.ShipInertiaData;
import org.valkyrienskies.core.api.ships.properties.ShipTransform;
import org.valkyrienskies.core.internal.ShipTeleportData;
import org.valkyrienskies.core.internal.physics.PhysicsEntityData;
import org.valkyrienskies.core.internal.physics.PhysicsEntityServer;
import org.valkyrienskies.core.internal.physics.VSSphereCollisionShapeData;
import org.valkyrienskies.core.internal.world.VsiServerShipWorld;
import org.valkyrienskies.mod.common.VSGameUtilsKt;
import org.valkyrienskies.mod.common.util.DimensionIdProvider;

import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static org.valkyrienskies.mod.common.ValkyrienSkiesMod.getVsCore;

public class WheelEntity {
private static volatile Method newShipTeleportDataMethod;
private static volatile Method teleportPhysicsEntityMethod;

public static @Nullable PhysicsEntityServer getInLevel(ServerLevel level, long id) {
if (!aliveInLevel(level, id)) {
return null;
Expand Down Expand Up @@ -54,19 +55,56 @@ public static boolean moveTo(ServerLevel level, long id, Vector3dc pos) {
PhysicsEntityServer serverData = VSGameUtilsKt.getShipObjectWorld(level)
.retrieveLoadedPhysicsEntities().get(id);

ShipTeleportData teleportData = getVsCore().newShipTeleportData(
pos,
new Quaterniond(),
new Vector3d(),
new Vector3d(),
null,
null,
null
);
VSGameUtilsKt.getShipObjectWorld(level).teleportPhysicsEntity(serverData, teleportData);
Object vsCore = getVsCore();
Object shipWorld = VSGameUtilsKt.getShipObjectWorld(level);
try {
Method create = newShipTeleportDataMethod;
if (create == null) {
create = vsCore.getClass().getMethod(
"newShipTeleportData",
Vector3dc.class, Quaterniondc.class, Vector3dc.class, Vector3dc.class,
String.class, Double.class, Vector3dc.class
);
newShipTeleportDataMethod = create;
}
Object teleportData = create.invoke(vsCore,
pos,
new Quaterniond(),
new Vector3d(),
new Vector3d(),
null,
null,
null
);

Method teleport = teleportPhysicsEntityMethod;
if (teleport == null) {
teleport = findTeleportPhysicsEntity(shipWorld.getClass());
teleportPhysicsEntityMethod = teleport;
}
teleport.invoke(shipWorld, serverData, teleportData);
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new RuntimeException("Trackwork: incompatible Valkyrien Skies version, could not teleport wheel physics entity", e);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException) throw (RuntimeException) cause;
if (cause instanceof Error) throw (Error) cause;
throw new RuntimeException("Trackwork: failed to teleport wheel physics entity", cause);
}
return true;
}

private static Method findTeleportPhysicsEntity(Class<?> shipWorldClass) throws NoSuchMethodException {
for (Method m : shipWorldClass.getMethods()) {
if (!"teleportPhysicsEntity".equals(m.getName())) continue;
if (m.getParameterCount() != 2) continue;
if (m.getParameterTypes()[0].isAssignableFrom(PhysicsEntityServer.class)) {
return m;
}
}
throw new NoSuchMethodException("teleportPhysicsEntity(PhysicsEntityServer, ShipTeleportData) not found on " + shipWorldClass.getName());
}

public static final class DataBuilder {
private DataBuilder() {
}
Expand Down