fixes... lots of fixes
This commit is contained in:
parent
a654eec852
commit
8c877a5043
|
@ -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
|
||||
|
|
|
@ -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,31 +97,66 @@ 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();
|
||||
PortalRepresentation toPortal = toNode.getValue();
|
||||
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();
|
||||
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)) {
|
||||
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));
|
||||
//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);
|
||||
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!
|
||||
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…
Reference in New Issue
Block a user