fixes... lots of fixes
This commit is contained in:
		
							parent
							
								
									a654eec852
								
							
						
					
					
						commit
						9545a46171
					
				@ -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
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,7 @@ yarn_mappings=1.21+build.2
 | 
				
			|||||||
loader_version=0.15.11
 | 
					loader_version=0.15.11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Mod Properties
 | 
					# Mod Properties
 | 
				
			||||||
mod_version=0.9.5
 | 
					mod_version=0.9.5.1
 | 
				
			||||||
maven_group=quimufu.colourful-portalRepresentations
 | 
					maven_group=quimufu.colourful-portalRepresentations
 | 
				
			||||||
archives_base_name=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 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,31 +97,66 @@ 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();
 | 
				
			||||||
            PortalRepresentation toPortal = toNode.getValue();
 | 
					            PortalRepresentation toPortal = toNode.getValue();
 | 
				
			||||||
            BlockBox fromBox = fromPortal.location();
 | 
					            BlockBox fromBox = fromPortal.location();
 | 
				
			||||||
            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) {
 | 
				
			||||||
                //todo: maybe fancy continoous movement math!
 | 
					//                    //un-fuck up arrow Yaw
 | 
				
			||||||
                ServerWorld toWorld = getPortalWorld(server, toPortal);
 | 
					//                    //rotate by 90°
 | 
				
			||||||
                TeleportTarget teleportTarget = new TeleportTarget(toWorld, targetPos, entity.getVelocity(), (entity.getYaw() + 90.F) % 360.F, entity.getPitch(), TeleportTarget.ADD_PORTAL_CHUNK_TICKET);
 | 
					//                    targetYaw = (entity.getYaw() + 90.F) % 360.F;
 | 
				
			||||||
                entity.teleportTo(teleportTarget);
 | 
					//                    //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!
 | 
				
			||||||
 | 
					            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
 | 
					    @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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user