-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9045c93
commit a3e51eb
Showing
8 changed files
with
308 additions
and
16 deletions.
There are no files selected for viewing
83 changes: 83 additions & 0 deletions
83
common/src/main/java/org/valkyrienskies/mod/mixin/feature/ai/MixinDefaultRandomPos.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,83 @@ | ||
package org.valkyrienskies.mod.mixin.feature.ai; | ||
|
||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation; | ||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; | ||
import java.util.function.Supplier; | ||
import net.minecraft.core.BlockPos; | ||
import net.minecraft.world.entity.PathfinderMob; | ||
import net.minecraft.world.entity.ai.util.DefaultRandomPos; | ||
import net.minecraft.world.entity.ai.util.GoalUtils; | ||
import net.minecraft.world.entity.ai.util.RandomPos; | ||
import net.minecraft.world.phys.AABB; | ||
import net.minecraft.world.phys.Vec3; | ||
import org.joml.Vector3d; | ||
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 org.valkyrienskies.core.api.ships.LoadedShip; | ||
import org.valkyrienskies.mod.common.VSGameUtilsKt; | ||
import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; | ||
|
||
/** | ||
* @author Tomato | ||
* Should allow for mobs to pathfind on ships. | ||
*/ | ||
@Mixin(DefaultRandomPos.class) | ||
public class MixinDefaultRandomPos { | ||
@Inject( | ||
method = "generateRandomPosTowardDirection", | ||
at = @At( | ||
value = "HEAD" | ||
), | ||
cancellable = true | ||
) | ||
private static void postGenerateRandomPosTowardDirection(PathfinderMob pathfinderMob, int i, boolean bl, | ||
BlockPos blockPos, final CallbackInfoReturnable<BlockPos> cir) { | ||
if (pathfinderMob.level != null) { | ||
final BlockPos blockPos3 = RandomPos.generateRandomPosTowardDirection(pathfinderMob, i, pathfinderMob.getRandom(), blockPos); | ||
if (blockPos3 == null) { | ||
return; | ||
} | ||
AABB checker = new AABB(blockPos3); | ||
Iterable<LoadedShip> ships = VSGameUtilsKt.getShipObjectWorld(pathfinderMob.level).getLoadedShips().getIntersecting(VectorConversionsMCKt.toJOML(checker), VSGameUtilsKt.getDimensionId(pathfinderMob.level)); | ||
if (ships.iterator().hasNext()) { | ||
for (LoadedShip ship : ships) { | ||
Vector3d posInShip = ship.getWorldToShip() | ||
.transformPosition(VectorConversionsMCKt.toJOMLD(blockPos3), new Vector3d()); | ||
BlockPos blockPosInShip = new BlockPos(VectorConversionsMCKt.toMinecraft(posInShip)); | ||
if (!GoalUtils.isRestricted(bl, pathfinderMob, blockPosInShip) && | ||
!GoalUtils.isNotStable(pathfinderMob.getNavigation(), blockPosInShip) && | ||
!GoalUtils.hasMalus(pathfinderMob, blockPosInShip)) { | ||
cir.setReturnValue(blockPosInShip); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
@WrapOperation(method = "getPosTowards", at = @At(value = "INVOKE", | ||
target = "Lnet/minecraft/world/entity/ai/util/RandomPos;generateRandomPos(Lnet/minecraft/world/entity/PathfinderMob;Ljava/util/function/Supplier;)Lnet/minecraft/world/phys/Vec3;")) | ||
private static Vec3 redirectGetPosInDirection(PathfinderMob arg, Supplier<BlockPos> supplier, | ||
Operation<Vec3> original) { | ||
Vec3 result = original.call(arg, supplier); | ||
if (result != null) { | ||
return VSGameUtilsKt.toWorldCoordinates(arg.level, result); | ||
} | ||
return null; | ||
} | ||
|
||
@WrapOperation(method = "getPos", at = @At(value = "INVOKE", | ||
target = "Lnet/minecraft/world/entity/ai/util/RandomPos;generateRandomPos(Lnet/minecraft/world/entity/PathfinderMob;Ljava/util/function/Supplier;)Lnet/minecraft/world/phys/Vec3;")) | ||
private static Vec3 redirectGetPos(PathfinderMob arg, Supplier<BlockPos> supplier, | ||
Operation<Vec3> original) { | ||
Vec3 result = original.call(arg, supplier); | ||
if (result != null) { | ||
return VSGameUtilsKt.toWorldCoordinates(arg.level, result); | ||
} | ||
return null; | ||
} | ||
|
||
|
||
} |
88 changes: 88 additions & 0 deletions
88
common/src/main/java/org/valkyrienskies/mod/mixin/feature/ai/MixinLandRandomPos.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,88 @@ | ||
package org.valkyrienskies.mod.mixin.feature.ai; | ||
|
||
import static net.minecraft.world.entity.ai.util.LandRandomPos.generateRandomPosTowardDirection; | ||
import static net.minecraft.world.entity.ai.util.LandRandomPos.movePosUpOutOfSolid; | ||
|
||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation; | ||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; | ||
import java.util.function.Supplier; | ||
import java.util.function.ToDoubleFunction; | ||
import net.minecraft.core.BlockPos; | ||
import net.minecraft.world.entity.PathfinderMob; | ||
import net.minecraft.world.entity.ai.util.GoalUtils; | ||
import net.minecraft.world.entity.ai.util.LandRandomPos; | ||
import net.minecraft.world.entity.ai.util.RandomPos; | ||
import net.minecraft.world.phys.AABB; | ||
import net.minecraft.world.phys.Vec3; | ||
import org.joml.Vector3d; | ||
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 org.valkyrienskies.core.api.ships.LoadedShip; | ||
import org.valkyrienskies.mod.common.VSGameUtilsKt; | ||
import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; | ||
|
||
/** | ||
* @author Tomato | ||
* Should allow for mobs to pathfind on ships. | ||
*/ | ||
@Mixin(LandRandomPos.class) | ||
public class MixinLandRandomPos { | ||
|
||
@Inject( | ||
method = "generateRandomPosTowardDirection", | ||
at = @At( | ||
value = "HEAD" | ||
), | ||
cancellable = true | ||
) | ||
private static void postGenerateRandomPosTowardDirection(PathfinderMob pathfinderMob, int i, boolean bl, | ||
BlockPos blockPos, CallbackInfoReturnable<BlockPos> cir) { | ||
if (pathfinderMob.level != null) { | ||
final BlockPos blockPos3 = RandomPos.generateRandomPosTowardDirection(pathfinderMob, i, pathfinderMob.getRandom(), blockPos); | ||
AABB checker = new AABB(blockPos3); | ||
Iterable<LoadedShip> ships = VSGameUtilsKt.getShipObjectWorld(pathfinderMob.level).getLoadedShips().getIntersecting(VectorConversionsMCKt.toJOML(checker), VSGameUtilsKt.getDimensionId(pathfinderMob.level)); | ||
if (ships.iterator().hasNext()) { | ||
for (LoadedShip ship : ships) { | ||
Vector3d posInShip = ship.getWorldToShip() | ||
.transformPosition(VectorConversionsMCKt.toJOMLD(blockPos3), new Vector3d()); | ||
BlockPos blockPosInShip = new BlockPos(VectorConversionsMCKt.toMinecraft(posInShip)); | ||
if (!GoalUtils.isRestricted(bl, pathfinderMob, blockPosInShip) && | ||
!GoalUtils.isNotStable(pathfinderMob.getNavigation(), blockPosInShip) && | ||
!GoalUtils.hasMalus(pathfinderMob, blockPosInShip)) { | ||
cir.setReturnValue(blockPosInShip); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
@WrapOperation(method = "getPosInDirection", at = @At(value = "INVOKE", | ||
target = "Lnet/minecraft/world/entity/ai/util/RandomPos;generateRandomPos(Lnet/minecraft/world/entity/PathfinderMob;Ljava/util/function/Supplier;)Lnet/minecraft/world/phys/Vec3;")) | ||
private static Vec3 redirectGetPosInDirection(PathfinderMob arg, Supplier<BlockPos> supplier, | ||
Operation<Vec3> original) { | ||
Vec3 result = original.call(arg, supplier); | ||
if (result != null) { | ||
return VSGameUtilsKt.toWorldCoordinates(arg.level, result); | ||
} | ||
return null; | ||
} | ||
|
||
@Inject(method = "getPos(Lnet/minecraft/world/entity/PathfinderMob;IILjava/util/function/ToDoubleFunction;)Lnet/minecraft/world/phys/Vec3;", at = @At("HEAD"), cancellable = true) | ||
private static void preGetPos(PathfinderMob pathfinderMob, int i, int j, | ||
ToDoubleFunction<BlockPos> toDoubleFunction, CallbackInfoReturnable<Vec3> cir) { | ||
boolean bl = GoalUtils.mobRestricted(pathfinderMob, i); | ||
Vec3 randomPos = RandomPos.generateRandomPos(() -> { | ||
BlockPos blockPos = RandomPos.generateRandomDirection(pathfinderMob.getRandom(), i, j); | ||
BlockPos blockPos2 = generateRandomPosTowardDirection(pathfinderMob, i, bl, blockPos); | ||
return blockPos2 == null ? null : movePosUpOutOfSolid(pathfinderMob, blockPos2); | ||
}, toDoubleFunction); | ||
|
||
if (randomPos != null) { | ||
cir.setReturnValue(VSGameUtilsKt.toWorldCoordinates(pathfinderMob.level, randomPos)); | ||
} | ||
cir.setReturnValue(null); | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
common/src/main/java/org/valkyrienskies/mod/mixin/feature/ai/MixinPOIManager.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,77 @@ | ||
package org.valkyrienskies.mod.mixin.feature.ai; | ||
|
||
import java.util.function.Predicate; | ||
import java.util.stream.Stream; | ||
import net.minecraft.core.BlockPos; | ||
import net.minecraft.world.entity.ai.village.poi.PoiManager; | ||
import net.minecraft.world.entity.ai.village.poi.PoiManager.Occupancy; | ||
import net.minecraft.world.entity.ai.village.poi.PoiRecord; | ||
import net.minecraft.world.entity.ai.village.poi.PoiType; | ||
import net.minecraft.world.level.ChunkPos; | ||
import net.minecraft.world.level.Level; | ||
import net.minecraft.world.phys.AABB; | ||
import net.minecraft.world.phys.Vec3; | ||
import org.joml.Vector4ic; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Overwrite; | ||
import org.spongepowered.asm.mixin.Shadow; | ||
import org.spongepowered.asm.mixin.Unique; | ||
import org.valkyrienskies.core.api.ships.LoadedShip; | ||
import org.valkyrienskies.mod.common.VSGameUtilsKt; | ||
import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; | ||
import org.valkyrienskies.mod.common.world.POIChunkSearcher; | ||
import org.valkyrienskies.mod.mixinducks.world.OfLevel; | ||
|
||
/** | ||
* @author Tomato | ||
* This atrocious mess of a mixin allows POIs in ship space to be detected, however it requires further mixins to Goals for the ship space positions to be correctly used, from what I can understand. | ||
*/ | ||
@Mixin(PoiManager.class) | ||
public abstract class MixinPOIManager implements OfLevel { | ||
|
||
@Unique | ||
private Level valkyrienskies$sLevel; | ||
|
||
@Shadow | ||
public abstract Stream<PoiRecord> getInChunk(Predicate<PoiType> predicate, ChunkPos chunkPos, Occupancy occupancy); | ||
|
||
/** | ||
* @author Tomato | ||
* @reason Allows for ships to be considered as a valid POI, also this method sucks anyway. | ||
*/ | ||
@Overwrite | ||
public Stream<PoiRecord> getInSquare(Predicate<PoiType> predicate, BlockPos blockPos, int i, Occupancy occupancy) { | ||
int j = Math.floorDiv(i, 16) + 1; | ||
final AABB aABB = new AABB(blockPos).inflate((double) j +1); | ||
Stream<ChunkPos> chunkRange = ChunkPos.rangeClosed(new ChunkPos(blockPos), j); | ||
Stream<PoiRecord> shipPOIs = Stream.empty(); | ||
if (this.valkyrienskies$sLevel != null) { | ||
for (LoadedShip ship : VSGameUtilsKt.getShipObjectWorld(this.valkyrienskies$sLevel).getLoadedShips().getIntersecting( | ||
VectorConversionsMCKt.toJOML(aABB), VSGameUtilsKt.getDimensionId(this.valkyrienskies$sLevel))) { | ||
Vector4ic chunkRangeBounds = POIChunkSearcher.INSTANCE.shipChunkBounds(ship.getActiveChunksSet()); | ||
ChunkPos.rangeClosed(new ChunkPos(chunkRangeBounds.x(), chunkRangeBounds.z()), | ||
new ChunkPos(chunkRangeBounds.y(), chunkRangeBounds.w())).flatMap((chunkPos) -> this.getInChunk(predicate, chunkPos, occupancy)).filter((poiRecord) -> { | ||
BlockPos blockPos2 = poiRecord.getPos(); | ||
Vec3 vecPos = new Vec3(blockPos2.getX(), blockPos2.getY(), blockPos2.getZ()); | ||
VSGameUtilsKt.toWorldCoordinates(this.valkyrienskies$sLevel, vecPos); | ||
return Math.abs(vecPos.x() - blockPos.getX()) <= i && Math.abs(vecPos.z() - blockPos.getZ()) <= i; | ||
});; | ||
} | ||
} | ||
final Stream<PoiRecord> worldPOIs = chunkRange.flatMap((chunkPos) -> this.getInChunk(predicate, chunkPos, occupancy)).filter((poiRecord) -> { | ||
BlockPos blockPos2 = poiRecord.getPos(); | ||
return Math.abs(blockPos2.getX() - blockPos.getX()) <= i && Math.abs(blockPos2.getZ() - blockPos.getZ()) <= i; | ||
}); | ||
return Stream.concat(worldPOIs, shipPOIs); | ||
} | ||
|
||
@Override | ||
public Level getLevel() { | ||
return valkyrienskies$sLevel; | ||
} | ||
|
||
@Override | ||
public void setLevel(Level level) { | ||
valkyrienskies$sLevel = level; | ||
} | ||
} |
8 changes: 0 additions & 8 deletions
8
...n/java/org/valkyrienskies/mod/mixin/feature/ai/goal_redirector/MixinRandomStrollGoal.java
This file was deleted.
Oops, something went wrong.
8 changes: 0 additions & 8 deletions
8
...lkyrienskies/mod/mixin/feature/ai/goal_redirector/MixinWaterAvoidingRandomStrollGoal.java
This file was deleted.
Oops, something went wrong.
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
47 changes: 47 additions & 0 deletions
47
common/src/main/kotlin/org/valkyrienskies/mod/common/world/POIChunkSearcher.kt
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,47 @@ | ||
package org.valkyrienskies.mod.common.world | ||
|
||
import net.minecraft.server.level.ServerLevel | ||
import net.minecraft.world.entity.ai.village.poi.PoiRecord | ||
import net.minecraft.world.level.ChunkPos | ||
import net.minecraft.world.level.Level | ||
import net.minecraft.world.phys.AABB | ||
import net.minecraft.world.phys.Vec3 | ||
import org.joml.Vector4i | ||
import org.joml.Vector4ic | ||
import org.valkyrienskies.core.api.ships.LoadedServerShip | ||
import org.valkyrienskies.core.api.ships.QueryableShipData | ||
import org.valkyrienskies.core.api.ships.properties.IShipActiveChunksSet | ||
import org.valkyrienskies.core.impl.chunk_tracking.ShipActiveChunksSet | ||
import org.valkyrienskies.mod.common.dimensionId | ||
import org.valkyrienskies.mod.common.getShipObjectManagingPos | ||
import org.valkyrienskies.mod.common.shipObjectWorld | ||
import org.valkyrienskies.mod.common.util.toJOML | ||
import org.valkyrienskies.mod.common.util.toMinecraft | ||
|
||
object POIChunkSearcher { | ||
fun shipChunkBounds(chunkSet: IShipActiveChunksSet): Vector4ic { | ||
var minChunkX = Integer.MIN_VALUE | ||
var minChunkZ = Integer.MIN_VALUE | ||
var maxChunkX = Integer.MAX_VALUE | ||
var maxChunkZ = Integer.MAX_VALUE | ||
chunkSet.forEach { chunkX, chunkZ -> | ||
minChunkX = minChunkX.coerceAtLeast(chunkX) | ||
minChunkZ = minChunkZ.coerceAtLeast(chunkZ) | ||
maxChunkX = maxChunkX.coerceAtMost(chunkX) | ||
maxChunkZ = maxChunkZ.coerceAtMost(chunkZ) | ||
} | ||
return Vector4i(minChunkX, minChunkZ, maxChunkX, maxChunkZ) | ||
} | ||
|
||
fun PoiRecord.getWorldPos(level: Level): Vec3 { | ||
val blockPos = this.pos | ||
val vecPos = Vec3(blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble()) | ||
if (level.shipObjectWorld.isBlockInShipyard(blockPos.x, blockPos.y, blockPos.z, level.dimensionId)) { | ||
val ship = level.getShipObjectManagingPos(blockPos) | ||
if (ship != null) { | ||
return ship.shipToWorld.transformPosition(vecPos.toJOML()).toMinecraft() | ||
} | ||
} | ||
return vecPos | ||
} | ||
} |
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