Add Metalstorm-style cursor aim
Virtual stick cursor steered through the gun reticle, server-side virtual pilot using measured control responses, client cursor/camera handling with look-ahead, free look and scroll zoom. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YVREx3uo7nz1FEhzveWTUh
This commit is contained in:
17 files changed
+1037
-38
No files matched your search
@@ -0,0 +1,101 @@
|
||||
package dev.lumareth.improvedAerodynamics.flight;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
|
||||
/**
|
||||
* The frame cursor aim steers in, in ship coordinates: forward is the boresight (what Warium's gun reticle points
|
||||
* along, from the HUD block in front of the seat, else the way the seat faces), up is the ship's up axis and right
|
||||
* completes it. Server and client both build it from the same block data, so a cursor sent as components in this
|
||||
* frame means the same on both.
|
||||
*
|
||||
* @param nodePos the Vehicle Control Node the seat is linked to
|
||||
*/
|
||||
public record AimBasis(BlockPos seatPos, BlockPos nodePos, double[] forward, double[] right, double[] up) {
|
||||
|
||||
/**
|
||||
* @param entityPos block position of the seat entity. Warium's control seat block is at that position or just
|
||||
* below it.
|
||||
* @return null if there is no seat block linked to a control node there
|
||||
*/
|
||||
public static AimBasis of(Level level, BlockPos entityPos) {
|
||||
for (BlockPos pos : new BlockPos[]{entityPos, entityPos.below()}) {
|
||||
BlockEntity seat = level.getBlockEntity(pos);
|
||||
if (seat == null || !seat.getPersistentData().contains("ControlX")) {
|
||||
continue;
|
||||
}
|
||||
CompoundTag tag = seat.getPersistentData();
|
||||
BlockPos nodePos = BlockPos.containing(tag.getDouble("ControlX"), tag.getDouble("ControlY"), tag.getDouble("ControlZ"));
|
||||
return new AimBasis(pos, nodePos, null, null, null).withAxes(level, pos, nodePos);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private AimBasis withAxes(Level level, BlockPos seatPos, BlockPos nodePos) {
|
||||
BlockState state = level.getBlockState(seatPos);
|
||||
Direction facing = Direction.NORTH;
|
||||
Property<?> property = state.getBlock().getStateDefinition().getProperty("facing");
|
||||
if (property instanceof DirectionProperty directionProperty) {
|
||||
facing = state.getValue(directionProperty);
|
||||
}
|
||||
double fx = facing.getStepX();
|
||||
double fy = facing.getStepY();
|
||||
double fz = facing.getStepZ();
|
||||
|
||||
// Warium's gun reticle: the HUD block in front of the seat holds the aim vector of its guns
|
||||
BlockEntity hud = level.getBlockEntity(seatPos.relative(facing));
|
||||
if (hud != null && hud.getPersistentData().contains("Pitch")) {
|
||||
CompoundTag hudTag = hud.getPersistentData();
|
||||
double bx = hudTag.getDouble("X") + facing.getStepX();
|
||||
double by = hudTag.getDouble("Pitch");
|
||||
double bz = hudTag.getDouble("Z") + facing.getStepZ();
|
||||
if (bx * bx + by * by + bz * bz > 1.0E-6) {
|
||||
fx = bx;
|
||||
fy = by;
|
||||
fz = bz;
|
||||
}
|
||||
}
|
||||
double length = Math.sqrt(fx * fx + fy * fy + fz * fz);
|
||||
if (length < 1.0E-6) {
|
||||
fx = 0.0;
|
||||
fy = 0.0;
|
||||
fz = -1.0;
|
||||
length = 1.0;
|
||||
}
|
||||
fx /= length;
|
||||
fy /= length;
|
||||
fz /= length;
|
||||
|
||||
// right = forward x up(0,1,0)
|
||||
double rx = -fz;
|
||||
double ry = 0.0;
|
||||
double rz = fx;
|
||||
double rl = Math.sqrt(rx * rx + rz * rz);
|
||||
if (rl < 1.0E-6) {
|
||||
rx = 1.0;
|
||||
rz = 0.0;
|
||||
rl = 1.0;
|
||||
}
|
||||
rx /= rl;
|
||||
rz /= rl;
|
||||
// up = right x forward
|
||||
double ux = ry * fz - rz * fy;
|
||||
double uy = rz * fx - rx * fz;
|
||||
double uz = rx * fy - ry * fx;
|
||||
return new AimBasis(seatPos, nodePos, new double[]{fx, fy, fz}, new double[]{rx, ry, rz}, new double[]{ux, uy, uz});
|
||||
}
|
||||
|
||||
/** Ship-space direction of a cursor given by its components along forward, right and up. */
|
||||
public double[] toShip(double cf, double cr, double cu) {
|
||||
return new double[]{
|
||||
forward[0] * cf + right[0] * cr + up[0] * cu,
|
||||
forward[1] * cf + right[1] * cr + up[1] * cu,
|
||||
forward[2] * cf + right[2] * cr + up[2] * cu};
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user