fixes... lots of fixes
This commit is contained in:
		
							parent
							
								
									a654eec852
								
							
						
					
					
						commit
						9545a46171
					
				@ -126,7 +126,7 @@ import com.modrinth.minotaur.dependencies.ModDependency
 | 
			
		||||
modrinth {
 | 
			
		||||
    projectId = 'QXA901PE' // The ID of your Modrinth project. Slugs will not work.
 | 
			
		||||
    uploadFile = remapJar // Tells Minotaur to use the remapped jar
 | 
			
		||||
    versionType = "alpha"
 | 
			
		||||
    versionType = "beta"
 | 
			
		||||
    dependencies = [
 | 
			
		||||
            new ModDependency('P7dR8mSH', 'required'), //required dependency on Fabric API
 | 
			
		||||
            new ModDependency('AANobbMI', 'optional'), //compatible with Sodium
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ yarn_mappings=1.21+build.2
 | 
			
		||||
loader_version=0.15.11
 | 
			
		||||
 | 
			
		||||
# Mod Properties
 | 
			
		||||
mod_version=0.9.5
 | 
			
		||||
mod_version=0.9.5.1
 | 
			
		||||
maven_group=quimufu.colourful-portalRepresentations
 | 
			
		||||
archives_base_name=colourful-portalRepresentations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@ public class MixinConfig implements IMixinConfigPlugin {
 | 
			
		||||
    private static final Supplier<Boolean> TRUE = () -> true;
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
@ -76,8 +76,8 @@ public class PortalBlock extends Block implements FluidFillable {
 | 
			
		||||
        return VoxelShapes.empty();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
 | 
			
		||||
    protected void onEntityCollisionOld(BlockState state, World world, BlockPos pos, Entity entity) {
 | 
			
		||||
        ColourfulPortalsMod.LOGGER.info("detected collision {}", entity.getType());
 | 
			
		||||
        if (entity.getBoundingBox()
 | 
			
		||||
                .intersects(getShape(state, world, pos).getBoundingBox())) {
 | 
			
		||||
            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 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);
 | 
			
		||||
        if (world instanceof ServerWorld) {
 | 
			
		||||
            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.SpriteContents;
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
package quimufu.colourful_portals.mixin;
 | 
			
		||||
package quimufu.colourful_portals.mixin.client;
 | 
			
		||||
 | 
			
		||||
import net.minecraft.client.resource.metadata.AnimationResourceMetadata;
 | 
			
		||||
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 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.buffers.ChunkModelBuilder;
 | 
			
		||||
import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.FluidRenderer;
 | 
			
		||||
import me.jellysquid.mods.sodium.client.world.WorldSlice;
 | 
			
		||||
import net.minecraft.fluid.FluidState;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.world.BlockRenderView;
 | 
			
		||||
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
 | 
			
		||||
import quimufu.colourful_portals.client.SodiumPortalFluidRenderHandler;
 | 
			
		||||
 | 
			
		||||
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.texture.SpriteContents;
 | 
			
		||||
import net.minecraft.client.texture.SpriteDimensions;
 | 
			
		||||
import net.minecraft.resource.metadata.ResourceMetadata;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
import org.spongepowered.asm.mixin.Final;
 | 
			
		||||
import org.spongepowered.asm.mixin.Mixin;
 | 
			
		||||
@ -1,7 +1,10 @@
 | 
			
		||||
package quimufu.colourful_portals.portal;
 | 
			
		||||
 | 
			
		||||
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.network.ServerPlayerEntity;
 | 
			
		||||
import net.minecraft.server.world.ServerWorld;
 | 
			
		||||
import net.minecraft.util.Identifier;
 | 
			
		||||
import net.minecraft.util.math.BlockBox;
 | 
			
		||||
@ -11,14 +14,15 @@ import net.minecraft.util.math.Vec3d;
 | 
			
		||||
import net.minecraft.world.TeleportTarget;
 | 
			
		||||
import quimufu.colourful_portals.general_util.LinkedList;
 | 
			
		||||
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 static quimufu.colourful_portals.ColourfulPortalsMod.LOGGER;
 | 
			
		||||
import static quimufu.colourful_portals.ColourfulPortalsMod.MOD_ID;
 | 
			
		||||
import static quimufu.colourful_portals.portal.PortalHelper.getAxisW;
 | 
			
		||||
import static quimufu.colourful_portals.portal.PortalHelper.insideOf;
 | 
			
		||||
import static quimufu.colourful_portals.portal.PortalHelper.getDimId;
 | 
			
		||||
import static quimufu.colourful_portals.portal.PortalHelper.*;
 | 
			
		||||
 | 
			
		||||
public class DefaultLinkingSystem implements PortalLinkingSystem {
 | 
			
		||||
 | 
			
		||||
@ -58,9 +62,32 @@ public class DefaultLinkingSystem implements PortalLinkingSystem {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onPortalPassed(Entity entity, BlockPos pos, ServerWorld world, Direction.Axis a) {
 | 
			
		||||
        Set<Node<PortalRepresentation>> portalRepresentationCandidated = positionalLookup.get(pos);
 | 
			
		||||
        Optional<Node<PortalRepresentation>> portalOpt = portalRepresentationCandidated.stream()
 | 
			
		||||
    public boolean movementCallback(Entity entity, BlockPos pos, ServerWorld world) {
 | 
			
		||||
        for (Direction.Axis axis : Direction.Axis.values()) {
 | 
			
		||||
            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.getValue() != null)
 | 
			
		||||
                .filter(n -> getAxisW(n.getValue()).rotateYClockwise().getAxis() == a)
 | 
			
		||||
@ -70,7 +97,7 @@ public class DefaultLinkingSystem implements PortalLinkingSystem {
 | 
			
		||||
            Node<PortalRepresentation> fromNode = portalOpt.get();
 | 
			
		||||
            Node<PortalRepresentation> toNode = fromNode.getNext() != null ? fromNode.getNext() : fromNode.getPartOf().getNode(0);
 | 
			
		||||
            if (toNode == null || toNode.getValue() == null) {
 | 
			
		||||
                return;
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            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 relPos = entity.getPos().subtract(fromCenter);
 | 
			
		||||
            Vec3d targetPos;
 | 
			
		||||
            float targetYaw;
 | 
			
		||||
            Vec3d targetVelocity;
 | 
			
		||||
            ServerWorld toWorld = getPortalWorld(server, toPortal);
 | 
			
		||||
            if (getAxisW(fromPortal) == getAxisW(toPortal)) {
 | 
			
		||||
                Vec3d relPos = entity.getPos().subtract(fromCenter);
 | 
			
		||||
                Vec3d targetPos = toCenter.add(relPos);
 | 
			
		||||
                //todo: maybe fancy continoous movement math!
 | 
			
		||||
                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);
 | 
			
		||||
                targetPos = toCenter.add(relPos);
 | 
			
		||||
                targetYaw = entity.getYaw();
 | 
			
		||||
                targetVelocity = entity.getVelocity();
 | 
			
		||||
            } else {
 | 
			
		||||
                Vec3d relPos = entity.getPos().subtract(fromCenter);
 | 
			
		||||
                Vec3d targetPos = toCenter.add(new Vec3d(-relPos.z, relPos.y, relPos.x));
 | 
			
		||||
                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!
 | 
			
		||||
                ServerWorld toWorld = getPortalWorld(server, toPortal);
 | 
			
		||||
                TeleportTarget teleportTarget = new TeleportTarget(toWorld, targetPos, entity.getVelocity(), (entity.getYaw() + 90.F) % 360.F, entity.getPitch(), TeleportTarget.ADD_PORTAL_CHUNK_TICKET);
 | 
			
		||||
                entity.teleportTo(teleportTarget);
 | 
			
		||||
            TeleportTarget teleportTarget = new TeleportTarget(toWorld, targetPos, targetVelocity, targetYaw, entity.getPitch(), TeleportTarget.ADD_PORTAL_CHUNK_TICKET);
 | 
			
		||||
            if (entity instanceof ServerPlayerEntity) {
 | 
			
		||||
                ((ServerPlayerEntityAccessor) entity).setInTeleportationState(true);
 | 
			
		||||
            }
 | 
			
		||||
            Entity target;
 | 
			
		||||
            if ((target = entity.teleportTo(teleportTarget)) != null) {
 | 
			
		||||
                target.velocityDirty = true;
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -102,6 +164,11 @@ public class DefaultLinkingSystem implements PortalLinkingSystem {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean needsMovementCallback() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static ServerWorld getPortalWorld(MinecraftServer server, PortalRepresentation fromPortalRepresentation) {
 | 
			
		||||
        ServerWorld serverWorld = PortalHelper.getPortalWorld(server, fromPortalRepresentation);
 | 
			
		||||
        if (serverWorld == null) {
 | 
			
		||||
 | 
			
		||||
@ -111,8 +111,9 @@ public class ImmersivePortalsLinkingSystem implements PortalLinkingSystem {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @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
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -120,6 +121,16 @@ public class ImmersivePortalsLinkingSystem implements PortalLinkingSystem {
 | 
			
		||||
        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) {
 | 
			
		||||
        Box portalBox = Box.from(portalRepresentation.location());
 | 
			
		||||
        return getPortalWorld(portalRepresentation)
 | 
			
		||||
 | 
			
		||||
@ -7,8 +7,6 @@ import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.math.Direction;
 | 
			
		||||
import quimufu.colourful_portals.general_util.LinkedList;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public interface PortalLinkingSystem {
 | 
			
		||||
    Identifier getLinkingSystemId();
 | 
			
		||||
 | 
			
		||||
@ -16,7 +14,11 @@ public interface PortalLinkingSystem {
 | 
			
		||||
 | 
			
		||||
    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 needsMovementCallback();
 | 
			
		||||
 | 
			
		||||
    boolean movementCallback(Entity entity, BlockPos p, ServerWorld world);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -251,6 +251,10 @@ public class PortalManager {
 | 
			
		||||
        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) {
 | 
			
		||||
        HashSet<Identifier> blockIdsToDelete = new HashSet<>(portalCandidateList.getBlockIds());
 | 
			
		||||
        blockIdsToDelete.addAll(portalList.getBlockIds());
 | 
			
		||||
 | 
			
		||||
@ -198,6 +198,8 @@ public class PortalFluid extends Fluid {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Direction candidate = null;
 | 
			
		||||
        BlockState candidateBlockState = null;
 | 
			
		||||
 | 
			
		||||
        for (Direction dir : Direction.values()) {
 | 
			
		||||
            if (dir == targetDir.getOpposite() || dir == targetDir) {
 | 
			
		||||
                continue;
 | 
			
		||||
@ -212,12 +214,16 @@ public class PortalFluid extends Fluid {
 | 
			
		||||
            //if adjacent to any solid Block, it's a candidate
 | 
			
		||||
            if (neighbourOfInspected.isSideSolidFullSquare(world, neighborOfInspectedLocation, dir.getOpposite())) {
 | 
			
		||||
                candidate = dir;
 | 
			
		||||
                candidateBlockState = world.getBlockState(pos.offset(dir));
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            if (candidate == null && !neighbourOfInspected.isReplaceable()) {
 | 
			
		||||
            if ((candidate == null || candidateBlockState.isReplaceable()) && !neighbourOfInspected.isReplaceable()) {
 | 
			
		||||
                candidate = dir;
 | 
			
		||||
                candidateBlockState = world.getBlockState(pos.offset(dir));
 | 
			
		||||
            }
 | 
			
		||||
            if (candidate == null && !neighbourOfInspected.isReplaceable()) {
 | 
			
		||||
            if (candidate == null) {
 | 
			
		||||
                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",
 | 
			
		||||
  "compatibilityLevel": "JAVA_17",
 | 
			
		||||
  "mixins": [
 | 
			
		||||
    "BlockChangeMixin",
 | 
			
		||||
    "EntityMixin"
 | 
			
		||||
    "BlockChangeAndEntityMovementMixin",
 | 
			
		||||
    "ServerPlayerEntityAccessor",
 | 
			
		||||
    "ServerPlayNetworkHandlerAccessor"
 | 
			
		||||
  ],
 | 
			
		||||
  "injectors": {
 | 
			
		||||
    "defaultRequire": 1
 | 
			
		||||
  },
 | 
			
		||||
  "plugin": "quimufu.colourful_portals.MixinConfig",
 | 
			
		||||
  "client": [
 | 
			
		||||
    "AnimationMixin",
 | 
			
		||||
    "AnimationResourceMetadataMixin",
 | 
			
		||||
    "AnimationResourceMetadataReaderMixin",
 | 
			
		||||
    "SodiumFluidRendererMixin",
 | 
			
		||||
    "SpriteContentsMixin"
 | 
			
		||||
    "client.AnimationMixin",
 | 
			
		||||
    "client.AnimationResourceMetadataMixin",
 | 
			
		||||
    "client.AnimationResourceMetadataReaderMixin",
 | 
			
		||||
    "client.SodiumFluidRendererMixin",
 | 
			
		||||
    "client.SpriteContentsMixin"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user