添加ProjectileUtil对于obb entity的检测

This commit is contained in:
17146 2025-06-15 19:38:28 +08:00 committed by Light_Quanta
parent 5d90e12169
commit 07f7710103
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
3 changed files with 60 additions and 7 deletions

View file

@ -0,0 +1,45 @@
package com.atsuishio.superbwarfare.mixins;
import com.atsuishio.superbwarfare.entity.OBBEntity;
import com.atsuishio.superbwarfare.tools.OBB;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.projectile.ProjectileUtil;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.Vec3;
import org.joml.Vector3f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
import java.util.function.Predicate;
@Mixin(ProjectileUtil.class)
public class ProjectileUtilMixin {
@Inject(method = "getEntityHitResult(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/AABB;Ljava/util/function/Predicate;F)Lnet/minecraft/world/phys/EntityHitResult;",
at = @At("RETURN"), cancellable = true)
private static void getEntityHitResult(Level pLevel, Entity pProjectile, Vec3 pStartVec, Vec3 pEndVec, AABB pBoundingBox, Predicate<Entity> pFilter, float pInflationAmount, CallbackInfoReturnable<EntityHitResult> cir) {
Entity res = null;
for (var entity : pLevel.getEntities(pProjectile, pBoundingBox, pFilter)) {
if (entity instanceof OBBEntity obbEntity) {
OBB obb = obbEntity.getOBB().inflate(pInflationAmount * 2);
Optional<Vector3f> optional = obb.clip(pStartVec.toVector3f(), pEndVec.toVector3f());
if (optional.isPresent()) {
double d1 = pStartVec.distanceToSqr(new Vec3(optional.get()));
if (d1 < Double.MAX_VALUE) {
res = entity;
}
if (res != null) {
cir.setReturnValue(new EntityHitResult(res, new Vec3(optional.get())));
}
}
}
}
}
}

View file

@ -185,14 +185,11 @@ public record OBB(Vector3f center, Vector3f extents, Quaternionf rotation) {
}
// 检查是否有有效交点
if (tEnter >= 0 && tEnter <= 1) {
// 计算局部坐标系中的交点
Vector3f localHit = new Vector3f(dir).mul((float) tEnter).add(localFrom);
// 转换回世界坐标系
return Optional.of(localToWorld(localHit, axes));
}
return Optional.empty();
}
// 世界坐标转局部坐标
@ -213,4 +210,14 @@ public record OBB(Vector3f center, Vector3f extents, Quaternionf rotation) {
result.add(axes[2].mul(localPoint.z, new Vector3f()));
return result;
}
public OBB inflate(float amount) {
Vector3f newExtents = new Vector3f(extents).add(amount, amount, amount);
return new OBB(center, newExtents, rotation);
}
public OBB inflate(float x, float y, float z) {
Vector3f newExtents = new Vector3f(extents).add(x, y, z);
return new OBB(center, newExtents, rotation);
}
}

View file

@ -11,6 +11,7 @@
"LevelMixin",
"LivingEntityMixin",
"PlayerMixin",
"ProjectileUtilMixin",
"VillagerMixin"
],
"client": [