Skip to content

Commit

Permalink
Merge branch '1.18.x/main' into schematic-on-ship
Browse files Browse the repository at this point in the history
  • Loading branch information
ewoudje authored Feb 28, 2024
2 parents 9d1b6ed + 1705b55 commit 6801f8b
Show file tree
Hide file tree
Showing 22 changed files with 761 additions and 139 deletions.
3 changes: 3 additions & 0 deletions common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ dependencies {
modCompileOnly("com.jozufozu.flywheel:flywheel-fabric-${minecraft_version}:${flywheel_version_fabric}")
modCompileOnly("io.github.fabricators_of_create:Porting-Lib:${port_lib_version}+${minecraft_version}")
modCompileOnly("com.rbasamoyai:createbigcannons-fabric-${minecraft_version}:${createbigcannons_version}")

//Bluemap fabric 1.18
modCompileOnly("curse.maven:bluemap-406463:4950063")
}

architectury {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.spongepowered.asm.mixin.Mixins;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import org.spongepowered.asm.service.MixinService;
import org.valkyrienskies.mod.compat.VSRenderer;

/**
Expand Down Expand Up @@ -72,6 +73,15 @@ public boolean shouldApplyMixin(final String s, final String mixinClassName) {
if (mixinClassName.contains("org.valkyrienskies.mod.mixin.feature.render_pathfinding")) {
return PATH_FINDING_DEBUG;
}
if (mixinClassName.contains("org.valkyrienskies.mod.mixin.mod_compat.create.client.trackOutlines")) {
//interactive has its own track outline stuff so disable fixed version of VS2's track outline stuff
if (classExists("org.valkyrienskies.create_interactive.mixin.client.MixinTrackBlockOutline")) {
MixinService.getService().getLogger("mixin")
.info("[VS2] found Interactive, disabling VS2's trackOutline Compat - " +
mixinClassName.substring(mixinClassName.lastIndexOf(".") + 1));
return false;
}
}

return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,50 +1,37 @@
package org.valkyrienskies.mod.mixin.feature.block_placement_orientation;

import net.minecraft.world.InteractionResult;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import org.valkyrienskies.mod.common.PlayerUtil;

@Mixin(BlockItem.class)
public abstract class MixinBlockItem {

@Inject(
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/item/BlockItem;getPlacementState(Lnet/minecraft/world/item/context/BlockPlaceContext;)Lnet/minecraft/world/level/block/state/BlockState;"
),
method = "place",
locals = LocalCapture.CAPTURE_FAILHARD
)
private void transformPlayerWhenPlacing(final BlockPlaceContext ignore,
final CallbackInfoReturnable<InteractionResult> cir, final BlockPlaceContext context) {
if (context == null || context.getPlayer() == null) {
return;
}

PlayerUtil.transformPlayerTemporarily(context.getPlayer(), context.getLevel(), context.getClickedPos());
}

@Inject(
@WrapOperation(
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/world/item/BlockItem;getPlacementState(Lnet/minecraft/world/item/context/BlockPlaceContext;)Lnet/minecraft/world/level/block/state/BlockState;",
shift = Shift.AFTER
target = "Lnet/minecraft/world/item/BlockItem;getPlacementState(Lnet/minecraft/world/item/context/BlockPlaceContext;)Lnet/minecraft/world/level/block/state/BlockState;"
),
method = "place"
)
private void untransformPlayerAfterPlacing(final BlockPlaceContext context,
final CallbackInfoReturnable<InteractionResult> cir) {
if (context.getPlayer() == null) {
return;
private BlockState transformPlayerWhenPlacing(
final BlockItem _instance, final BlockPlaceContext _ctx,
final Operation<BlockState> original, final BlockPlaceContext ctx
) {
if (ctx == null || ctx.getPlayer() == null) {
return null;
}

PlayerUtil.untransformPlayer(context.getPlayer());
return PlayerUtil.transformPlayerTemporarily(
ctx.getPlayer(),
ctx.getLevel(),
ctx.getClickedPos(),
() -> original.call(this, ctx)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.valkyrienskies.mod.mixin.mod_compat.bluemap;

import de.bluecolored.bluemap.core.map.hires.HiresTileModel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(HiresTileModel.class)
@Pseudo
public interface HiresTileModelAccessor {

@Accessor("position")
double[] getPositions();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.valkyrienskies.mod.mixin.mod_compat.bluemap;

import com.flowpowered.math.vector.Vector2i;
import de.bluecolored.bluemap.core.map.BmMap;
import de.bluecolored.bluemap.core.map.hires.HiresModelManager;
import de.bluecolored.bluemap.core.world.World;
import java.util.function.Predicate;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.valkyrienskies.mod.common.VSGameUtilsKt;
import org.valkyrienskies.mod.mixinducks.mod_compat.bluemap.WorldDuck;

@Mixin(BmMap.class)
@Pseudo
public class MixinBmMap {
@Shadow
@Final
private World world;

@Shadow
@Final
private HiresModelManager hiresModelManager;

@Redirect(
method = "renderTile",
at = @At(
value = "INVOKE",
target = "Ljava/util/function/Predicate;test(Ljava/lang/Object;)Z"
),
remap = false
)
boolean skipShipyard(final Predicate<Object> predicate, final Object object) {
final Vector2i tilePos = (Vector2i) object;
final var level = ((WorldDuck) world).valkyrienskies$getCorrelatingLevel();
final var grid = this.hiresModelManager.getTileGrid();
final var x = grid.getCellMinX(tilePos.getX()) + 1;
final var z = grid.getCellMinY(tilePos.getY()) + 1;

final var notShipyard = !VSGameUtilsKt.isBlockInShipyard(level, x, 0, z);

return predicate.test(tilePos) && notShipyard;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package org.valkyrienskies.mod.mixin.mod_compat.bluemap;

import com.flowpowered.math.vector.Vector3i;
import de.bluecolored.bluemap.core.map.TileMetaConsumer;
import de.bluecolored.bluemap.core.map.hires.HiresModelManager;
import de.bluecolored.bluemap.core.map.hires.HiresModelRenderer;
import de.bluecolored.bluemap.core.map.hires.HiresTileModel;
import de.bluecolored.bluemap.core.world.World;
import org.joml.Matrix4dc;
import org.joml.Vector3d;
import org.joml.Vector3dc;
import org.joml.primitives.AABBd;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.valkyrienskies.core.api.ships.Ship;
import org.valkyrienskies.mod.common.VSGameUtilsKt;
import org.valkyrienskies.mod.mixinducks.mod_compat.bluemap.WorldDuck;

@Pseudo
@Mixin(HiresModelManager.class)
public class MixinHiresModelManager {

@Redirect(
remap = false,
method = "render",
at = @At(value = "INVOKE", target = "Lde/bluecolored/bluemap/core/map/hires/HiresModelRenderer;render(Lde/bluecolored/bluemap/core/world/World;Lcom/flowpowered/math/vector/Vector3i;Lcom/flowpowered/math/vector/Vector3i;Lde/bluecolored/bluemap/core/map/hires/HiresTileModel;Lde/bluecolored/bluemap/core/map/TileMetaConsumer;)V")
)
void renderModel(final HiresModelRenderer instance, final World world,
final Vector3i min, final Vector3i max,
final HiresTileModel model, final TileMetaConsumer tmc
) {
final var aabb = new AABBd(
min.getX(), min.getY(), min.getZ(),
max.getX(), max.getY(), max.getZ()
);

final var level = ((WorldDuck) world).valkyrienskies$getCorrelatingLevel();
if (level == null) {
System.out.println("Valkyrien Skies x BlueMap: Could not find correlating level for bluemap world");
return;
}

//TODO we are begging the gods to not have race conditions here
final var ships = VSGameUtilsKt.getShipsIntersecting(level, aabb);

var start = model.size();

for (final Ship ship : ships) {
if (!aabb.containsPoint(ship.getTransform().getPositionInWorld())) continue;
final var shipAABB = ship.getShipAABB();

assert shipAABB != null;
final var shipMin = new Vector3i(shipAABB.minX() - 1, shipAABB.minY() - 1, shipAABB.minZ() - 1);
final var shipMax = new Vector3i(shipAABB.maxX() + 1, shipAABB.maxY() + 1, shipAABB.maxZ() + 1);


// renders the ship with as origin shipMin.x, 0, shipMin.z
instance.render(world, shipMin, shipMax, model, tmc);

final var preTranslation = new Vector3d(
shipMin.getX(),
0,
shipMin.getZ()
);

final var postTranslation = new Vector3d(
-min.getX(),
0,
-min.getZ()
);

valkyrienskies$transformModel(start, model.size(), model, preTranslation, postTranslation, ship.getTransform().getShipToWorld());

start = model.size();
}


instance.render(world, min, max, model, tmc);
}

@Unique
private void valkyrienskies$transformModel(final int start, final int end, final HiresTileModel model, final Vector3dc preTranslation, final Vector3dc postTranslation, final Matrix4dc transform) {
final var positions = ((HiresTileModelAccessor) model).getPositions();

for(int face = start; face < end; ++face) {
for(int i = 0; i < 3; ++i) {
final int index = face * 9 + i * 3;
final double x = positions[index] + preTranslation.x();
final double y = positions[index + 1] + preTranslation.y();
final double z = positions[index + 2] + preTranslation.z();
positions[index] = (x * transform.m00()) + (y * transform.m10()) + (z * transform.m20()) + transform.m30() + postTranslation.x();
positions[index + 1] = (x * transform.m01()) + (y * transform.m11()) + (z * transform.m21()) + transform.m31() + postTranslation.y();
positions[index + 2] = (x * transform.m02()) + (y * transform.m12()) + (z * transform.m22()) + transform.m32() + postTranslation.z();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.valkyrienskies.mod.mixin.mod_compat.bluemap;

import de.bluecolored.bluemap.core.mca.MCAWorld;
import java.nio.file.Path;
import java.util.Objects;
import net.minecraft.world.level.Level;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.Shadow;
import org.valkyrienskies.mod.common.ValkyrienSkiesMod;
import org.valkyrienskies.mod.mixin.server.MinecraftServerAccessor;
import org.valkyrienskies.mod.mixinducks.mod_compat.bluemap.WorldDuck;

@Mixin(MCAWorld.class)
@Pseudo
public class MixinWorld implements WorldDuck {

@Shadow
@Final
private Path worldFolder;

@Override
public Level valkyrienskies$getCorrelatingLevel() {
for (final var level : Objects.requireNonNull(ValkyrienSkiesMod.getCurrentServer()).getAllLevels()) {
final MinecraftServerAccessor accessor = (MinecraftServerAccessor) ValkyrienSkiesMod.getCurrentServer();

final Path path1 = accessor.getStorageSource().getDimensionPath(level.dimension()).toAbsolutePath().normalize();
final Path path2 = this.worldFolder.toAbsolutePath().normalize();
if (path1.equals(path2))
return level;
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.valkyrienskies.mod.mixin.mod_compat.create.accessors;

import com.simibubi.create.content.logistics.chute.ChuteBlockEntity;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;

@Mixin(ChuteBlockEntity.class)
public interface ChuteBlockEntityAccessor {
@Accessor("bottomPullDistance")
float getBottomPullDistance();

@Invoker
boolean callCanAcceptItem(ItemStack item);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.valkyrienskies.mod.mixin.mod_compat.create.blockentity;

import com.simibubi.create.content.logistics.chute.ChuteBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
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.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import org.valkyrienskies.core.api.ships.ServerShip;
import org.valkyrienskies.mod.common.VSGameUtilsKt;
import org.valkyrienskies.mod.mixin.mod_compat.create.accessors.ChuteBlockEntityAccessor;

@Mixin(ChuteBlockEntity.class)
public class MixinChuteBlockEntity {
@Inject(method = "findEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/phys/AABB;<init>(Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;)V", shift = Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true, remap = false)
private void preFindEntities(float itemSpeed, CallbackInfo ci, Vec3 center) {
if (((ChuteBlockEntity) (Object) this).getLevel() != null) {

final ChuteBlockEntity be = (ChuteBlockEntity) (Object) this;
final ChuteBlockEntityAccessor bea = (ChuteBlockEntityAccessor) be;
Level level = ((ChuteBlockEntity) (Object) this).getLevel();

BlockPos pos = be.getBlockPos();

AABB searchArea = new AABB(center.add(0, -bea.getBottomPullDistance() - 0.5, 0), center.add(0, -0.5, 0)).inflate(.45f);

if (VSGameUtilsKt.getShipObjectManagingPos(level, pos) instanceof ServerShip ship) {
Vector3d searchAreaMin = new Vector3d(searchArea.minX, searchArea.minY, searchArea.minZ);
Vector3d searchAreaMax = new Vector3d(searchArea.maxX, searchArea.maxY, searchArea.maxZ);

Vector3d searchAreaReturnMin = new Vector3d();
Vector3d searchAreaReturnMax = new Vector3d();

ship.getTransform().getShipToWorld().transformAab(searchAreaMin, searchAreaMax, searchAreaReturnMin, searchAreaReturnMax);

searchArea = new AABB(searchAreaReturnMin.x, searchAreaReturnMin.y, searchAreaReturnMin.z, searchAreaReturnMax.x, searchAreaReturnMax.y, searchAreaReturnMax.z);

for (ItemEntity itemEntity : level.getEntitiesOfClass(ItemEntity.class, searchArea)) {
if (!itemEntity.isAlive())
continue;
ItemStack entityItem = itemEntity.getItem();
if (!bea.callCanAcceptItem(entityItem))
continue;
be.setItem(entityItem.copy(), (float) (itemEntity.getBoundingBox()
.getCenter().y - be.getBlockPos().getY()));
itemEntity.discard();
break;
}
ci.cancel();
}
}
}
}
Loading

0 comments on commit 6801f8b

Please sign in to comment.