[Change] Improved Eternal Portal Code
This commit is contained in:
parent
7f8d8bef0c
commit
9f4999c966
10 changed files with 775 additions and 531 deletions
|
@ -3,25 +3,15 @@ package org.betterx.betterend.blocks;
|
|||
import org.betterx.bclib.client.render.BCLRenderLayer;
|
||||
import org.betterx.bclib.interfaces.CustomColorProvider;
|
||||
import org.betterx.bclib.interfaces.RenderLayerProvider;
|
||||
import org.betterx.betterend.advancements.BECriteria;
|
||||
import org.betterx.betterend.interfaces.TeleportingEntity;
|
||||
import org.betterx.betterend.portal.TravelingEntity;
|
||||
import org.betterx.betterend.registry.EndParticles;
|
||||
import org.betterx.betterend.registry.EndPortals;
|
||||
import org.betterx.betterend.rituals.EternalRitual;
|
||||
|
||||
import net.minecraft.client.color.block.BlockColor;
|
||||
import net.minecraft.client.color.item.ItemColor;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
@ -31,19 +21,14 @@ import net.minecraft.world.level.LevelAccessor;
|
|||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.NetherPortalBlock;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class EndPortalBlock extends NetherPortalBlock implements RenderLayerProvider, CustomColorProvider {
|
||||
public static final IntegerProperty PORTAL = EndBlockProperties.PORTAL;
|
||||
|
||||
|
@ -104,39 +89,16 @@ public class EndPortalBlock extends NetherPortalBlock implements RenderLayerProv
|
|||
return state;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
if (world.isClientSide || !validate(entity)) return;
|
||||
entity.setPortalCooldown();
|
||||
ServerLevel currentWorld = (ServerLevel) world;
|
||||
MinecraftServer server = currentWorld.getServer();
|
||||
ServerLevel targetWorld = EndPortals.getWorld(server, state.getValue(PORTAL));
|
||||
boolean isInEnd = currentWorld.dimension().equals(Level.END);
|
||||
ServerLevel destination = isInEnd ? targetWorld : server.getLevel(Level.END);
|
||||
BlockPos exitPos = findExitPos(currentWorld, destination, pos, entity);
|
||||
if (exitPos == null) return;
|
||||
if (entity instanceof ServerPlayer sp && sp.isCreative()) {
|
||||
((ServerPlayer) entity).teleportTo(
|
||||
destination,
|
||||
exitPos.getX() + 0.5,
|
||||
exitPos.getY(),
|
||||
exitPos.getZ() + 0.5,
|
||||
entity.getYRot(),
|
||||
entity.getXRot()
|
||||
);
|
||||
BECriteria.PORTAL_TRAVEL.trigger(sp);
|
||||
} else {
|
||||
if (entity instanceof ServerPlayer sp) {
|
||||
BECriteria.PORTAL_TRAVEL.trigger(sp);
|
||||
}
|
||||
((TeleportingEntity) entity).be_setExitPos(exitPos);
|
||||
Optional<Entity> teleported = Optional.ofNullable(entity.changeDimension(destination));
|
||||
teleported.ifPresent(Entity::setPortalCooldown);
|
||||
if (validate(entity) && entity instanceof TravelingEntity te && te.be_getTravelerState() != null) {
|
||||
te.be_getTravelerState().handleInsidePortal(pos);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean validate(Entity entity) {
|
||||
return !entity.isPassenger() && !entity.isVehicle() && entity.canChangeDimensions() && !entity.isOnPortalCooldown();
|
||||
return !entity.isPassenger() && !entity.isVehicle() && entity.canChangeDimensions();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -144,79 +106,6 @@ public class EndPortalBlock extends NetherPortalBlock implements RenderLayerProv
|
|||
return BCLRenderLayer.TRANSLUCENT;
|
||||
}
|
||||
|
||||
private BlockPos findExitPos(
|
||||
ServerLevel currentWorld,
|
||||
ServerLevel targetWorld,
|
||||
BlockPos currentPos,
|
||||
Entity entity
|
||||
) {
|
||||
if (targetWorld == null) return null;
|
||||
Registry<DimensionType> registry = targetWorld.registryAccess()
|
||||
.registryOrThrow(Registries.DIMENSION_TYPE);
|
||||
ResourceLocation targetWorldId = targetWorld.dimension().location();
|
||||
ResourceLocation currentWorldId = currentWorld.dimension().location();
|
||||
double targetMultiplier = Objects.requireNonNull(registry.get(targetWorldId)).coordinateScale();
|
||||
double currentMultiplier = Objects.requireNonNull(registry.get(currentWorldId)).coordinateScale();
|
||||
double multiplier = targetMultiplier > currentMultiplier ? 1.0 / targetMultiplier : currentMultiplier;
|
||||
MutableBlockPos basePos = currentPos.mutable()
|
||||
.set(
|
||||
currentPos.getX() * multiplier,
|
||||
currentPos.getY(),
|
||||
currentPos.getZ() * multiplier
|
||||
);
|
||||
MutableBlockPos checkPos = basePos.mutable();
|
||||
BlockState currentState = currentWorld.getBlockState(currentPos);
|
||||
int radius = (EternalRitual.SEARCH_RADIUS >> 4) + 1;
|
||||
checkPos = EternalRitual.findBlockPos(
|
||||
targetWorld,
|
||||
checkPos,
|
||||
radius,
|
||||
this,
|
||||
state -> state.is(this) && state.getValue(PORTAL).equals(currentState.getValue(PORTAL))
|
||||
);
|
||||
if (checkPos != null) {
|
||||
BlockState checkState = targetWorld.getBlockState(checkPos);
|
||||
Axis axis = checkState.getValue(AXIS);
|
||||
checkPos = findCenter(targetWorld, checkPos, axis);
|
||||
Direction frontDir = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE).getClockWise();
|
||||
Direction entityDir = entity.getMotionDirection();
|
||||
if (entityDir.getAxis().isVertical()) {
|
||||
entityDir = frontDir;
|
||||
}
|
||||
if (frontDir != entityDir && frontDir.getOpposite() != entityDir) {
|
||||
entity.rotate(Rotation.CLOCKWISE_90);
|
||||
entityDir = entityDir.getClockWise();
|
||||
}
|
||||
return checkPos.relative(entityDir);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private MutableBlockPos findCenter(Level world, MutableBlockPos pos, Direction.Axis axis) {
|
||||
return findCenter(world, pos, axis, 1);
|
||||
}
|
||||
|
||||
private MutableBlockPos findCenter(Level world, MutableBlockPos pos, Direction.Axis axis, int step) {
|
||||
if (step > 8) return pos;
|
||||
BlockState right, left;
|
||||
Direction rightDir, leftDir;
|
||||
rightDir = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE);
|
||||
leftDir = rightDir.getOpposite();
|
||||
right = world.getBlockState(pos.relative(rightDir));
|
||||
left = world.getBlockState(pos.relative(leftDir));
|
||||
BlockState down = world.getBlockState(pos.below());
|
||||
if (down.is(this)) {
|
||||
return findCenter(world, pos.move(Direction.DOWN), axis, step);
|
||||
} else if (right.is(this) && left.is(this)) {
|
||||
return pos;
|
||||
} else if (right.is(this)) {
|
||||
return findCenter(world, pos.move(rightDir), axis, ++step);
|
||||
} else if (left.is(this)) {
|
||||
return findCenter(world, pos.move(leftDir), axis, ++step);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockColor getProvider() {
|
||||
return (state, world, pos, tintIndex) -> EndPortals.getColor(state.getValue(PORTAL));
|
||||
|
|
|
@ -38,11 +38,11 @@ public class EternalPedestal extends PedestalBlock {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void checkRitual(Level world, Player player, BlockPos pos) {
|
||||
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
public void checkRitual(Level sourceLevel, Player player, BlockPos pos) {
|
||||
BlockEntity blockEntity = sourceLevel.getBlockEntity(pos);
|
||||
if (blockEntity instanceof EternalPedestalEntity) {
|
||||
EternalPedestalEntity pedestal = (EternalPedestalEntity) blockEntity;
|
||||
BlockState updatedState = world.getBlockState(pos);
|
||||
BlockState updatedState = sourceLevel.getBlockState(pos);
|
||||
if (pedestal.isEmpty()) {
|
||||
if (pedestal.hasRitual()) {
|
||||
EternalRitual ritual = pedestal.getRitual();
|
||||
|
@ -57,16 +57,19 @@ public class EternalPedestal extends PedestalBlock {
|
|||
ritual.disablePortal(portalId);
|
||||
}
|
||||
}
|
||||
world.setBlockAndUpdate(pos, updatedState.setValue(ACTIVATED, false).setValue(HAS_LIGHT, false));
|
||||
sourceLevel.setBlockAndUpdate(pos, updatedState.setValue(ACTIVATED, false).setValue(HAS_LIGHT, false));
|
||||
} else {
|
||||
ItemStack itemStack = pedestal.getItem(0);
|
||||
ResourceLocation id = BuiltInRegistries.ITEM.getKey(itemStack.getItem());
|
||||
if (EndPortals.isAvailableItem(id)) {
|
||||
world.setBlockAndUpdate(pos, updatedState.setValue(ACTIVATED, true).setValue(HAS_LIGHT, true));
|
||||
sourceLevel.setBlockAndUpdate(
|
||||
pos,
|
||||
updatedState.setValue(ACTIVATED, true).setValue(HAS_LIGHT, true)
|
||||
);
|
||||
if (pedestal.hasRitual()) {
|
||||
pedestal.getRitual().checkStructure(player);
|
||||
} else {
|
||||
EternalRitual ritual = new EternalRitual(world, pos);
|
||||
EternalRitual ritual = new EternalRitual(sourceLevel, pos);
|
||||
ritual.checkStructure(player);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue