Skip to content

Commit

Permalink
Made teleporting respect the collision shape of blocks. TODO: Handle …
Browse files Browse the repository at this point in the history
…obstructed destination

-Accounted for entities with a hitbox width larger than one
-Made door collision box be two blocks high. This allows entities with smaller hitboxes such as chickens or items to have a larger surface to be teleported more easily
  • Loading branch information
50ap5ud5 committed Dec 29, 2023
1 parent fa7566e commit 5a96b64
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@

public class GlobalDoorBlock extends InternalDoorBlock{

protected static final VoxelShape SOUTH_AABB, NORTH_AABB, WEST_AABB, EAST_AABB;
protected static final VoxelShape NORTH_AABB = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 32.0D, 0.25D);
protected static final VoxelShape SOUTH_AABB = Block.box(0.0D, 0.0D, 15.75D, 16.0D, 32.0D, 16.0D);
protected static final VoxelShape EAST_AABB= Block.box(15.75D, 0.0D, 0.0D, 16.0D, 32.0D, 16.0D);
protected static final VoxelShape WEST_AABB = Block.box(0.0D, 0.0D, 0.0D, 0.25D, 32.0D, 16.0D);

public GlobalDoorBlock(Properties properties) {
super(properties);
Expand Down Expand Up @@ -69,7 +72,6 @@ public BlockState getStateForPlacement(@NotNull BlockPlaceContext blockPlaceCont
public InteractionResult use(BlockState blockState, Level level, BlockPos blockPos, Player player, InteractionHand interactionHand, BlockHitResult blockHitResult) {
if (interactionHand == InteractionHand.MAIN_HAND) {
if (level instanceof ServerLevel serverLevel) {

if (TardisLevelOperator.get(serverLevel).isPresent()) {
if (serverLevel.getBlockEntity(blockPos) instanceof GlobalDoorBlockEntity entity) {
entity.onRightClick(blockState, entity, player);
Expand All @@ -86,22 +88,20 @@ public InteractionResult use(BlockState blockState, Level level, BlockPos blockP
public VoxelShape getShape(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos, CollisionContext collisionContext) {
switch(blockState.getValue(FACING)) {
case EAST:
default:
return EAST_AABB;
return EAST_AABB;
case SOUTH:
return SOUTH_AABB ;
return SOUTH_AABB;
case WEST:
return WEST_AABB;
case NORTH:
return NORTH_AABB;
}
return SOUTH_AABB;
}

static {
NORTH_AABB = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 0.25D);
SOUTH_AABB = Block.box(0.0D, 0.0D, 15.75D, 16.0D, 16.0D, 16.0D);
EAST_AABB= Block.box(15.75D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D);
WEST_AABB = Block.box(0.0D, 0.0D, 0.0D, 0.25D, 16.0D, 16.0D);
@Override
public VoxelShape getCollisionShape(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos, CollisionContext collisionContext) {
return this.getShape(blockState, blockGetter, blockPos, collisionContext);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
Expand All @@ -15,17 +16,22 @@
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import whocraft.tardis_refined.common.blockentity.door.InternalDoorBlockEntity;
import whocraft.tardis_refined.common.blockentity.door.TardisInternalDoor;
import whocraft.tardis_refined.common.util.TRTeleporter;

import java.util.List;

public class InternalDoorBlock extends BaseEntityBlock {

public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING;
public static final BooleanProperty OPEN = BooleanProperty.create("open");
protected static final VoxelShape COLLISION = Block.box(0, 0, 0, 16, 3, 16);
protected static final VoxelShape COLLISION = Block.box(0, 0, 0, 16, 32, 16);
protected static BlockEntity blockEntity;


Expand All @@ -50,7 +56,7 @@ public VoxelShape getShape(BlockState blockState, BlockGetter blockGetter, Block

@Override
public VoxelShape getCollisionShape(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos, CollisionContext collisionContext) {
return COLLISION;
return this.getShape(blockState, blockGetter, blockPos, collisionContext);
}

@Nullable
Expand Down Expand Up @@ -88,8 +94,12 @@ public BlockState getStateForPlacement(@NotNull BlockPlaceContext blockPlaceCont
public void entityInside(BlockState blockState, Level level, BlockPos blockPos, Entity entity) {

if (!level.isClientSide()) {
if (level.getBlockEntity(blockPos) instanceof InternalDoorBlockEntity door) {
door.onAttemptEnter(blockState, level, blockPos, entity);
ServerLevel serverLevel = (ServerLevel)level;
if (serverLevel.getBlockEntity(blockPos) instanceof TardisInternalDoor door) {
AABB teleportAABB = this.getCollisionShape(blockState, level, blockPos, CollisionContext.of(entity)).bounds().move(blockPos);
if (TRTeleporter.teleportIfCollided(serverLevel, blockPos, entity, teleportAABB)){
door.onAttemptEnter(blockState, serverLevel, blockPos, entity);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
Expand All @@ -19,11 +18,15 @@
import net.minecraft.world.level.gameevent.GameEventListener;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import whocraft.tardis_refined.common.blockentity.shell.ShellBaseBlockEntity;
import whocraft.tardis_refined.common.tardis.ExteriorShell;
import whocraft.tardis_refined.common.util.TRTeleporter;

import java.util.List;

public abstract class ShellBaseBlock extends BaseEntityBlock implements SimpleWaterloggedBlock, Fallable {

Expand Down Expand Up @@ -122,16 +125,24 @@ public VoxelShape getShape(BlockState blockState, BlockGetter blockGetter, Block
return EAST_AABB;
}
}

return SOUTH_AABB;
}

@Override
public VoxelShape getCollisionShape(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos, CollisionContext collisionContext) {
return this.getShape(blockState, blockGetter, blockPos, collisionContext);
}


@Override
public void entityInside(BlockState blockState, Level level, BlockPos blockPos, Entity entity) {
if (!level.isClientSide()){
if (level.getBlockEntity(blockPos) instanceof ShellBaseBlockEntity shellEntity) {
shellEntity.onAttemptEnter(blockState, level, shellEntity.getBlockPos(), entity);
ServerLevel serverLevel = (ServerLevel)level;
if (serverLevel.getBlockEntity(blockPos) instanceof ExteriorShell shellEntity) {
AABB teleportAABB = this.getCollisionShape(blockState, level, blockPos, CollisionContext.of(entity)).bounds().move(blockPos);
if (TRTeleporter.teleportIfCollided(serverLevel, blockPos, entity, teleportAABB)) {
shellEntity.onAttemptEnter(blockState, serverLevel, blockPos, entity);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ public BlockPos getDoorPosition() {

@Override
public BlockPos getEntryPosition() {
Direction direction = this.getBlockState().getValue(ShellBaseBlock.FACING);
Direction direction = this.getBlockState().getValue(InternalDoorBlock.FACING);
return this.getBlockPos().offset(direction.getOpposite().getNormal());

}

@Override
public Direction getEntryRotation() {
return getBlockState().getValue(InternalDoorBlock.FACING).getOpposite();
return this.getBlockState().getValue(InternalDoorBlock.FACING).getOpposite();
}

@Override
Expand Down Expand Up @@ -134,6 +134,7 @@ public void load(CompoundTag compoundTag) {
this.isLocked = compoundTag.getBoolean(NbtConstants.DOOR_IS_LOCKED);
}

@Override
public void onAttemptEnter(BlockState blockState, Level level, BlockPos doorPos, Entity entity) {
if(!entity.level().isClientSide() && level instanceof ServerLevel serverLevel){
Optional<TardisLevelOperator> data = TardisLevelOperator.get(serverLevel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerEntity;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;

import java.util.UUID;

Expand All @@ -27,5 +30,6 @@ public interface TardisInternalDoor {
void setLocked(boolean locked);

boolean locked();
void onAttemptEnter(BlockState blockState, Level level, BlockPos doorPos, Entity entity);

}
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public boolean shouldSetup() {
return false;
}

@Override
public void onAttemptEnter(BlockState blockState, Level level, BlockPos externalShellPos, Entity entity) {
if (!entity.level().isClientSide() && level instanceof ServerLevel serverLevel) {
if (this.TARDIS_ID == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public static void tick(ServerLevel level) {
if (teleports.size() != 0){
for (TeleportEntry entry : teleports) {

if (!entry.getIsCurrentTeleporting()) {
if (!entry.getIsCurrentTeleporting() && !entry.getSuccessfulTeleport()) {
entry.setIsCurrentTeleporting(true);

Entity entity = entry.getEntity();
Expand All @@ -74,13 +74,17 @@ public static void tick(ServerLevel level) {
if (entity != null && targetWorld != null && entity.level() == level) {
if (TRTeleporter.performTeleport(entity, targetWorld, entry.getX(), entry.getY(), entry.getZ(), entry.getyRot(), entry.getxRot(), teleportedEntities)) {
teleportedEntities.add(entity);
entry.setIsCurrentTeleporting(true);
}
else {
entry.setSuccessfulTeleport(false);
}
}
}
}

// remove all entities that were teleported from the queue
teleports.removeIf(teleportEntry -> teleportedEntities.contains(teleportEntry.getEntity()));
// remove all entities that were successfully teleported. Also remove failed teleports to prevent a backlog from building up
teleports.removeIf(teleportEntry -> teleportedEntities.contains(teleportEntry.getEntity()) || !teleportEntry.getSuccessfulTeleport());

eventData.queuedTeleports = teleports;
}
Expand Down Expand Up @@ -113,6 +117,8 @@ private static final class TeleportEntry{
private final float yRot, xRot;
private boolean isCurrentTeleporting = false;

private boolean successfulTeleport = false;

public TeleportEntry(Entity entity, ResourceKey<Level> destination, double x, double y, double z, float yRot, float xRot) {
this.entity = entity;
this.destination = destination;
Expand Down Expand Up @@ -158,5 +164,13 @@ public boolean getIsCurrentTeleporting() {
public void setIsCurrentTeleporting(boolean isCurrentTeleporting) {
this.isCurrentTeleporting = isCurrentTeleporting;
}

public boolean getSuccessfulTeleport() {
return successfulTeleport;
}

public void setSuccessfulTeleport(boolean successfulTeleport) {
this.isCurrentTeleporting = successfulTeleport;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import whocraft.tardis_refined.common.tardis.themes.DesktopTheme;

public interface ExteriorShell {
Expand All @@ -14,4 +16,6 @@ public interface ExteriorShell {

void setTardisId(ResourceKey<Level> levelKey);

void onAttemptEnter(BlockState blockState, Level level, BlockPos externalShellPos, Entity entity);

}
Loading

0 comments on commit 5a96b64

Please sign in to comment.