Skip to content

Commit

Permalink
Bluemap Compat (#703)
Browse files Browse the repository at this point in the history
  • Loading branch information
ewoudje authored Feb 24, 2024
1 parent 6754162 commit 1705b55
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 0 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
@@ -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,13 @@
package org.valkyrienskies.mod.mixin.server;

import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.storage.LevelStorageSource;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(MinecraftServer.class)
public interface MinecraftServerAccessor {

@Accessor("storageSource")
LevelStorageSource.LevelStorageAccess getStorageSource();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.valkyrienskies.mod.mixinducks.mod_compat.bluemap;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;

public interface WorldDuck {

Level valkyrienskies$getCorrelatingLevel();

}
5 changes: 5 additions & 0 deletions common/src/main/resources/valkyrienskies-common.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
"feature.water_in_ships_entity.MixinEntity",
"feature.world_border.MixinLevel",
"feature.world_border.MixinWorldBorder",
"mod_compat.bluemap.HiresTileModelAccessor",
"mod_compat.bluemap.MixinBmMap",
"mod_compat.bluemap.MixinHiresModelManager",
"mod_compat.bluemap.MixinWorld",
"mod_compat.create.IMixinDeployerHandler",
"mod_compat.create.IMixinDeployerMovementBehaviour",
"mod_compat.create.MixinAirCurrent",
Expand Down Expand Up @@ -92,6 +96,7 @@
"mod_compat.create_big_cannons.MixinPitchOrientedContraptionEntity",
"mod_compat.ftb_chunks.MixinClaimedChunkManager",
"mod_compat.reachentityattributes.MixinReachEntityAttributes",
"server.MinecraftServerAccessor",
"server.MixinMinecraftServer",
"server.MixinPlayerList",
"server.command.MixinCommands",
Expand Down

0 comments on commit 1705b55

Please sign in to comment.