adfds
This commit is contained in:
119
.gitignore
vendored
Normal file
119
.gitignore
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
# User-specific stuff
|
||||
.idea/
|
||||
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
.gradle
|
||||
build/
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Cache of project
|
||||
.gradletasknamecache
|
||||
|
||||
**/build/
|
||||
|
||||
# Common working directory
|
||||
run/
|
||||
runs/
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
2
LICENSE.txt
Normal file
2
LICENSE.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Copyright (c) 2025
|
||||
All rights reserved.
|
||||
95
build.gradle
Normal file
95
build.gradle
Normal file
@@ -0,0 +1,95 @@
|
||||
plugins {
|
||||
id 'fabric-loom' version '1.10-SNAPSHOT'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
version = project.mod_version
|
||||
group = project.maven_group
|
||||
|
||||
base {
|
||||
archivesName = project.archives_base_name
|
||||
}
|
||||
|
||||
|
||||
fabricApi {
|
||||
configureDataGeneration {
|
||||
client = true
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
// Add repositories to retrieve artifacts from in here.
|
||||
// You should only use this when depending on other mods because
|
||||
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
|
||||
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
|
||||
// for more information about repositories.
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// To change the versions see the gradle.properties file
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
inputs.property "minecraft_version", project.minecraft_version
|
||||
inputs.property "loader_version", project.loader_version
|
||||
filteringCharset "UTF-8"
|
||||
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand "version": project.version,
|
||||
"minecraft_version": project.minecraft_version,
|
||||
"loader_version": project.loader_version
|
||||
}
|
||||
}
|
||||
|
||||
def targetJavaVersion = 21
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
// ensure that the encoding is set to UTF-8, no matter what the system default is
|
||||
// this fixes some edge cases with special characters not displaying correctly
|
||||
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
|
||||
// If Javadoc is generated, this must be specified in that task too.
|
||||
it.options.encoding = "UTF-8"
|
||||
if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
|
||||
it.options.release.set(targetJavaVersion)
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
|
||||
if (JavaVersion.current() < javaVersion) {
|
||||
toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
|
||||
}
|
||||
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||||
// if it is present.
|
||||
// If you remove this line, sources will not be generated.
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
jar {
|
||||
from("LICENSE") {
|
||||
rename { "${it}_${project.archivesBaseName}" }
|
||||
}
|
||||
}
|
||||
|
||||
// configure the maven publication
|
||||
publishing {
|
||||
publications {
|
||||
create("mavenJava", MavenPublication) {
|
||||
artifactId = project.archives_base_name
|
||||
from components.java
|
||||
}
|
||||
}
|
||||
|
||||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||
repositories {
|
||||
// Add repositories to publish to here.
|
||||
// Notice: This block does NOT have the same function as the block in the top level.
|
||||
// The repositories here will be used for publishing your artifact, not for
|
||||
// retrieving dependencies.
|
||||
}
|
||||
}
|
||||
14
gradle.properties
Normal file
14
gradle.properties
Normal file
@@ -0,0 +1,14 @@
|
||||
# Done to increase the memory available to gradle.
|
||||
org.gradle.jvmargs=-Xmx1G
|
||||
# Fabric Properties
|
||||
# check these on https://modmuss50.me/fabric.html
|
||||
minecraft_version=1.21.4
|
||||
yarn_mappings=1.21.4+build.8
|
||||
loader_version=0.16.14
|
||||
# Mod Properties
|
||||
mod_version=1.0
|
||||
maven_group=org.walruslab
|
||||
archives_base_name=kepler
|
||||
# Dependencies
|
||||
# check this on https://modmuss50.me/fabric.html
|
||||
fabric_version=0.119.2+1.21.4
|
||||
1
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
1
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1 @@
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||
9
settings.gradle
Normal file
9
settings.gradle
Normal file
@@ -0,0 +1,9 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
maven {
|
||||
name = 'Fabric'
|
||||
url = 'https://maven.fabricmc.net/'
|
||||
}
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
10
src/main/java/org/walruslab/kepler/Kepler.java
Normal file
10
src/main/java/org/walruslab/kepler/Kepler.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package org.walruslab.kepler;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
|
||||
public class Kepler implements ModInitializer {
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
}
|
||||
}
|
||||
17
src/main/java/org/walruslab/kepler/client/KeplerClient.java
Normal file
17
src/main/java/org/walruslab/kepler/client/KeplerClient.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package org.walruslab.kepler.client;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import org.walruslab.kepler.render.TrajectoryRenderer;
|
||||
|
||||
public class KeplerClient implements ClientModInitializer {
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
ClientEntityEvents.ENTITY_LOAD.register((entity, _a) -> {
|
||||
if (entity instanceof PlayerEntity) TrajectoryRenderer.setupRenderLine((PlayerEntity) entity);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.walruslab.kepler.client;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
|
||||
|
||||
public class KeplerDataGenerator implements DataGeneratorEntrypoint {
|
||||
|
||||
@Override
|
||||
public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) {
|
||||
FabricDataGenerator.Pack pack = fabricDataGenerator.createPack();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package org.walruslab.kepler.render;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
||||
import net.jpountz.util.Utils;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gl.ShaderProgramKeys;
|
||||
import net.minecraft.client.render.BufferRenderer;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.VertexFormat;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.ArrowEntity;
|
||||
import net.minecraft.item.BowItem;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.predicate.entity.EntityPredicate;
|
||||
import net.minecraft.predicate.entity.EntityPredicates;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.TypeFilter;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.walruslab.kepler.trajectory.Trajectory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class TrajectoryRenderer {
|
||||
public static void setupRenderLine(PlayerEntity player) {
|
||||
player.sendMessage(Text.of("Kepler: TrajectoryRenderer setupRenderLine"), false);
|
||||
WorldRenderEvents.END.register((drawContext) -> {
|
||||
// get all error entity in player world
|
||||
var world = player.getWorld();
|
||||
var arrows = world.getEntitiesByType(TypeFilter.instanceOf(ArrowEntity.class), new Box(player.getPos().subtract(Vec3d.of(new Vec3i(100, 100, 100))), player.getPos().add(Vec3d.of(new Vec3i(100, 100, 100)))), EntityPredicates.VALID_ENTITY);
|
||||
|
||||
for (ArrowEntity arrow : arrows) {
|
||||
if (arrow.groundCollision) return;
|
||||
|
||||
var pos = arrow.getPos();
|
||||
var velocity = arrow.getVelocity();
|
||||
|
||||
var tr = new Trajectory(pos.toVector3f(), velocity.toVector3f());
|
||||
var hit = tr.getTrajectoryPoints(world, 0.1f, player);
|
||||
var points = hit.points();
|
||||
|
||||
if (points.size() < 2) {
|
||||
continue; // Skip if not enough points
|
||||
}
|
||||
|
||||
// Render the trajectory line
|
||||
if (hit.hitEntity()) {
|
||||
renderLine(drawContext, points, 0.0f, 1.0f, 0.0f); // Red for hit
|
||||
} else {
|
||||
renderLine(drawContext, points, 1.0f, 0.0f, 1.0f); // Green for no hit
|
||||
}
|
||||
}
|
||||
|
||||
var livingEntities = world.getOtherEntities(player, new Box(player.getPos().subtract(Vec3d.of(new Vec3i(100, 100, 100))), player.getPos().add(Vec3d.of(new Vec3i(100, 100, 100)))), EntityPredicates.VALID_ENTITY);
|
||||
for (var entity : livingEntities) {
|
||||
if (entity instanceof ArrowEntity) continue;
|
||||
|
||||
var pos = entity.getPos();
|
||||
var velocity = entity.getVelocity();
|
||||
|
||||
if (velocity.length() < 0.1) continue; // Skip if velocity is too low
|
||||
|
||||
var predictedPos = new Vector3f(
|
||||
(float) (entity.getX() + velocity.x * 20),
|
||||
(float) (entity.getY() + velocity.y * 20),
|
||||
(float) (entity.getZ() + velocity.z * 20)
|
||||
);
|
||||
|
||||
var points = List.of(
|
||||
new Vector3f((float) pos.x, (float) pos.y, (float) pos.z),
|
||||
predictedPos
|
||||
);
|
||||
|
||||
// Render the trajectory line
|
||||
renderLine(drawContext, points, 0.0f, 0.0f, 1.0f); // Blue for entity
|
||||
}
|
||||
|
||||
// check player is shooting bow
|
||||
var activeItem = player.getMainHandStack();
|
||||
if (activeItem != null && (activeItem.isOf(Items.BOW) || activeItem.isOf(Items.CROSSBOW))) {
|
||||
float speed;
|
||||
if (activeItem.isOf(Items.BOW)) {
|
||||
var item = (BowItem) activeItem.getItem();
|
||||
var f = BowItem.getPullProgress(player.getItemUseTime());
|
||||
speed = f * 3.0f;
|
||||
} else {
|
||||
speed = 3.15f;
|
||||
}
|
||||
|
||||
var dirDouble = player.getRotationVec(1.0f);
|
||||
|
||||
var dir = new Vector3f(
|
||||
(float) dirDouble.x,
|
||||
(float) dirDouble.y,
|
||||
(float) dirDouble.z
|
||||
).normalize();
|
||||
|
||||
var pos = player.getEyePos();
|
||||
var playerVelocity = player.getVelocity();
|
||||
|
||||
var velocity = new Vector3f(
|
||||
(float) (dir.x * speed + playerVelocity.x),
|
||||
(float) (dir.y * speed + playerVelocity.y),
|
||||
(float) (dir.z * speed + playerVelocity.z)
|
||||
);
|
||||
|
||||
var tr = new Trajectory(pos.toVector3f(), velocity);
|
||||
var hit = tr.getTrajectoryPoints(world, 0.1f, player);
|
||||
|
||||
var points = hit.points();
|
||||
|
||||
if (points.size() >= 2) {
|
||||
var playerRight = dir.cross(new Vector3f(0, 1, 0)).normalize();
|
||||
// move points to the right, closest point -> move 1, farthest point -> move 0, linear
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
var point = points.get(i);
|
||||
var rightOffset = 0.05;
|
||||
var dx = (float) (point.x + playerRight.x * rightOffset * (1 - ((float) i / points.size())));
|
||||
var dy = (float) (point.y + playerRight.y * rightOffset * (1 - ((float) i / points.size())));
|
||||
var dz = (float) (point.z + playerRight.z * rightOffset * (1 - ((float) i / points.size())));
|
||||
|
||||
points.set(i, new Vector3f(dx, dy, dz));
|
||||
}
|
||||
|
||||
// Render the trajectory line
|
||||
if (hit.hitEntity()) {
|
||||
renderLine(drawContext, points, 0.0f, 1.0f, 0.0f); // Red for hit
|
||||
} else {
|
||||
renderLine(drawContext, points, 1.0f, 0.0f, 1.0f); // Green for no hit
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void renderLine(WorldRenderContext drawContext, List<Vector3f> points, float r, float g, float b) {
|
||||
// enable z-buffer
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.depthFunc(GL11.GL_LEQUAL);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
|
||||
RenderSystem.setShaderColor(r, g, b, 1.0f);
|
||||
|
||||
var tesselator = Tessellator.getInstance();
|
||||
var buf = tesselator.begin(VertexFormat.DrawMode.DEBUG_LINE_STRIP, VertexFormats.POSITION_COLOR);
|
||||
var mat = drawContext.positionMatrix();
|
||||
|
||||
var playerPos = MinecraftClient.getInstance().getCameraEntity().getCameraPosVec(0);
|
||||
|
||||
for (var point: points) {
|
||||
float dx = (float) (point.x - playerPos.x);
|
||||
float dy = (float) (point.y - playerPos.y);
|
||||
float dz = (float) (point.z - playerPos.z);
|
||||
|
||||
buf.vertex(mat, dx, dy, dz);
|
||||
|
||||
buf.color(r, g, b, 1.0f);
|
||||
}
|
||||
|
||||
RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR);
|
||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
BufferRenderer.drawWithGlobalProgram(buf.end());
|
||||
}
|
||||
}
|
||||
142
src/main/java/org/walruslab/kepler/trajectory/Trajectory.java
Normal file
142
src/main/java/org/walruslab/kepler/trajectory/Trajectory.java
Normal file
@@ -0,0 +1,142 @@
|
||||
package org.walruslab.kepler.trajectory;
|
||||
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.decoration.EndCrystalEntity;
|
||||
import net.minecraft.util.Pair;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.RaycastContext;
|
||||
import net.minecraft.world.World;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Trajectory {
|
||||
public final Vector3f position;
|
||||
public final Vector3f velocity;
|
||||
public final float speedMultiplier;
|
||||
public final float gravity;
|
||||
|
||||
public Trajectory(Vector3f position, Vector3f velocity) {
|
||||
this.position = position;
|
||||
this.velocity = velocity;
|
||||
this.speedMultiplier = 0.99f;
|
||||
this.gravity = 1.0f / 20;
|
||||
}
|
||||
|
||||
public Trajectory(Vector3f position, Vector3f velocity, float speedMultiplier, float gravity) {
|
||||
this.position = position;
|
||||
this.velocity = velocity;
|
||||
this.speedMultiplier = speedMultiplier;
|
||||
this.gravity = gravity;
|
||||
}
|
||||
|
||||
public TrajectoryHit getTrajectoryPoints(World world, float density, Entity exclusionEntity) {
|
||||
List<Vector3f> points = new ArrayList<>();
|
||||
Vector3f currentPosition = new Vector3f(position);
|
||||
Vector3f currentVelocity = new Vector3f(velocity);
|
||||
int currentTick = 0;
|
||||
|
||||
while (true) {
|
||||
Vec3d start = new Vec3d(currentPosition.x, currentPosition.y, currentPosition.z);
|
||||
Vec3d end = new Vec3d(currentPosition.x + currentVelocity.x, currentPosition.y + currentVelocity.y, currentPosition.z + currentVelocity.z);
|
||||
|
||||
// get all entities in range of 10 blocks
|
||||
var entities = world.getOtherEntities(null, new Box(start.subtract(100, 100, 100), end.add(100, 100, 100)), entity -> entity instanceof LivingEntity || entity instanceof EndCrystalEntity);
|
||||
for (Entity entity : entities) {
|
||||
if (entity.equals(exclusionEntity)) continue;
|
||||
// check start-end line collides with entity bounding box
|
||||
var bb = entity.getBoundingBox();
|
||||
var entityVelocity = entity.getVelocity();
|
||||
// predict entity position by adding its velocity * seconds(by tick)
|
||||
var curEntityPos = new Vector3f(
|
||||
(float) (entity.getX()),
|
||||
(float) (entity.getY()),
|
||||
(float) (entity.getZ())
|
||||
);
|
||||
var predictEntityPos = new Vector3f(
|
||||
(float) (entity.getX() + entityVelocity.x * currentTick),
|
||||
(float) (entity.getY() + entityVelocity.y * currentTick),
|
||||
(float) (entity.getZ() + entityVelocity.z * currentTick)
|
||||
);
|
||||
var entityStart = new Vec3d(bb.minX, bb.minY, bb.minZ).add(entityVelocity.x * currentTick, entityVelocity.y * currentTick, entityVelocity.z * currentTick);
|
||||
var entityEnd = new Vec3d(bb.maxX, bb.maxY, bb.maxZ).add(entityVelocity.x * currentTick, entityVelocity.y * currentTick, entityVelocity.z * currentTick);
|
||||
var entityBox = new Box(entityStart, entityEnd);
|
||||
if (this.boxIntersectsLine(start, end, entityBox)) {
|
||||
return new TrajectoryHit(points, true); // Hit an entity
|
||||
}
|
||||
}
|
||||
|
||||
var rContext = new RaycastContext(
|
||||
start,
|
||||
end,
|
||||
RaycastContext.ShapeType.COLLIDER,
|
||||
RaycastContext.FluidHandling.NONE,
|
||||
ShapeContext.absent()
|
||||
);
|
||||
|
||||
var hitResult = world.raycast(rContext);
|
||||
if (hitResult.getType() != HitResult.Type.MISS) {
|
||||
// Check if the hit result is a block
|
||||
if (hitResult.getType() == HitResult.Type.BLOCK) {
|
||||
return new TrajectoryHit(points, false); // Hit a block
|
||||
}
|
||||
}
|
||||
|
||||
points.add(new Vector3f(currentPosition));
|
||||
|
||||
// Update position and velocity
|
||||
currentPosition.add(currentVelocity);
|
||||
currentVelocity.y -= gravity; // Apply gravity
|
||||
currentVelocity.mul(speedMultiplier); // Apply speed multiplier
|
||||
currentTick++;
|
||||
|
||||
if (currentTick > 5000 / density) {
|
||||
break; // Prevent infinite loop
|
||||
}
|
||||
}
|
||||
return new TrajectoryHit(points, false); // No hit
|
||||
}
|
||||
|
||||
private boolean boxIntersectsLine(Vec3d start, Vec3d end, Box box) {
|
||||
double tMin = 0.0;
|
||||
double tMax = 1.0;
|
||||
|
||||
double[] startArr = {start.x, start.y, start.z};
|
||||
double[] endArr = {end.x, end.y, end.z};
|
||||
double[] boxMin = {box.minX, box.minY, box.minZ};
|
||||
double[] boxMax = {box.maxX, box.maxY, box.maxZ};
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
double d = endArr[i] - startArr[i];
|
||||
|
||||
if (Math.abs(d) < 1e-8) {
|
||||
if (startArr[i] < boxMin[i] || startArr[i] > boxMax[i]) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
double t1 = (boxMin[i] - startArr[i]) / d;
|
||||
double t2 = (boxMax[i] - startArr[i]) / d;
|
||||
|
||||
if (t1 > t2) {
|
||||
double temp = t1;
|
||||
t1 = t2;
|
||||
t2 = temp;
|
||||
}
|
||||
|
||||
tMin = Math.max(tMin, t1);
|
||||
tMax = Math.min(tMax, t2);
|
||||
|
||||
if (tMin > tMax) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.walruslab.kepler.trajectory;
|
||||
|
||||
import net.minecraft.util.Pair;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record TrajectoryHit(List<Vector3f> points, boolean hitEntity) {
|
||||
}
|
||||
31
src/main/resources/fabric.mod.json
Normal file
31
src/main/resources/fabric.mod.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "kepler",
|
||||
"version": "${version}",
|
||||
"name": "Kepler",
|
||||
"description": "",
|
||||
"authors": [],
|
||||
"contact": {},
|
||||
"license": "All-Rights-Reserved",
|
||||
"icon": "assets/kepler/icon.png",
|
||||
"environment": "client",
|
||||
"entrypoints": {
|
||||
"fabric-datagen": [
|
||||
"org.walruslab.kepler.client.KeplerDataGenerator"
|
||||
],
|
||||
"client": [
|
||||
"org.walruslab.kepler.client.KeplerClient"
|
||||
],
|
||||
"main": [
|
||||
"org.walruslab.kepler.Kepler"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
"kepler.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=${loader_version}",
|
||||
"fabric": "*",
|
||||
"minecraft": "${minecraft_version}"
|
||||
}
|
||||
}
|
||||
13
src/main/resources/kepler.mixins.json
Normal file
13
src/main/resources/kepler.mixins.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "org.walruslab.kepler.mixin",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user