mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-12 13:25:01 +01:00
3D
- Trains can now travel through Aether Portals
This commit is contained in:
parent
3bafe6fe40
commit
1439a52a37
9 changed files with 139 additions and 49 deletions
|
@ -203,6 +203,7 @@ dependencies {
|
|||
// runtimeOnly fg.deobf("slimeknights.tconstruct:TConstruct:1.16.5-3.1.1.252")
|
||||
// runtimeOnly fg.deobf("maven.modrinth:rubidium:0.5.3")
|
||||
// implementation fg.deobf("com.railwayteam.railways:railways-1.18.2-1.1.1:all") { transitive = false }
|
||||
// runtimeOnly fg.deobf("maven.modrinth:aether:1.19.2-1.0.0-beta.1.1-forge")
|
||||
|
||||
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
||||
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
||||
|
|
|
@ -27,7 +27,7 @@ flywheel_version = 0.6.10-20
|
|||
jei_minecraft_version = 1.19.2
|
||||
jei_version = 11.2.0.254
|
||||
curios_minecraft_version = 1.19.2
|
||||
curios_version = 5.1.1.0
|
||||
curios_version = 5.1.4.1
|
||||
|
||||
cc_tweaked_enable = true
|
||||
cc_tweaked_minecraft_version = 1.19.2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
// 1.19.2 2023-05-24T18:02:06.5252419 Create's lang merger
|
||||
12da996b104ab0e5ce956c963fbdae7e59e72f79 assets/create/lang/en_us.json
|
||||
// 1.19.2 2023-09-20T14:31:50.8818458 Create's lang merger
|
||||
532d323119782de6b62f1fe52672941cc9209a40 assets/create/lang/en_us.json
|
||||
|
|
|
@ -868,7 +868,7 @@
|
|||
"advancement.create.train_whistle": "Choo Choo!",
|
||||
"advancement.create.train_whistle.desc": "Assemble a Steam Whistle to your Train and activate it while driving",
|
||||
"advancement.create.train_portal": "Dimensional Commuter",
|
||||
"advancement.create.train_portal.desc": "Ride a Train through a Nether portal",
|
||||
"advancement.create.train_portal.desc": "Ride a Train through a portal",
|
||||
"advancement.create.track_crafting_factory": "Track Factory",
|
||||
"advancement.create.track_crafting_factory.desc": "Produce more than 1000 Train Tracks with the same Mechanical Press",
|
||||
"advancement.create.long_train": "Ambitious Endeavours",
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.simibubi.create.content.redstone.link.RedstoneLinkNetworkHandler;
|
|||
import com.simibubi.create.content.schematics.ServerSchematicLoader;
|
||||
import com.simibubi.create.content.trains.GlobalRailwayManager;
|
||||
import com.simibubi.create.content.trains.bogey.BogeySizes;
|
||||
import com.simibubi.create.content.trains.track.AllPortalTracks;
|
||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.block.CopperRegistries;
|
||||
|
@ -134,6 +135,7 @@ public class Create {
|
|||
// FIXME: some of these registrations are not thread-safe
|
||||
AllMovementBehaviours.registerDefaults();
|
||||
AllInteractionBehaviours.registerDefaults();
|
||||
AllPortalTracks.registerDefaults();
|
||||
AllDisplayBehaviours.registerDefaults();
|
||||
ContraptionMovementSetting.registerDefaults();
|
||||
AllArmInteractionPointTypes.register();
|
||||
|
|
|
@ -295,9 +295,12 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
|||
return PushReaction.IGNORE;
|
||||
}
|
||||
|
||||
public void setPortalEntrancePos() {
|
||||
portalEntrancePos = blockPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PortalInfo findDimensionEntryPoint(ServerLevel pDestination) {
|
||||
portalEntrancePos = blockPosition();
|
||||
return super.findDimensionEntryPoint(pDestination);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
package com.simibubi.create.content.trains.track;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import com.simibubi.create.content.contraptions.glue.SuperGlueEntity;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.simibubi.create.foundation.utility.BlockFace;
|
||||
import com.simibubi.create.foundation.utility.Pair;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.portal.PortalInfo;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraftforge.common.util.ITeleporter;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class AllPortalTracks {
|
||||
|
||||
// Portals must be entered from the side and must lead to a different dimension
|
||||
// than the one entered from
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PortalTrackProvider extends UnaryOperator<Pair<ServerLevel, BlockFace>> {
|
||||
};
|
||||
|
||||
private static final AttachedRegistry<Block, PortalTrackProvider> PORTAL_BEHAVIOURS =
|
||||
new AttachedRegistry<>(ForgeRegistries.BLOCKS);
|
||||
|
||||
public static void registerIntegration(ResourceLocation block, PortalTrackProvider provider) {
|
||||
PORTAL_BEHAVIOURS.register(block, provider);
|
||||
}
|
||||
|
||||
public static void registerIntegration(Block block, PortalTrackProvider provider) {
|
||||
PORTAL_BEHAVIOURS.register(block, provider);
|
||||
}
|
||||
|
||||
public static boolean isSupportedPortal(BlockState state) {
|
||||
return PORTAL_BEHAVIOURS.get(state.getBlock()) != null;
|
||||
}
|
||||
|
||||
public static Pair<ServerLevel, BlockFace> getOtherSide(ServerLevel level, BlockFace inboundTrack) {
|
||||
BlockPos portalPos = inboundTrack.getConnectedPos();
|
||||
BlockState portalState = level.getBlockState(portalPos);
|
||||
PortalTrackProvider provider = PORTAL_BEHAVIOURS.get(portalState.getBlock());
|
||||
return provider == null ? null : provider.apply(Pair.of(level, inboundTrack));
|
||||
}
|
||||
|
||||
// Builtin handlers
|
||||
|
||||
public static void registerDefaults() {
|
||||
registerIntegration(Blocks.NETHER_PORTAL, AllPortalTracks::nether);
|
||||
registerIntegration(new ResourceLocation("aether", "aether_portal"), AllPortalTracks::aether);
|
||||
}
|
||||
|
||||
private static Pair<ServerLevel, BlockFace> nether(Pair<ServerLevel, BlockFace> inbound) {
|
||||
return standardPortalProvider(inbound, Level.OVERWORLD, Level.NETHER, ServerLevel::getPortalForcer);
|
||||
}
|
||||
|
||||
private static Pair<ServerLevel, BlockFace> aether(Pair<ServerLevel, BlockFace> inbound) {
|
||||
ResourceKey<Level> aetherLevelKey =
|
||||
ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation("aether", "the_aether"));
|
||||
return standardPortalProvider(inbound, Level.OVERWORLD, aetherLevelKey, level -> {
|
||||
try {
|
||||
return (ITeleporter) Class.forName("com.aetherteam.aether.block.portal.AetherPortalForcer")
|
||||
.getDeclaredConstructor(ServerLevel.class, boolean.class)
|
||||
.newInstance(level, true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return level.getPortalForcer();
|
||||
});
|
||||
}
|
||||
|
||||
public static Pair<ServerLevel, BlockFace> standardPortalProvider(Pair<ServerLevel, BlockFace> inbound,
|
||||
ResourceKey<Level> firstDimension, ResourceKey<Level> secondDimension,
|
||||
Function<ServerLevel, ITeleporter> customPortalForcer) {
|
||||
ServerLevel level = inbound.getFirst();
|
||||
ResourceKey<Level> resourcekey = level.dimension() == secondDimension ? firstDimension : secondDimension;
|
||||
MinecraftServer minecraftserver = level.getServer();
|
||||
ServerLevel otherLevel = minecraftserver.getLevel(resourcekey);
|
||||
|
||||
if (otherLevel == null || !minecraftserver.isNetherEnabled())
|
||||
return null;
|
||||
|
||||
BlockFace inboundTrack = inbound.getSecond();
|
||||
BlockPos portalPos = inboundTrack.getConnectedPos();
|
||||
BlockState portalState = level.getBlockState(portalPos);
|
||||
ITeleporter teleporter = customPortalForcer.apply(otherLevel);
|
||||
|
||||
SuperGlueEntity probe = new SuperGlueEntity(level, new AABB(portalPos));
|
||||
probe.setYRot(inboundTrack.getFace()
|
||||
.toYRot());
|
||||
probe.setPortalEntrancePos();
|
||||
|
||||
PortalInfo portalinfo = teleporter.getPortalInfo(probe, otherLevel, probe::findDimensionEntryPoint);
|
||||
if (portalinfo == null)
|
||||
return null;
|
||||
|
||||
BlockPos otherPortalPos = new BlockPos(portalinfo.pos);
|
||||
BlockState otherPortalState = otherLevel.getBlockState(otherPortalPos);
|
||||
if (otherPortalState.getBlock() != portalState.getBlock())
|
||||
return null;
|
||||
|
||||
Direction targetDirection = inboundTrack.getFace();
|
||||
if (targetDirection.getAxis() == otherPortalState.getValue(BlockStateProperties.HORIZONTAL_AXIS))
|
||||
targetDirection = targetDirection.getClockWise();
|
||||
BlockPos otherPos = otherPortalPos.relative(targetDirection);
|
||||
return Pair.of(otherLevel, new BlockFace(otherPos, targetDirection.getOpposite()));
|
||||
}
|
||||
|
||||
}
|
|
@ -30,7 +30,6 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.AllPartialModels;
|
||||
import com.simibubi.create.AllShapes;
|
||||
import com.simibubi.create.AllTags;
|
||||
import com.simibubi.create.content.contraptions.glue.SuperGlueEntity;
|
||||
import com.simibubi.create.content.decoration.girder.GirderBlock;
|
||||
import com.simibubi.create.content.equipment.wrench.IWrenchable;
|
||||
import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement;
|
||||
|
@ -63,7 +62,6 @@ import net.minecraft.core.Direction.Axis;
|
|||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
@ -82,7 +80,6 @@ import net.minecraft.world.level.LevelReader;
|
|||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.NetherPortalBlock;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
@ -95,9 +92,6 @@ import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
|||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.level.pathfinder.BlockPathTypes;
|
||||
import net.minecraft.world.level.portal.PortalForcer;
|
||||
import net.minecraft.world.level.portal.PortalInfo;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
|
@ -241,10 +235,10 @@ public class TrackBlock extends Block
|
|||
withBlockEntityDo(level, pos, tbe -> tbe.tilt.undoSmoothing());
|
||||
if (!state.getValue(SHAPE)
|
||||
.isPortal())
|
||||
connectToNether(level, pos, state);
|
||||
connectToPortal(level, pos, state);
|
||||
}
|
||||
|
||||
protected void connectToNether(ServerLevel level, BlockPos pos, BlockState state) {
|
||||
protected void connectToPortal(ServerLevel level, BlockPos pos, BlockState state) {
|
||||
TrackShape shape = state.getValue(TrackBlock.SHAPE);
|
||||
Axis portalTest = shape == TrackShape.XO ? Axis.X : shape == TrackShape.ZO ? Axis.Z : null;
|
||||
if (portalTest == null)
|
||||
|
@ -257,11 +251,11 @@ public class TrackBlock extends Block
|
|||
for (Direction d : Iterate.directionsInAxis(portalTest)) {
|
||||
BlockPos portalPos = pos.relative(d);
|
||||
BlockState portalState = level.getBlockState(portalPos);
|
||||
if (!(portalState.getBlock() instanceof NetherPortalBlock))
|
||||
if (!AllPortalTracks.isSupportedPortal(portalState))
|
||||
continue;
|
||||
|
||||
pop = true;
|
||||
Pair<ServerLevel, BlockFace> otherSide = getOtherSide(level, new BlockFace(pos, d));
|
||||
Pair<ServerLevel, BlockFace> otherSide = AllPortalTracks.getOtherSide(level, new BlockFace(pos, d));
|
||||
if (otherSide == null) {
|
||||
fail = "missing";
|
||||
continue;
|
||||
|
@ -314,38 +308,6 @@ public class TrackBlock extends Block
|
|||
.append(component.withStyle(st -> st.withColor(0xFFD3B4))), false);
|
||||
}
|
||||
|
||||
protected Pair<ServerLevel, BlockFace> getOtherSide(ServerLevel level, BlockFace inboundTrack) {
|
||||
BlockPos portalPos = inboundTrack.getConnectedPos();
|
||||
BlockState portalState = level.getBlockState(portalPos);
|
||||
if (!(portalState.getBlock() instanceof NetherPortalBlock))
|
||||
return null;
|
||||
|
||||
MinecraftServer minecraftserver = level.getServer();
|
||||
ResourceKey<Level> resourcekey = level.dimension() == Level.NETHER ? Level.OVERWORLD : Level.NETHER;
|
||||
ServerLevel otherLevel = minecraftserver.getLevel(resourcekey);
|
||||
if (otherLevel == null || !minecraftserver.isNetherEnabled())
|
||||
return null;
|
||||
|
||||
PortalForcer teleporter = otherLevel.getPortalForcer();
|
||||
SuperGlueEntity probe = new SuperGlueEntity(level, new AABB(portalPos));
|
||||
probe.setYRot(inboundTrack.getFace()
|
||||
.toYRot());
|
||||
PortalInfo portalinfo = teleporter.getPortalInfo(probe, otherLevel, probe::findDimensionEntryPoint);
|
||||
if (portalinfo == null)
|
||||
return null;
|
||||
|
||||
BlockPos otherPortalPos = new BlockPos(portalinfo.pos);
|
||||
BlockState otherPortalState = otherLevel.getBlockState(otherPortalPos);
|
||||
if (!(otherPortalState.getBlock() instanceof NetherPortalBlock))
|
||||
return null;
|
||||
|
||||
Direction targetDirection = inboundTrack.getFace();
|
||||
if (targetDirection.getAxis() == otherPortalState.getValue(NetherPortalBlock.AXIS))
|
||||
targetDirection = targetDirection.getClockWise();
|
||||
BlockPos otherPos = otherPortalPos.relative(targetDirection);
|
||||
return Pair.of(otherLevel, new BlockFace(otherPos, targetDirection.getOpposite()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction pDirection, BlockState pNeighborState,
|
||||
LevelAccessor level, BlockPos pCurrentPos, BlockPos pNeighborPos) {
|
||||
|
@ -362,7 +324,7 @@ public class TrackBlock extends Block
|
|||
|
||||
BlockPos portalPos = pCurrentPos.relative(d);
|
||||
BlockState portalState = level.getBlockState(portalPos);
|
||||
if (!(portalState.getBlock() instanceof NetherPortalBlock))
|
||||
if (!AllPortalTracks.isSupportedPortal(portalState))
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
}
|
||||
|
||||
|
|
|
@ -551,7 +551,7 @@ public class AllAdvancements implements DataProvider {
|
|||
|
||||
TRAIN_PORTAL = create("train_portal", b -> b.icon(Blocks.AMETHYST_BLOCK)
|
||||
.title("Dimensional Commuter")
|
||||
.description("Ride a Train through a Nether portal")
|
||||
.description("Ride a Train through a portal")
|
||||
.after(TRAIN_WHISTLE)
|
||||
.special(NOISY)),
|
||||
|
||||
|
|
Loading…
Reference in a new issue