Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(utils): move ray trace utils from EntityUtils to a separate …
…class
- Loading branch information
1 parent
b89379a
commit 0ef6e68
Showing
2 changed files
with
181 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
src/main/java/org/auioc/mcmod/arnicalib/utils/game/RayTraceUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package org.auioc.mcmod.arnicalib.utils.game; | ||
|
||
import java.util.Optional; | ||
import java.util.function.Function; | ||
import java.util.function.Predicate; | ||
import javax.annotation.Nullable; | ||
import net.minecraft.world.entity.Entity; | ||
import net.minecraft.world.entity.EntitySelector; | ||
import net.minecraft.world.entity.LivingEntity; | ||
import net.minecraft.world.level.ClipContext; | ||
import net.minecraft.world.level.Level; | ||
import net.minecraft.world.phys.AABB; | ||
import net.minecraft.world.phys.BlockHitResult; | ||
import net.minecraft.world.phys.EntityHitResult; | ||
import net.minecraft.world.phys.HitResult; | ||
import net.minecraft.world.phys.Vec3; | ||
|
||
public class RayTraceUtils { | ||
|
||
public static Vec3[] getEntityViewRay(Entity entity, double rayLength) { | ||
Vec3 entityViewVector = entity.getViewVector(1.0F); | ||
Vec3 rayPath = entityViewVector.scale(rayLength); | ||
Vec3 from = entity.getEyePosition(1.0F); | ||
Vec3 to = from.add(rayPath); | ||
return new Vec3[] {from, to}; | ||
} | ||
|
||
@Nullable | ||
public static EntityHitResult getEntityHitResult(Level level, Entity entity, Vec3 from, Vec3 to, AABB aabb, Predicate<Entity> predicate, float pickRadiusAddition) { | ||
double d0 = Double.MAX_VALUE; | ||
Entity targetEntity = null; | ||
|
||
for (Entity entity1 : level.getEntities(targetEntity, aabb, predicate)) { | ||
AABB entity1aabb = entity1.getBoundingBox().inflate((double) (entity1.getPickRadius() + pickRadiusAddition)); | ||
Optional<Vec3> optional = entity1aabb.clip(from, to); | ||
if (optional.isPresent()) { | ||
double d1 = from.distanceToSqr(optional.get()); | ||
if (d1 < d0) { | ||
targetEntity = entity1; | ||
d0 = d1; | ||
} | ||
} | ||
} | ||
|
||
return targetEntity == null ? null : new EntityHitResult(targetEntity); | ||
} | ||
|
||
|
||
|
||
public static BlockHitResult getBlockHitResult(Entity entity, double rayLength, ClipContext.Block blockMode, ClipContext.Fluid fluidMode) { | ||
Vec3[] viewRay = getEntityViewRay(entity, rayLength); | ||
ClipContext rayCtx = new ClipContext(viewRay[0], viewRay[1], blockMode, fluidMode, entity); | ||
return entity.level.clip(rayCtx); | ||
} | ||
|
||
@Nullable | ||
public static EntityHitResult getEntityHitResult(Entity entity, double rayLength, float pickRadiusAddition, boolean blockMode) { | ||
Vec3[] viewRay = getEntityViewRay(entity, rayLength); | ||
|
||
Vec3 to = viewRay[1]; | ||
if (blockMode) { | ||
BlockHitResult rayHitBlock = getBlockHitResult(entity, rayLength, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE); | ||
if (rayHitBlock.getType() != HitResult.Type.MISS) { | ||
to = rayHitBlock.getLocation(); | ||
} | ||
} | ||
|
||
return getEntityHitResult(entity, viewRay[0], to, pickRadiusAddition); | ||
} | ||
|
||
|
||
|
||
@Nullable | ||
public static EntityHitResult getEntityHitResult(Entity entity, Vec3 from, Vec3 to, float pickRadiusAddition) { | ||
return getEntityHitResult(entity.level, entity, from, to, entity.getBoundingBox().expandTowards(to).inflate(1.0D), EntitySelector.NO_SPECTATORS, pickRadiusAddition); | ||
} | ||
|
||
@Nullable | ||
public static EntityHitResult getEntityHitResult(Entity entity, Vec3 from, Vec3 to) { | ||
return getEntityHitResult(entity, from, to, 0.0F); | ||
} | ||
|
||
|
||
public static BlockHitResult getBlockHitResult(Entity entity, double rayLength) { | ||
return getBlockHitResult(entity, rayLength, ClipContext.Block.OUTLINE, ClipContext.Fluid.ANY); | ||
} | ||
|
||
public static EntityHitResult getEntityHitResult(Entity entity, double rayLength) { | ||
return getEntityHitResult(entity, rayLength, 0.0F, false); | ||
} | ||
|
||
|
||
|
||
public static int rayHitEntityOrBlockOrMiss( | ||
Entity entity, double rayLength, | ||
float pickRadiusAddition, ClipContext.Block blockMode, ClipContext.Fluid fluidMode, | ||
Function<EntityHitResult, Integer> e, Function<BlockHitResult, Integer> b, Function<BlockHitResult, Integer> m | ||
) { | ||
EntityHitResult rayHitEntity = getEntityHitResult(entity, rayLength, pickRadiusAddition, false); | ||
if (rayHitEntity != null) { | ||
return e.apply(rayHitEntity); | ||
} | ||
|
||
BlockHitResult rayHitBlock = getBlockHitResult(entity, rayLength, blockMode, fluidMode); | ||
if (rayHitBlock.getType() != HitResult.Type.MISS) { | ||
return b.apply(rayHitBlock); | ||
} else { | ||
return m.apply(rayHitBlock); | ||
} | ||
} | ||
|
||
public static int rayHitEntityOrBlock(Entity entity, double rayLength, Function<EntityHitResult, Integer> e, Function<BlockHitResult, Integer> b) { | ||
return rayHitEntityOrBlockOrMiss(entity, rayLength, 0.0F, ClipContext.Block.OUTLINE, ClipContext.Fluid.ANY, e, b, m -> 0); | ||
} | ||
|
||
public static int rayHitLivingEntityOrBlock(Entity entity, double rayLength, Function<EntityHitResult, Integer> e, Function<BlockHitResult, Integer> b) { | ||
return rayHitEntityOrBlock( | ||
entity, rayLength, | ||
(r) -> { | ||
if (r.getEntity() instanceof LivingEntity) { | ||
return e.apply(r); | ||
} else { | ||
return 0; | ||
} | ||
}, b | ||
); | ||
} | ||
|
||
} |