fixes... lots of fixes
This commit is contained in:
parent
a654eec852
commit
8c877a5043
|
@ -126,7 +126,7 @@ import com.modrinth.minotaur.dependencies.ModDependency
|
||||||
modrinth {
|
modrinth {
|
||||||
projectId = 'QXA901PE' // The ID of your Modrinth project. Slugs will not work.
|
projectId = 'QXA901PE' // The ID of your Modrinth project. Slugs will not work.
|
||||||
uploadFile = remapJar // Tells Minotaur to use the remapped jar
|
uploadFile = remapJar // Tells Minotaur to use the remapped jar
|
||||||
versionType = "alpha"
|
versionType = "beta"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
new ModDependency('P7dR8mSH', 'required'), //required dependency on Fabric API
|
new ModDependency('P7dR8mSH', 'required'), //required dependency on Fabric API
|
||||||
new ModDependency('AANobbMI', 'optional'), //compatible with Sodium
|
new ModDependency('AANobbMI', 'optional'), //compatible with Sodium
|
||||||
|
|
|
@ -14,7 +14,7 @@ public class MixinConfig implements IMixinConfigPlugin {
|
||||||
private static final Supplier<Boolean> TRUE = () -> true;
|
private static final Supplier<Boolean> TRUE = () -> true;
|
||||||
|
|
||||||
private static final Map<String, Supplier<Boolean>> CONDITIONS = Map.of(
|
private static final Map<String, Supplier<Boolean>> CONDITIONS = Map.of(
|
||||||
"quimufu.colourful_portals.mixin.SodiumFluidRendererMixin", () -> FabricLoader.getInstance().isModLoaded("sodium")
|
"quimufu.colourful_portals.mixin.client.SodiumFluidRendererMixin", () -> FabricLoader.getInstance().isModLoaded("sodium")
|
||||||
);
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -76,8 +76,8 @@ public class PortalBlock extends Block implements FluidFillable {
|
||||||
return VoxelShapes.empty();
|
return VoxelShapes.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected void onEntityCollisionOld(BlockState state, World world, BlockPos pos, Entity entity) {
|
||||||
protected void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
|
ColourfulPortalsMod.LOGGER.info("detected collision {}", entity.getType());
|
||||||
if (entity.getBoundingBox()
|
if (entity.getBoundingBox()
|
||||||
.intersects(getShape(state, world, pos).getBoundingBox())) {
|
.intersects(getShape(state, world, pos).getBoundingBox())) {
|
||||||
Vec3d vec3d = new Vec3d(0.5, 0.5f, 0.5);
|
Vec3d vec3d = new Vec3d(0.5, 0.5f, 0.5);
|
||||||
|
@ -85,6 +85,11 @@ public class PortalBlock extends Block implements FluidFillable {
|
||||||
}
|
}
|
||||||
Vec3d entityPos = entity.getPos();
|
Vec3d entityPos = entity.getPos();
|
||||||
Vec3d prevEntityPos = new Vec3d(entity.prevX, entity.prevY, entity.prevZ);
|
Vec3d prevEntityPos = new Vec3d(entity.prevX, entity.prevY, entity.prevZ);
|
||||||
|
if(entityPos.equals(prevEntityPos) && entity.getVelocity().squaredDistanceTo(Vec3d.ZERO) >= 0.01D){
|
||||||
|
//in this case, the collision logic was called prior to the movement logic,
|
||||||
|
// so we'll have to calculate our own next postion
|
||||||
|
entityPos = entityPos.add(entity.getVelocity());
|
||||||
|
}
|
||||||
Vec3d movement = entityPos.subtract(prevEntityPos);
|
Vec3d movement = entityPos.subtract(prevEntityPos);
|
||||||
if (world instanceof ServerWorld) {
|
if (world instanceof ServerWorld) {
|
||||||
Direction.Axis axis = state.get(AXIS);
|
Direction.Axis axis = state.get(AXIS);
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
package quimufu.colourful_portals.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import quimufu.colourful_portals.util.RaycastHelper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static quimufu.colourful_portals.ColourfulPortalsMod.*;
|
||||||
|
|
||||||
|
@Mixin(ServerWorld.class)
|
||||||
|
public abstract class BlockChangeAndEntityMovementMixin {
|
||||||
|
@Unique
|
||||||
|
private static final List<Direction> HORIZONTAL = Direction.stream().filter(d -> d.getAxis().isHorizontal()).toList();
|
||||||
|
|
||||||
|
// @Unique
|
||||||
|
// private final ThreadLocal<Map<EntityType<?>, Entity>> entities =
|
||||||
|
// ThreadLocal.withInitial(() -> HashMap.newHashMap(Registries.ENTITY_TYPE.size()));
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract String toString();
|
||||||
|
|
||||||
|
// @Inject(at = @At(value = "HEAD"), method = "tickEntity")
|
||||||
|
// private void cpm_beforeEntityTick(Entity entity, CallbackInfo ci) {
|
||||||
|
// if(PORTAL_MANAGER.getLinkingSystem().needsMovementCallback()){
|
||||||
|
// Entity copy = entities.get().computeIfAbsent(entity.getType(), t -> t.create(null));
|
||||||
|
// copy.copyFrom(entity);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract boolean isChunkLoaded(long chunkPos);
|
||||||
|
|
||||||
|
@Inject(at = @At("RETURN"), method = "tickEntity")
|
||||||
|
private void cpm_afterEntityTick(Entity entity, CallbackInfo ci) {
|
||||||
|
if (PORTAL_MANAGER.getLinkingSystem().needsMovementCallback()) {
|
||||||
|
Vec3d prevEntityPos;
|
||||||
|
if (entity instanceof ServerPlayerEntity serverPlayerEntity) {
|
||||||
|
ServerPlayNetworkHandlerAccessor spnha = (ServerPlayNetworkHandlerAccessor) serverPlayerEntity.networkHandler;
|
||||||
|
prevEntityPos = new Vec3d(spnha.getLastTickX(), spnha.getLastTickY(), spnha.getLastTickZ());
|
||||||
|
} else {
|
||||||
|
prevEntityPos = new Vec3d(entity.prevX, entity.prevY, entity.prevZ);
|
||||||
|
}
|
||||||
|
Vec3d entityPos = entity.getPos();
|
||||||
|
ServerWorld world = (ServerWorld) (Object) this;
|
||||||
|
List<BlockPos> passedBlocks = RaycastHelper.passedBlocks(prevEntityPos, entityPos);
|
||||||
|
for (BlockPos passedBlock : passedBlocks) {
|
||||||
|
if (PORTAL_MANAGER.onMovementThroughBlock(entity, passedBlock, world)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(at = @At("RETURN"), method = "onBlockChanged")
|
||||||
|
private void cpm_afterOnBlockChanged(BlockPos pos, BlockState oldBlock, BlockState newBlock, CallbackInfo info) {
|
||||||
|
ServerWorld world = (ServerWorld) (Object) this;
|
||||||
|
if (world.isDebugWorld())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// This code is injected into the end of ServerWorld.onBlockChanged()V
|
||||||
|
if (oldBlock.getBlock() != newBlock.getBlock()) {
|
||||||
|
if (PORTAL_BLOCKS.contains(Registries.BLOCK.getId(newBlock.getBlock()))) {
|
||||||
|
LOGGER.info("onBlockNew {} -> {}", oldBlock, newBlock);
|
||||||
|
Identifier blockId = Registries.BLOCK.getId(newBlock.getBlock());
|
||||||
|
world.getServer().execute(() -> PORTAL_MANAGER.onPortalBlockPlaced(world, pos, blockId));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PORTAL_BLOCKS.contains(Registries.BLOCK.getId(oldBlock.getBlock()))) {
|
||||||
|
LOGGER.info("onBlockOld {} -> {}", oldBlock, newBlock);
|
||||||
|
Identifier blockId = Registries.BLOCK.getId(oldBlock.getBlock());
|
||||||
|
world.getServer().execute(() -> PORTAL_MANAGER.onPortalBlockBroken(world, pos, blockId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,39 +0,0 @@
|
||||||
package quimufu.colourful_portals.mixin;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.registry.Registries;
|
|
||||||
import net.minecraft.server.world.ServerWorld;
|
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
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.CallbackInfo;
|
|
||||||
|
|
||||||
import static quimufu.colourful_portals.ColourfulPortalsMod.*;
|
|
||||||
|
|
||||||
@Mixin(ServerWorld.class)
|
|
||||||
public class BlockChangeMixin {
|
|
||||||
|
|
||||||
@Inject(at = @At("RETURN"), method = "onBlockChanged")
|
|
||||||
private void cpm_afterOnBlockChanged(BlockPos pos, BlockState oldBlock, BlockState newBlock, CallbackInfo info) {
|
|
||||||
ServerWorld world = (ServerWorld) (Object) this;
|
|
||||||
if(world.isDebugWorld()|| !world.isChunkLoaded(pos))
|
|
||||||
return;
|
|
||||||
// This code is injected into the end of ServerWorld.onBlockChanged()V
|
|
||||||
if (oldBlock.getBlock() != newBlock.getBlock()) {
|
|
||||||
if (PORTAL_BLOCKS.contains(Registries.BLOCK.getId(newBlock.getBlock()))) {
|
|
||||||
LOGGER.info("onBlockNew {} -> {}", oldBlock, newBlock);
|
|
||||||
Identifier blockId = Registries.BLOCK.getId(newBlock.getBlock());
|
|
||||||
PORTAL_MANAGER.onPortalBlockPlaced(world, pos, blockId);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (PORTAL_BLOCKS.contains(Registries.BLOCK.getId(oldBlock.getBlock()))) {
|
|
||||||
LOGGER.info("onBlockOld {} -> {}", oldBlock, newBlock);
|
|
||||||
Identifier blockId = Registries.BLOCK.getId(oldBlock.getBlock());
|
|
||||||
PORTAL_MANAGER.onPortalBlockBroken(world, pos, blockId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package quimufu.colourful_portals.mixin;
|
|
||||||
|
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.RaycastContext;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
import quimufu.colourful_portals.util.CollisionAwareShapeContext;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
import static quimufu.colourful_portals.ColourfulPortalsMod.PORTAL_BLOCK;
|
|
||||||
|
|
||||||
@Mixin(Entity.class)
|
|
||||||
public class EntityMixin {
|
|
||||||
@Shadow
|
|
||||||
private World world;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
public double prevX;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
public double prevY;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
public double prevZ;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
private Vec3d pos;
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private final ThreadLocal<HashSet<BlockPos>> calledAlready = ThreadLocal.withInitial(HashSet::new);
|
|
||||||
|
|
||||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;onEntityCollision(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/Entity;)V"), method = "checkBlockCollision")
|
|
||||||
public void cpm_dontCallTwice(CallbackInfo ci, @Local BlockPos.Mutable mutable) {
|
|
||||||
calledAlready.get().add(mutable.toImmutable());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(at = @At("RETURN"), method = "checkBlockCollision")
|
|
||||||
public void cpm_afterCheckBlockCollision(CallbackInfo ci) {
|
|
||||||
if (!world.isClient()) {
|
|
||||||
BlockHitResult hitResult = world.raycast(new RaycastContext(new Vec3d(prevX, prevY, prevZ), pos, RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, new CollisionAwareShapeContext()));
|
|
||||||
|
|
||||||
BlockPos hitResultBlockPos = hitResult.getBlockPos();
|
|
||||||
if (!calledAlready.get().contains(hitResultBlockPos)) {
|
|
||||||
BlockState state = world.getBlockState(hitResultBlockPos);
|
|
||||||
if (state.getBlock() == PORTAL_BLOCK) {
|
|
||||||
state.onEntityCollision(world, hitResultBlockPos, (Entity) ((Object) this));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
calledAlready.get().clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package quimufu.colourful_portals.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(ServerPlayNetworkHandler.class)
|
||||||
|
public interface ServerPlayNetworkHandlerAccessor {
|
||||||
|
@Accessor
|
||||||
|
double getLastTickX();
|
||||||
|
|
||||||
|
@Accessor
|
||||||
|
double getLastTickY();
|
||||||
|
|
||||||
|
@Accessor
|
||||||
|
double getLastTickZ();
|
||||||
|
|
||||||
|
@Accessor
|
||||||
|
double getLastTickRiddenX();
|
||||||
|
|
||||||
|
@Accessor
|
||||||
|
double getLastTickRiddenY();
|
||||||
|
|
||||||
|
@Accessor
|
||||||
|
double getLastTickRiddenZ();
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package quimufu.colourful_portals.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(ServerPlayerEntity.class)
|
||||||
|
public interface ServerPlayerEntityAccessor {
|
||||||
|
|
||||||
|
@Accessor
|
||||||
|
void setInTeleportationState(boolean inTeleportationState);
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package quimufu.colourful_portals.mixin;
|
package quimufu.colourful_portals.mixin.client;
|
||||||
|
|
||||||
import net.minecraft.client.texture.Animator;
|
import net.minecraft.client.texture.Animator;
|
||||||
import net.minecraft.client.texture.SpriteContents;
|
import net.minecraft.client.texture.SpriteContents;
|
|
@ -1,4 +1,4 @@
|
||||||
package quimufu.colourful_portals.mixin;
|
package quimufu.colourful_portals.mixin.client;
|
||||||
|
|
||||||
import net.minecraft.client.resource.metadata.AnimationResourceMetadata;
|
import net.minecraft.client.resource.metadata.AnimationResourceMetadata;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
|
@ -1,4 +1,4 @@
|
||||||
package quimufu.colourful_portals.mixin;
|
package quimufu.colourful_portals.mixin.client;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import net.minecraft.client.resource.metadata.AnimationResourceMetadata;
|
import net.minecraft.client.resource.metadata.AnimationResourceMetadata;
|
|
@ -1,17 +1,14 @@
|
||||||
package quimufu.colourful_portals.mixin;
|
package quimufu.colourful_portals.mixin.client;
|
||||||
|
|
||||||
import me.jellysquid.mods.sodium.client.render.chunk.compile.ChunkBuildBuffers;
|
import me.jellysquid.mods.sodium.client.render.chunk.compile.ChunkBuildBuffers;
|
||||||
import me.jellysquid.mods.sodium.client.render.chunk.compile.buffers.ChunkModelBuilder;
|
|
||||||
import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.FluidRenderer;
|
import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.FluidRenderer;
|
||||||
import me.jellysquid.mods.sodium.client.world.WorldSlice;
|
import me.jellysquid.mods.sodium.client.world.WorldSlice;
|
||||||
import net.minecraft.fluid.FluidState;
|
import net.minecraft.fluid.FluidState;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.BlockRenderView;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
import quimufu.colourful_portals.client.SodiumPortalFluidRenderHandler;
|
import quimufu.colourful_portals.client.SodiumPortalFluidRenderHandler;
|
||||||
|
|
||||||
import static quimufu.colourful_portals.ColourfulPortalsMod.PORTAL_FLUID;
|
import static quimufu.colourful_portals.ColourfulPortalsMod.PORTAL_FLUID;
|
|
@ -1,9 +1,8 @@
|
||||||
package quimufu.colourful_portals.mixin;
|
package quimufu.colourful_portals.mixin.client;
|
||||||
|
|
||||||
import net.minecraft.client.resource.metadata.AnimationResourceMetadata;
|
import net.minecraft.client.resource.metadata.AnimationResourceMetadata;
|
||||||
import net.minecraft.client.texture.SpriteContents;
|
import net.minecraft.client.texture.SpriteContents;
|
||||||
import net.minecraft.client.texture.SpriteDimensions;
|
import net.minecraft.client.texture.SpriteDimensions;
|
||||||
import net.minecraft.resource.metadata.ResourceMetadata;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
|
@ -1,7 +1,10 @@
|
||||||
package quimufu.colourful_portals.portal;
|
package quimufu.colourful_portals.portal;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.projectile.ArrowEntity;
|
||||||
|
import net.minecraft.entity.projectile.PersistentProjectileEntity;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockBox;
|
import net.minecraft.util.math.BlockBox;
|
||||||
|
@ -11,14 +14,15 @@ import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.TeleportTarget;
|
import net.minecraft.world.TeleportTarget;
|
||||||
import quimufu.colourful_portals.general_util.LinkedList;
|
import quimufu.colourful_portals.general_util.LinkedList;
|
||||||
import quimufu.colourful_portals.general_util.Node;
|
import quimufu.colourful_portals.general_util.Node;
|
||||||
|
import quimufu.colourful_portals.mixin.ServerPlayNetworkHandlerAccessor;
|
||||||
|
import quimufu.colourful_portals.mixin.ServerPlayerEntityAccessor;
|
||||||
|
import quimufu.colourful_portals.util.RaycastHelper;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static quimufu.colourful_portals.ColourfulPortalsMod.LOGGER;
|
import static quimufu.colourful_portals.ColourfulPortalsMod.LOGGER;
|
||||||
import static quimufu.colourful_portals.ColourfulPortalsMod.MOD_ID;
|
import static quimufu.colourful_portals.ColourfulPortalsMod.MOD_ID;
|
||||||
import static quimufu.colourful_portals.portal.PortalHelper.getAxisW;
|
import static quimufu.colourful_portals.portal.PortalHelper.*;
|
||||||
import static quimufu.colourful_portals.portal.PortalHelper.insideOf;
|
|
||||||
import static quimufu.colourful_portals.portal.PortalHelper.getDimId;
|
|
||||||
|
|
||||||
public class DefaultLinkingSystem implements PortalLinkingSystem {
|
public class DefaultLinkingSystem implements PortalLinkingSystem {
|
||||||
|
|
||||||
|
@ -58,9 +62,32 @@ public class DefaultLinkingSystem implements PortalLinkingSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPortalPassed(Entity entity, BlockPos pos, ServerWorld world, Direction.Axis a) {
|
public boolean movementCallback(Entity entity, BlockPos pos, ServerWorld world) {
|
||||||
Set<Node<PortalRepresentation>> portalRepresentationCandidated = positionalLookup.get(pos);
|
for (Direction.Axis axis : Direction.Axis.values()) {
|
||||||
Optional<Node<PortalRepresentation>> portalOpt = portalRepresentationCandidated.stream()
|
Vec3d prevEntityPos;
|
||||||
|
if (entity instanceof ServerPlayerEntity serverPlayerEntity) {
|
||||||
|
ServerPlayNetworkHandlerAccessor spnha = (ServerPlayNetworkHandlerAccessor) serverPlayerEntity.networkHandler;
|
||||||
|
prevEntityPos = new Vec3d(spnha.getLastTickX(), spnha.getLastTickY(), spnha.getLastTickZ());
|
||||||
|
} else {
|
||||||
|
prevEntityPos = new Vec3d(entity.prevX, entity.prevY, entity.prevZ);
|
||||||
|
}
|
||||||
|
if (RaycastHelper.passedOnAxis(prevEntityPos, entity.getPos(), pos, axis)) {
|
||||||
|
//LOGGER.info("passed on Axis!");
|
||||||
|
if (onPortalPassed(entity, pos, world, axis)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPortalPassed(Entity entity, BlockPos pos, ServerWorld world, Direction.Axis a) {
|
||||||
|
Set<Node<PortalRepresentation>> portalRepresentationCandidates = positionalLookup.get(pos);
|
||||||
|
if (portalRepresentationCandidates == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Optional<Node<PortalRepresentation>> portalOpt = portalRepresentationCandidates.stream()
|
||||||
.filter(n -> !n.orphaned())
|
.filter(n -> !n.orphaned())
|
||||||
.filter(n -> n.getValue() != null)
|
.filter(n -> n.getValue() != null)
|
||||||
.filter(n -> getAxisW(n.getValue()).rotateYClockwise().getAxis() == a)
|
.filter(n -> getAxisW(n.getValue()).rotateYClockwise().getAxis() == a)
|
||||||
|
@ -70,7 +97,7 @@ public class DefaultLinkingSystem implements PortalLinkingSystem {
|
||||||
Node<PortalRepresentation> fromNode = portalOpt.get();
|
Node<PortalRepresentation> fromNode = portalOpt.get();
|
||||||
Node<PortalRepresentation> toNode = fromNode.getNext() != null ? fromNode.getNext() : fromNode.getPartOf().getNode(0);
|
Node<PortalRepresentation> toNode = fromNode.getNext() != null ? fromNode.getNext() : fromNode.getPartOf().getNode(0);
|
||||||
if (toNode == null || toNode.getValue() == null) {
|
if (toNode == null || toNode.getValue() == null) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PortalRepresentation fromPortal = fromNode.getValue();
|
PortalRepresentation fromPortal = fromNode.getValue();
|
||||||
|
@ -79,22 +106,57 @@ public class DefaultLinkingSystem implements PortalLinkingSystem {
|
||||||
Vec3d fromCenter = new Vec3d((fromBox.getMaxX() + 1 + fromBox.getMinX()) / 2D, (fromBox.getMaxY() + 1 + fromBox.getMinY()) / 2D, (fromBox.getMaxZ() + 1 + fromBox.getMinZ()) / 2D);
|
Vec3d fromCenter = new Vec3d((fromBox.getMaxX() + 1 + fromBox.getMinX()) / 2D, (fromBox.getMaxY() + 1 + fromBox.getMinY()) / 2D, (fromBox.getMaxZ() + 1 + fromBox.getMinZ()) / 2D);
|
||||||
BlockBox toBox = toPortal.location();
|
BlockBox toBox = toPortal.location();
|
||||||
Vec3d toCenter = new Vec3d((toBox.getMaxX() + 1 + toBox.getMinX()) / 2D, (toBox.getMaxY() + 1 + toBox.getMinY()) / 2D, (toBox.getMaxZ() + 1 + toBox.getMinZ()) / 2D);
|
Vec3d toCenter = new Vec3d((toBox.getMaxX() + 1 + toBox.getMinX()) / 2D, (toBox.getMaxY() + 1 + toBox.getMinY()) / 2D, (toBox.getMaxZ() + 1 + toBox.getMinZ()) / 2D);
|
||||||
|
Vec3d relPos = entity.getPos().subtract(fromCenter);
|
||||||
|
Vec3d targetPos;
|
||||||
|
float targetYaw;
|
||||||
|
Vec3d targetVelocity;
|
||||||
|
ServerWorld toWorld = getPortalWorld(server, toPortal);
|
||||||
if (getAxisW(fromPortal) == getAxisW(toPortal)) {
|
if (getAxisW(fromPortal) == getAxisW(toPortal)) {
|
||||||
Vec3d relPos = entity.getPos().subtract(fromCenter);
|
targetPos = toCenter.add(relPos);
|
||||||
Vec3d targetPos = toCenter.add(relPos);
|
targetYaw = entity.getYaw();
|
||||||
//todo: maybe fancy continoous movement math!
|
targetVelocity = entity.getVelocity();
|
||||||
ServerWorld toWorld = getPortalWorld(server, toPortal);
|
|
||||||
TeleportTarget teleportTarget = new TeleportTarget(toWorld, targetPos, entity.getVelocity(), entity.getYaw(), entity.getPitch(), TeleportTarget.ADD_PORTAL_CHUNK_TICKET);
|
|
||||||
entity.teleportTo(teleportTarget);
|
|
||||||
} else {
|
} else {
|
||||||
Vec3d relPos = entity.getPos().subtract(fromCenter);
|
targetPos = toCenter.add(new Vec3d(-relPos.z, relPos.y, relPos.x));
|
||||||
Vec3d targetPos = toCenter.add(new Vec3d(-relPos.z, relPos.y, relPos.x));
|
if (entity instanceof PersistentProjectileEntity) {
|
||||||
|
// //un-fuck up arrow Yaw
|
||||||
|
// //rotate by 90°
|
||||||
|
// targetYaw = (entity.getYaw() + 90.F) % 360.F;
|
||||||
|
// //mirror
|
||||||
|
// targetYaw = (-targetYaw) % 360.F;
|
||||||
|
// //rotate by 90°
|
||||||
|
// targetYaw = (targetYaw - 90.F) % 360.F;
|
||||||
|
//
|
||||||
|
// //now it's normal!
|
||||||
|
// //Let's rotate it!
|
||||||
|
// targetYaw = (targetYaw + 90.F) % 360.F;
|
||||||
|
//
|
||||||
|
// //fuck it up again
|
||||||
|
// //rotate by 90°
|
||||||
|
// targetYaw = (targetYaw + 90.F) % 360.F;
|
||||||
|
// //mirror
|
||||||
|
// targetYaw = (-targetYaw) % 360.F;
|
||||||
|
// //rotate by 90°
|
||||||
|
// targetYaw = (targetYaw - 90.F) % 360.F;
|
||||||
|
//short:
|
||||||
|
targetYaw = (entity.getYaw() - 90.F) % 360.F;
|
||||||
|
} else {
|
||||||
|
targetYaw = (entity.getYaw() + 90.F) % 360.F;
|
||||||
|
}
|
||||||
|
Vec3d currVelocity = entity.getVelocity();
|
||||||
|
targetVelocity = new Vec3d(-currVelocity.z, currVelocity.y, currVelocity.x);
|
||||||
|
}
|
||||||
//todo: maybe fancy continoous movement math!
|
//todo: maybe fancy continoous movement math!
|
||||||
ServerWorld toWorld = getPortalWorld(server, toPortal);
|
TeleportTarget teleportTarget = new TeleportTarget(toWorld, targetPos, targetVelocity, targetYaw, entity.getPitch(), TeleportTarget.ADD_PORTAL_CHUNK_TICKET);
|
||||||
TeleportTarget teleportTarget = new TeleportTarget(toWorld, targetPos, entity.getVelocity(), (entity.getYaw() + 90.F) % 360.F, entity.getPitch(), TeleportTarget.ADD_PORTAL_CHUNK_TICKET);
|
if (entity instanceof ServerPlayerEntity) {
|
||||||
entity.teleportTo(teleportTarget);
|
((ServerPlayerEntityAccessor) entity).setInTeleportationState(true);
|
||||||
|
}
|
||||||
|
Entity target;
|
||||||
|
if ((target = entity.teleportTo(teleportTarget)) != null) {
|
||||||
|
target.velocityDirty = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -102,6 +164,11 @@ public class DefaultLinkingSystem implements PortalLinkingSystem {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean needsMovementCallback() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private static ServerWorld getPortalWorld(MinecraftServer server, PortalRepresentation fromPortalRepresentation) {
|
private static ServerWorld getPortalWorld(MinecraftServer server, PortalRepresentation fromPortalRepresentation) {
|
||||||
ServerWorld serverWorld = PortalHelper.getPortalWorld(server, fromPortalRepresentation);
|
ServerWorld serverWorld = PortalHelper.getPortalWorld(server, fromPortalRepresentation);
|
||||||
if (serverWorld == null) {
|
if (serverWorld == null) {
|
||||||
|
|
|
@ -111,8 +111,9 @@ public class ImmersivePortalsLinkingSystem implements PortalLinkingSystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPortalPassed(Entity entity, BlockPos pos, ServerWorld world, Direction.Axis a) {
|
public boolean onPortalPassed(Entity entity, BlockPos pos, ServerWorld world, Direction.Axis a) {
|
||||||
//no-op, handled by immptl
|
//no-op, handled by immptl
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -120,6 +121,16 @@ public class ImmersivePortalsLinkingSystem implements PortalLinkingSystem {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean needsMovementCallback() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean movementCallback(Entity entity, BlockPos p, ServerWorld world) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private List<qouteall.imm_ptl.core.portal.Portal> getPortalList(PortalRepresentation portalRepresentation) {
|
private List<qouteall.imm_ptl.core.portal.Portal> getPortalList(PortalRepresentation portalRepresentation) {
|
||||||
Box portalBox = Box.from(portalRepresentation.location());
|
Box portalBox = Box.from(portalRepresentation.location());
|
||||||
return getPortalWorld(portalRepresentation)
|
return getPortalWorld(portalRepresentation)
|
||||||
|
|
|
@ -7,8 +7,6 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import quimufu.colourful_portals.general_util.LinkedList;
|
import quimufu.colourful_portals.general_util.LinkedList;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface PortalLinkingSystem {
|
public interface PortalLinkingSystem {
|
||||||
Identifier getLinkingSystemId();
|
Identifier getLinkingSystemId();
|
||||||
|
|
||||||
|
@ -16,7 +14,11 @@ public interface PortalLinkingSystem {
|
||||||
|
|
||||||
void unLinkPortal(PortalRepresentation portalRepresentation);
|
void unLinkPortal(PortalRepresentation portalRepresentation);
|
||||||
|
|
||||||
void onPortalPassed(Entity entity, BlockPos pos, ServerWorld world, Direction.Axis a);
|
boolean onPortalPassed(Entity entity, BlockPos pos, ServerWorld world, Direction.Axis a);
|
||||||
|
|
||||||
boolean needsReInit();
|
boolean needsReInit();
|
||||||
|
|
||||||
|
boolean needsMovementCallback();
|
||||||
|
|
||||||
|
boolean movementCallback(Entity entity, BlockPos p, ServerWorld world);
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,6 +251,10 @@ public class PortalManager {
|
||||||
linkingSystem.onPortalPassed(entity, pos, world, a);
|
linkingSystem.onPortalPassed(entity, pos, world, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean onMovementThroughBlock(Entity entity, BlockPos pos, ServerWorld world) {
|
||||||
|
return linkingSystem.movementCallback(entity, pos, world);
|
||||||
|
}
|
||||||
|
|
||||||
public void onLoad(MinecraftServer minecraftServer) {
|
public void onLoad(MinecraftServer minecraftServer) {
|
||||||
HashSet<Identifier> blockIdsToDelete = new HashSet<>(portalCandidateList.getBlockIds());
|
HashSet<Identifier> blockIdsToDelete = new HashSet<>(portalCandidateList.getBlockIds());
|
||||||
blockIdsToDelete.addAll(portalList.getBlockIds());
|
blockIdsToDelete.addAll(portalList.getBlockIds());
|
||||||
|
|
|
@ -198,6 +198,8 @@ public class PortalFluid extends Fluid {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Direction candidate = null;
|
Direction candidate = null;
|
||||||
|
BlockState candidateBlockState = null;
|
||||||
|
|
||||||
for (Direction dir : Direction.values()) {
|
for (Direction dir : Direction.values()) {
|
||||||
if (dir == targetDir.getOpposite() || dir == targetDir) {
|
if (dir == targetDir.getOpposite() || dir == targetDir) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -212,12 +214,16 @@ public class PortalFluid extends Fluid {
|
||||||
//if adjacent to any solid Block, it's a candidate
|
//if adjacent to any solid Block, it's a candidate
|
||||||
if (neighbourOfInspected.isSideSolidFullSquare(world, neighborOfInspectedLocation, dir.getOpposite())) {
|
if (neighbourOfInspected.isSideSolidFullSquare(world, neighborOfInspectedLocation, dir.getOpposite())) {
|
||||||
candidate = dir;
|
candidate = dir;
|
||||||
|
candidateBlockState = world.getBlockState(pos.offset(dir));
|
||||||
|
|
||||||
}
|
}
|
||||||
if (candidate == null && !neighbourOfInspected.isReplaceable()) {
|
if ((candidate == null || candidateBlockState.isReplaceable()) && !neighbourOfInspected.isReplaceable()) {
|
||||||
candidate = dir;
|
candidate = dir;
|
||||||
|
candidateBlockState = world.getBlockState(pos.offset(dir));
|
||||||
}
|
}
|
||||||
if (candidate == null && !neighbourOfInspected.isReplaceable()) {
|
if (candidate == null) {
|
||||||
candidate = dir;
|
candidate = dir;
|
||||||
|
candidateBlockState = world.getBlockState(pos.offset(dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
package quimufu.colourful_portals.util;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import quimufu.colourful_portals.ColourfulPortalsMod;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RaycastHelper {
|
||||||
|
|
||||||
|
|
||||||
|
public static List<BlockPos> passedBlocks(Vec3d from, Vec3d to) {
|
||||||
|
LinkedList<BlockPos> psitions = new LinkedList<>();
|
||||||
|
Vec3d difference = to.subtract(from);
|
||||||
|
if(to.equals(from)){
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
double[] diff = new double[]{difference.getX(), difference.getY(), difference.getZ()};
|
||||||
|
double[] start = new double[]{from.getX(), from.getY(), from.getZ()};
|
||||||
|
double[] pos = new double[]{from.getX(), from.getY(), from.getZ()};
|
||||||
|
BlockPos currentBlockPos = BlockPos.ofFloored(pos[0], pos[1], pos[2]);
|
||||||
|
|
||||||
|
double currDelta = 0;
|
||||||
|
|
||||||
|
while (currDelta < 1) {
|
||||||
|
psitions.add(currentBlockPos);
|
||||||
|
double minMissing = 1;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (diff[i] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
double curr;
|
||||||
|
if ((curr = ((round(pos[i], Math.signum(diff[i])) - pos[i]) / diff[i])) < minMissing) {
|
||||||
|
minMissing = curr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currDelta += minMissing;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
pos[i] = start[i] + currDelta * diff[i];
|
||||||
|
}
|
||||||
|
currentBlockPos = BlockPos.ofFloored(pos[0], pos[1], pos[2]);
|
||||||
|
}
|
||||||
|
BlockPos last = BlockPos.ofFloored(to);
|
||||||
|
if(!psitions.getLast().equals(last)){
|
||||||
|
psitions.add(last);
|
||||||
|
}
|
||||||
|
|
||||||
|
return psitions;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double round(double val, double signum) {
|
||||||
|
if (signum > 0) {
|
||||||
|
return Math.floor(val + signum);
|
||||||
|
}
|
||||||
|
return Math.ceil(val + signum);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean passedOnAxis(Vec3d from, Vec3d to, BlockPos blockPos, Direction.Axis axis) {
|
||||||
|
double startAA = from.getComponentAlongAxis(axis);
|
||||||
|
double centerAA = blockPos.toCenterPos().getComponentAlongAxis(axis);
|
||||||
|
Vec3d diff = to.subtract(from);
|
||||||
|
double differenceAA = diff.getComponentAlongAxis(axis);
|
||||||
|
|
||||||
|
double hitAfter = (centerAA - startAA) / differenceAA;
|
||||||
|
|
||||||
|
if (differenceAA == 0 || hitAfter > 1 || hitAfter < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//ColourfulPortalsMod.LOGGER.info("{}, {}: {} -> {}", hitAfter,axis, from, to);
|
||||||
|
|
||||||
|
return BlockPos.ofFloored(from.add(diff.multiply(hitAfter)))
|
||||||
|
.equals(blockPos);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,18 +3,19 @@
|
||||||
"package": "quimufu.colourful_portals.mixin",
|
"package": "quimufu.colourful_portals.mixin",
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"BlockChangeMixin",
|
"BlockChangeAndEntityMovementMixin",
|
||||||
"EntityMixin"
|
"ServerPlayerEntityAccessor",
|
||||||
|
"ServerPlayNetworkHandlerAccessor"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
},
|
},
|
||||||
"plugin": "quimufu.colourful_portals.MixinConfig",
|
"plugin": "quimufu.colourful_portals.MixinConfig",
|
||||||
"client": [
|
"client": [
|
||||||
"AnimationMixin",
|
"client.AnimationMixin",
|
||||||
"AnimationResourceMetadataMixin",
|
"client.AnimationResourceMetadataMixin",
|
||||||
"AnimationResourceMetadataReaderMixin",
|
"client.AnimationResourceMetadataReaderMixin",
|
||||||
"SodiumFluidRendererMixin",
|
"client.SodiumFluidRendererMixin",
|
||||||
"SpriteContentsMixin"
|
"client.SpriteContentsMixin"
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user