diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d84779..1397d1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,16 @@ ## Changelog +**0.0.1-beta 67** +Fix inPortalAmbianceSound and postTPPortalAmbiance sounds + +**0.0.1-beta 66** +Port to 1.21 + +**0.0.1-beta 65.5** +Remove test portals + +**0.0.1-beta 65** +Fix crash when attempting to teleport through an incomplete portal. + **0.0.1-beta 63** Re-Release old 1.19 versions. Fix compat with sodium diff --git a/build.gradle b/build.gradle index b861087..960d4c6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,17 +1,16 @@ plugins { - id 'fabric-loom' version '1.2-SNAPSHOT' + id 'fabric-loom' version '1.9-SNAPSHOT' id 'maven-publish' } -sourceCompatibility = JavaVersion.VERSION_17 -targetCompatibility = JavaVersion.VERSION_17 +sourceCompatibility = JavaVersion.VERSION_21 +targetCompatibility = JavaVersion.VERSION_21 archivesBaseName = project.archives_base_name version = project.mod_version group = project.maven_group repositories { - maven { url "https://api.modrinth.com/maven" } } dependencies { @@ -21,17 +20,6 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - optionalDependency("maven.modrinth:sodium:mc1.20-0.4.10") -} - -def optionalDependency(String dep) { - def exclude = { - exclude group: "net.fabricmc.fabric-api" - exclude group: "net.fabricmc" - } - - dependencies.modCompileOnly(dep, exclude) - //dependencies.modRuntimeOnly(dep, exclude) } processResources { @@ -43,7 +31,7 @@ processResources { } tasks.withType(JavaCompile).configureEach { - it.options.release = 17 + it.options.release = 21 } java { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fae0804..5da0069 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/gradlew b/gradlew index 1b6c787..fcb6fca 100644 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +130,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,6 +197,10 @@ if "$cygwin" || "$msys" ; then done fi + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in @@ -205,6 +213,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd3..93e3f59 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/src/main/java/net/kyrptonaught/customportalapi/CustomPortalBlock.java b/src/main/java/net/kyrptonaught/customportalapi/CustomPortalBlock.java index ba685ed..69d5b2d 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/CustomPortalBlock.java +++ b/src/main/java/net/kyrptonaught/customportalapi/CustomPortalBlock.java @@ -3,15 +3,16 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.kyrptonaught.customportalapi.client.CustomPortalsModClient; -import net.kyrptonaught.customportalapi.interfaces.EntityInCustomPortal; import net.kyrptonaught.customportalapi.portal.frame.PortalFrameTester; import net.kyrptonaught.customportalapi.util.CustomPortalHelper; import net.kyrptonaught.customportalapi.util.CustomTeleporter; import net.kyrptonaught.customportalapi.util.PortalLink; import net.minecraft.block.*; import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.particle.BlockStateParticleEffect; +import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvents; import net.minecraft.state.StateManager; @@ -21,11 +22,11 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; import net.minecraft.util.shape.VoxelShape; -import net.minecraft.world.BlockView; -import net.minecraft.world.World; -import net.minecraft.world.WorldAccess; +import net.minecraft.world.*; +import net.minecraft.world.tick.ScheduledTickView; +import org.jetbrains.annotations.Nullable; -public class CustomPortalBlock extends Block { +public class CustomPortalBlock extends Block implements Portal { public static final EnumProperty AXIS = Properties.AXIS; protected static final VoxelShape X_SHAPE = Block.createCuboidShape(0.0D, 0.0D, 6.0D, 16.0D, 16.0D, 10.0D); protected static final VoxelShape Z_SHAPE = Block.createCuboidShape(6.0D, 0.0D, 0.0D, 10.0D, 16.0D, 16.0D); @@ -45,25 +46,27 @@ public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos po }; } - public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom) { + @Override + protected BlockState getStateForNeighborUpdate(BlockState state, WorldView world, ScheduledTickView tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, Random random) { Block block = getPortalBase((World) world, pos); PortalLink link = CustomPortalApiRegistry.getPortalLinkFromBase(block); if (link != null) { - PortalFrameTester portalFrameTester = link.getFrameTester().createInstanceOfPortalFrameTester().init(world, pos, CustomPortalHelper.getAxisFrom(state), block); + PortalFrameTester portalFrameTester = link.getFrameTester().createInstanceOfPortalFrameTester().init((WorldAccess) world, pos, CustomPortalHelper.getAxisFrom(state), block); if (portalFrameTester.isAlreadyLitPortalFrame()) - return super.getStateForNeighborUpdate(state, direction, newState, world, pos, posFrom); + return super.getStateForNeighborUpdate(state, world, tickView, pos, direction, neighborPos, neighborState, random); } //todo handle unknown portallink return Blocks.AIR.getDefaultState(); } + @Override protected void appendProperties(StateManager.Builder builder) { builder.add(AXIS); } - @Environment(EnvType.CLIENT) - public ItemStack getPickStack(BlockView world, BlockPos pos, BlockState state) { + @Override + protected ItemStack getPickStack(WorldView world, BlockPos pos, BlockState state, boolean includeData) { return ItemStack.EMPTY; } @@ -98,21 +101,33 @@ public void randomDisplayTick(BlockState state, World world, BlockPos pos, Rando } } - @Override public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { - EntityInCustomPortal entityInPortal = (EntityInCustomPortal) entity; - entityInPortal.tickInPortal(pos.toImmutable()); - if (!entityInPortal.didTeleport()) { - if (entityInPortal.getTimeInPortal() >= entity.getMaxNetherPortalTime()) { - entityInPortal.setDidTP(true); - if (!world.isClient) - CustomTeleporter.TPToDim(world, entity, getPortalBase(world, pos), pos); - } + if (entity.canUsePortals(false)) { + entity.tryUsePortal(this, pos); } } public Block getPortalBase(World world, BlockPos pos) { return CustomPortalHelper.getPortalBaseDefault(world, pos); } + + @Override + public int getPortalDelay(ServerWorld world, Entity entity) { + if (entity instanceof PlayerEntity playerEntity) { + return Math.max(1, world.getGameRules().getInt(playerEntity.getAbilities().invulnerable ? GameRules.PLAYERS_NETHER_PORTAL_CREATIVE_DELAY : GameRules.PLAYERS_NETHER_PORTAL_DEFAULT_DELAY)); + } else { + return 0; + } + } + + @Override + public @Nullable TeleportTarget createTeleportTarget(ServerWorld world, Entity entity, BlockPos pos) { + return CustomTeleporter.createTeleportTarget(world, entity, getPortalBase(world, pos), pos); + } + + @Override + public Effect getPortalEffect() { + return Effect.CONFUSION; + } } \ No newline at end of file diff --git a/src/main/java/net/kyrptonaught/customportalapi/CustomPortalsMod.java b/src/main/java/net/kyrptonaught/customportalapi/CustomPortalsMod.java index 4bbb597..73a79fa 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/CustomPortalsMod.java +++ b/src/main/java/net/kyrptonaught/customportalapi/CustomPortalsMod.java @@ -3,7 +3,11 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.player.UseItemCallback; +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.kyrptonaught.customportalapi.api.CustomPortalBuilder; +import net.kyrptonaught.customportalapi.event.CPASoundEventData; +import net.kyrptonaught.customportalapi.networking.ForcePlacePacket; +import net.kyrptonaught.customportalapi.networking.LinkSyncPacket; import net.kyrptonaught.customportalapi.portal.PortalIgnitionSource; import net.kyrptonaught.customportalapi.portal.PortalPlacer; import net.kyrptonaught.customportalapi.portal.frame.FlatPortalAreaHelper; @@ -18,26 +22,31 @@ import net.minecraft.item.Items; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.ActionResult; import net.minecraft.util.Identifier; -import net.minecraft.util.TypedActionResult; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.PersistentStateManager; import net.minecraft.world.World; public class CustomPortalsMod implements ModInitializer { public static final String MOD_ID = "customportalapi"; public static CustomPortalBlock portalBlock; - public static Identifier VANILLAPORTAL_FRAMETESTER = new Identifier(MOD_ID, "vanillanether"); - public static Identifier FLATPORTAL_FRAMETESTER = new Identifier(MOD_ID, "flat"); + public static Identifier VANILLAPORTAL_FRAMETESTER = Identifier.of(MOD_ID, "vanillanether"); + public static Identifier FLATPORTAL_FRAMETESTER = Identifier.of(MOD_ID, "flat"); public static PortalLinkingStorage portalLinkingStorage; @Override public void onInitialize() { ServerLifecycleEvents.SERVER_STARTED.register(server -> { - portalLinkingStorage = (PortalLinkingStorage) server.getWorld(World.OVERWORLD).getPersistentStateManager().getOrCreate(PortalLinkingStorage::fromNbt, PortalLinkingStorage::new, MOD_ID); + PersistentStateManager persistentStateManager = server.getWorld(World.OVERWORLD).getPersistentStateManager(); + portalLinkingStorage = persistentStateManager.getOrCreate(PortalLinkingStorage.getPersistentStateType(), MOD_ID); }); CustomPortalApiRegistry.registerPortalFrameTester(VANILLAPORTAL_FRAMETESTER, VanillaPortalAreaHelper::new); CustomPortalApiRegistry.registerPortalFrameTester(FLATPORTAL_FRAMETESTER, FlatPortalAreaHelper::new); @@ -51,18 +60,33 @@ public void onInitialize() { BlockHitResult blockHit = (BlockHitResult) hit; BlockPos usedBlockPos = blockHit.getBlockPos(); if (PortalPlacer.attemptPortalLight(world, usedBlockPos.offset(blockHit.getSide()), PortalIgnitionSource.ItemUseSource(item).withPlayer(player))) { - return TypedActionResult.success(stack); + return ActionResult.SUCCESS_SERVER; } } } } - return TypedActionResult.pass(stack); + return ActionResult.PASS; })); - //CustomPortalBuilder.beginPortal().frameBlock(Blocks.GLOWSTONE).destDimID(new Identifier("the_nether")).lightWithWater().setPortalSearchYRange(126, 256).tintColor(125, 20, 20).registerPortal(); - //CustomPortalBuilder.beginPortal().frameBlock(Blocks.OBSIDIAN).destDimID(new Identifier("the_end")).tintColor(66, 135, 245).registerPortalForced(); - //CustomPortalBuilder.beginPortal().frameBlock(Blocks.COBBLESTONE).lightWithItem(Items.STICK).destDimID(new Identifier("the_end")).tintColor(45, 24, 45).flatPortal().registerPortal(); - //CustomPortalBuilder.beginPortal().frameBlock(Blocks.EMERALD_BLOCK).lightWithWater().destDimID(new Identifier("the_end")).tintColor(25, 76, 156).flatPortal().registerPortal(); + PayloadTypeRegistry.playS2C().register(LinkSyncPacket.PACKET_ID, LinkSyncPacket.codec); + PayloadTypeRegistry.playS2C().register(ForcePlacePacket.PACKET_ID, ForcePlacePacket.codec); + + //CustomPortalBuilder.beginPortal().frameBlock(Blocks.GLOWSTONE).destDimID(Identifier.of("the_nether")).lightWithWater().setPortalSearchYRange(126, 256).tintColor(125, 20, 20).registerPortal(); + //CustomPortalBuilder.beginPortal().frameBlock(Blocks.OBSIDIAN).destDimID(Identifier.of("the_end")).tintColor(66, 135, 245).registerPortalForced(); + //CustomPortalBuilder.beginPortal().frameBlock(Blocks.COBBLESTONE).lightWithItem(Items.STICK).destDimID(Identifier.of("the_end")).tintColor(45, 24, 45).flatPortal().registerPortal(); + /* + CustomPortalBuilder.beginPortal() + .frameBlock(Blocks.EMERALD_BLOCK) + .lightWithWater() + .destDimID(Identifier.of("the_end")) + .tintColor(25, 76, 156) + .flatPortal() + .registerInPortalAmbienceSound(player -> new CPASoundEventData(SoundEvents.BLOCK_ANVIL_LAND, player.getRandom().nextFloat() * 0.4F + 0.8F, 0.25F)) + .registerPostTPPortalAmbience(player -> new CPASoundEventData(SoundEvents.BLOCK_ANVIL_LAND, player.getRandom().nextFloat() * 0.4F + 0.8F, 0.25F)) + .registerPortal(); + + */ + } public static void logError(String message) { @@ -76,7 +100,17 @@ public static Block getDefaultPortalBlock() { // to guarantee block exists before use, unsure how safe this is but works for now. Don't want to switch to using a custom entrypoint to break compatibility with existing mods just yet //todo fix this with CustomPortalBuilder? static { - portalBlock = new CustomPortalBlock(AbstractBlock.Settings.create().noCollision().ticksRandomly().strength(-1.0f).sounds(BlockSoundGroup.GLASS).luminance(state -> 11).pistonBehavior(PistonBehavior.BLOCK)); - Registry.register(Registries.BLOCK, new Identifier(CustomPortalsMod.MOD_ID, "customportalblock"), portalBlock); + portalBlock = (CustomPortalBlock) Blocks.register( + RegistryKey.of(RegistryKeys.BLOCK, Identifier.of(CustomPortalsMod.MOD_ID, "customportalblock")), + CustomPortalBlock::new, + AbstractBlock.Settings.create() + .noCollision() + .ticksRandomly() + .strength(-1.0f) + .sounds(BlockSoundGroup.GLASS) + .luminance(state -> 11) + .pistonBehavior(PistonBehavior.BLOCK) + ); + } -} \ No newline at end of file +} diff --git a/src/main/java/net/kyrptonaught/customportalapi/api/CustomPortalBuilder.java b/src/main/java/net/kyrptonaught/customportalapi/api/CustomPortalBuilder.java index 568fe3e..90aea4f 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/api/CustomPortalBuilder.java +++ b/src/main/java/net/kyrptonaught/customportalapi/api/CustomPortalBuilder.java @@ -277,7 +277,7 @@ public CustomPortalBuilder registerIgniteEvent(PortalIgniteEvent event) { * * @param bottomY the lowest Y level to create a portal. * @param topY the highest Y level to create a portal. - * @see net.kyrptonaught.customportalapi.api.CustomPortalBuilder#setReturnPortalSearchYRange(int, int) + * @see CustomPortalBuilder#setReturnPortalSearchYRange(int, int) */ public CustomPortalBuilder setPortalSearchYRange(int bottomY, int topY) { portalLink.portalSearchYBottom = bottomY; @@ -291,7 +291,7 @@ public CustomPortalBuilder setPortalSearchYRange(int bottomY, int topY) { * * @param bottomY the lowest Y level to create a portal. * @param topY the highest Y level to create a portal. - * @see net.kyrptonaught.customportalapi.api.CustomPortalBuilder#setPortalSearchYRange(int, int) + * @see CustomPortalBuilder#setPortalSearchYRange(int, int) */ public CustomPortalBuilder setReturnPortalSearchYRange(int bottomY, int topY) { portalLink.returnPortalSearchYBottom = bottomY; diff --git a/src/main/java/net/kyrptonaught/customportalapi/client/CustomPortalsModClient.java b/src/main/java/net/kyrptonaught/customportalapi/client/CustomPortalsModClient.java index be83a50..12ab4db 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/client/CustomPortalsModClient.java +++ b/src/main/java/net/kyrptonaught/customportalapi/client/CustomPortalsModClient.java @@ -11,8 +11,7 @@ import net.kyrptonaught.customportalapi.CustomPortalApiRegistry; import net.kyrptonaught.customportalapi.CustomPortalsMod; import net.kyrptonaught.customportalapi.PerWorldPortals; -import net.kyrptonaught.customportalapi.networking.ForcePlacePortalPacket; -import net.kyrptonaught.customportalapi.networking.PortalRegistrySync; +import net.kyrptonaught.customportalapi.networking.NetworkManager; import net.kyrptonaught.customportalapi.util.CustomPortalHelper; import net.kyrptonaught.customportalapi.util.PortalLink; import net.minecraft.block.Block; @@ -25,7 +24,8 @@ @Environment(EnvType.CLIENT) public class CustomPortalsModClient implements ClientModInitializer { - public static final ParticleType CUSTOMPORTALPARTICLE = Registry.register(Registries.PARTICLE_TYPE, CustomPortalsMod.MOD_ID + ":customportalparticle", FabricParticleTypes.complex(BlockStateParticleEffect.PARAMETERS_FACTORY)); + + public static ParticleType CUSTOMPORTALPARTICLE = FabricParticleTypes.complex(BlockStateParticleEffect::createCodec, BlockStateParticleEffect::createPacketCodec); @Override public void onInitializeClient() { @@ -39,10 +39,10 @@ public void onInitializeClient() { return 1908001; }, CustomPortalsMod.portalBlock); + Registry.register(Registries.PARTICLE_TYPE, CustomPortalsMod.MOD_ID + ":customportalparticle", CUSTOMPORTALPARTICLE); ParticleFactoryRegistry.getInstance().register(CUSTOMPORTALPARTICLE, CustomPortalParticle.Factory::new); - PortalRegistrySync.registerReceivePortalData(); - ForcePlacePortalPacket.registerReceive(); + NetworkManager.registerPackets(); ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> { PerWorldPortals.removeOldPortalsFromRegistry(); }); diff --git a/src/main/java/net/kyrptonaught/customportalapi/interfaces/ClientPlayerInColoredPortal.java b/src/main/java/net/kyrptonaught/customportalapi/interfaces/ClientPlayerInColoredPortal.java deleted file mode 100644 index f774eed..0000000 --- a/src/main/java/net/kyrptonaught/customportalapi/interfaces/ClientPlayerInColoredPortal.java +++ /dev/null @@ -1,14 +0,0 @@ -package net.kyrptonaught.customportalapi.interfaces; - - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - -@Environment(EnvType.CLIENT) -public interface ClientPlayerInColoredPortal { - - void setLastUsedPortalColor(int color); - - int getLastUsedPortalColor(); - -} diff --git a/src/main/java/net/kyrptonaught/customportalapi/interfaces/CustomTeleportingEntity.java b/src/main/java/net/kyrptonaught/customportalapi/interfaces/CustomTeleportingEntity.java deleted file mode 100644 index 705e99c..0000000 --- a/src/main/java/net/kyrptonaught/customportalapi/interfaces/CustomTeleportingEntity.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.kyrptonaught.customportalapi.interfaces; - -import net.minecraft.world.TeleportTarget; - -public interface CustomTeleportingEntity { - - void setCustomTeleportTarget(TeleportTarget teleportTarget); - - TeleportTarget getCustomTeleportTarget(); -} diff --git a/src/main/java/net/kyrptonaught/customportalapi/interfaces/EntityInCustomPortal.java b/src/main/java/net/kyrptonaught/customportalapi/interfaces/EntityInCustomPortal.java deleted file mode 100644 index a418e6f..0000000 --- a/src/main/java/net/kyrptonaught/customportalapi/interfaces/EntityInCustomPortal.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.kyrptonaught.customportalapi.interfaces; - -import net.minecraft.util.math.BlockPos; - -public interface EntityInCustomPortal { - - int getTimeInPortal(); - - boolean didTeleport(); - - void setDidTP(boolean didTP); - - void tickInPortal(BlockPos portalPos); - - BlockPos getInPortalPos(); -} diff --git a/src/main/java/net/kyrptonaught/customportalapi/mixin/ServerPlayerMixin.java b/src/main/java/net/kyrptonaught/customportalapi/mixin/ServerPlayerMixin.java deleted file mode 100644 index 5a5a3a9..0000000 --- a/src/main/java/net/kyrptonaught/customportalapi/mixin/ServerPlayerMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.kyrptonaught.customportalapi.mixin; - -import net.kyrptonaught.customportalapi.CustomPortalsMod; -import net.kyrptonaught.customportalapi.interfaces.EntityInCustomPortal; -import net.kyrptonaught.customportalapi.util.CustomPortalHelper; -import net.minecraft.block.Block; -import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.s2c.play.WorldEventS2CPacket; -import net.minecraft.registry.Registries; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.server.network.ServerPlayNetworkHandler; -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.world.World; -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.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ServerPlayerEntity.class) -public abstract class ServerPlayerMixin implements EntityInCustomPortal { - int portalFrameBlockID; - - @Redirect(method = "moveToWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;getRegistryKey()Lnet/minecraft/registry/RegistryKey;", ordinal = 0)) - public RegistryKey CPApreventEndCredits(ServerWorld serverWorld) { - if (this.didTeleport()) { - Block portalFrame = CustomPortalHelper.getPortalBase(serverWorld, getInPortalPos()); - portalFrameBlockID = Registries.BLOCK.getRawId(portalFrame); - return RegistryKey.of(RegistryKeys.WORLD, new Identifier(CustomPortalsMod.MOD_ID, "nullworld")); - } - return serverWorld.getRegistryKey(); - } - - @Inject(method = "createEndSpawnPlatform", at = @At("HEAD"), cancellable = true) - public void CPAcancelEndPlatformSpawn(ServerWorld world, BlockPos centerPos, CallbackInfo ci) { - if (this.didTeleport()) ci.cancel(); - } - - @Redirect(method = "moveToWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V")) - public void CPAmodifyWorldEventPacket(ServerPlayNetworkHandler instance, Packet packet) { - if (packet instanceof WorldEventS2CPacket && portalFrameBlockID != 0) { - instance.sendPacket(new WorldEventS2CPacket(1032, BlockPos.ORIGIN, portalFrameBlockID, false)); - portalFrameBlockID = 0; - } else - instance.sendPacket(packet); - } -} diff --git a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/ClientPlayNetworkHandlerMixin.java b/src/main/java/net/kyrptonaught/customportalapi/mixin/client/ClientPlayNetworkHandlerMixin.java deleted file mode 100644 index 7827588..0000000 --- a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/ClientPlayNetworkHandlerMixin.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.kyrptonaught.customportalapi.mixin.client; - -import net.kyrptonaught.customportalapi.interfaces.ClientPlayerInColoredPortal; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.network.ClientPlayerInteractionManager; -import net.minecraft.client.recipebook.ClientRecipeBook; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.stat.StatHandler; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(ClientPlayNetworkHandler.class) -public class ClientPlayNetworkHandlerMixin { - - @Redirect(method = "onPlayerRespawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;createPlayer(Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/stat/StatHandler;Lnet/minecraft/client/recipebook/ClientRecipeBook;ZZ)Lnet/minecraft/client/network/ClientPlayerEntity;")) - public ClientPlayerEntity teleported(ClientPlayerInteractionManager instance, ClientWorld world, StatHandler statHandler, ClientRecipeBook recipeBook, boolean lastSneaking, boolean lastSprinting) { - ClientPlayerEntity newPlayer = instance.createPlayer(world, statHandler, recipeBook, lastSneaking, lastSprinting); - ((ClientPlayerInColoredPortal) newPlayer).setLastUsedPortalColor(-999); - return newPlayer; - } -} \ No newline at end of file diff --git a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/ClientPlayerEntityMixin.java b/src/main/java/net/kyrptonaught/customportalapi/mixin/client/ClientPlayerEntityMixin.java new file mode 100644 index 0000000..3f8b47f --- /dev/null +++ b/src/main/java/net/kyrptonaught/customportalapi/mixin/client/ClientPlayerEntityMixin.java @@ -0,0 +1,42 @@ +package net.kyrptonaught.customportalapi.mixin.client; + +import net.kyrptonaught.customportalapi.CustomPortalApiRegistry; +import net.kyrptonaught.customportalapi.CustomPortalBlock; +import net.kyrptonaught.customportalapi.util.PortalLink; +import net.minecraft.block.Portal; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.sound.SoundInstance; +import net.minecraft.client.sound.SoundManager; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.dimension.PortalManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(ClientPlayerEntity.class) +public class ClientPlayerEntityMixin { + + @Redirect(method = "tickNausea", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/sound/SoundManager;play(Lnet/minecraft/client/sound/SoundInstance;)V")) + public void playCustomPortalAmbiance(SoundManager instance, SoundInstance sound) { + ClientPlayerEntity player = (ClientPlayerEntity) (Object) this; + PortalLink link = isCustomPortal(player); + if (link != null && link.getInPortalAmbienceEvent().hasEvent()) { + instance.play(link.getInPortalAmbienceEvent().execute(player).getInstance()); + return; + } + instance.play(sound); + } + + @Unique + private PortalLink isCustomPortal(ClientPlayerEntity player) { + PortalManager portalManager = player.portalManager; + Portal portalBlock = portalManager != null && portalManager.isInPortal() ? ((PortalManagerAccessor) portalManager).getPortal() : null; + BlockPos portalPos = portalManager != null && portalManager.isInPortal() ? ((PortalManagerAccessor) portalManager).getPos() : null; + + if (portalBlock instanceof CustomPortalBlock) + return CustomPortalApiRegistry.getPortalLinkFromBase(((CustomPortalBlock) portalBlock).getPortalBase(player.clientWorld, portalPos)); + + return null; + } +} diff --git a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/ClientPlayerMixin.java b/src/main/java/net/kyrptonaught/customportalapi/mixin/client/ClientPlayerMixin.java deleted file mode 100644 index a569196..0000000 --- a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/ClientPlayerMixin.java +++ /dev/null @@ -1,118 +0,0 @@ -package net.kyrptonaught.customportalapi.mixin.client; - - -import com.mojang.authlib.GameProfile; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.kyrptonaught.customportalapi.CustomPortalApiRegistry; -import net.kyrptonaught.customportalapi.interfaces.ClientPlayerInColoredPortal; -import net.kyrptonaught.customportalapi.interfaces.EntityInCustomPortal; -import net.kyrptonaught.customportalapi.util.CustomPortalHelper; -import net.kyrptonaught.customportalapi.util.PortalLink; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.DeathScreen; -import net.minecraft.client.gui.screen.DownloadingTerrainScreen; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.sound.PositionedSoundInstance; -import net.minecraft.entity.effect.StatusEffects; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.network.encryption.PlayerPublicKey; -import net.minecraft.sound.SoundEvents; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -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; - -@Environment(EnvType.CLIENT) -@Mixin(ClientPlayerEntity.class) -public abstract class ClientPlayerMixin extends PlayerEntity implements EntityInCustomPortal, ClientPlayerInColoredPortal { - - @Shadow - @Final - protected MinecraftClient client; - - public ClientPlayerMixin(World world, BlockPos pos, float yaw, GameProfile gameProfile) { - super(world, pos, yaw, gameProfile); - } - - - @Shadow - public abstract void closeHandledScreen(); - - @Shadow public float prevNauseaIntensity; - @Shadow public float nauseaIntensity; - int portalColor; - - @Override - public void setLastUsedPortalColor(int color) { - this.portalColor = color; - - } - - @Override - public int getLastUsedPortalColor() { - return portalColor; - } - - - @Inject(method = "updateNausea", at = @At(value = "HEAD"), cancellable = true) - public void injectCustomNausea(CallbackInfo ci) { - if (this.inNetherPortal) { - setLastUsedPortalColor(-1); - } else if (this.getTimeInPortal() > 0) { - int previousColor = getLastUsedPortalColor(); - PortalLink link = this.getInPortalPos() != null ? CustomPortalApiRegistry.getPortalLinkFromBase(CustomPortalHelper.getPortalBase(this.getWorld(), this.getInPortalPos())) : null; - if (link != null) - setLastUsedPortalColor(link.colorID); - updateCustomNausea(previousColor); - ci.cancel(); - } - } - - @Unique - private void updateCustomNausea(int previousColor) { - this.prevNauseaIntensity = this.nauseaIntensity; - if (this.getTimeInPortal() > 0) { - if (this.client.currentScreen != null && !this.client.currentScreen.shouldPause() && !(this.client.currentScreen instanceof DeathScreen) && !(this.client.currentScreen instanceof DownloadingTerrainScreen)) { - if (this.client.currentScreen instanceof HandledScreen) { - this.closeHandledScreen(); - } - this.client.setScreen(null); - } - - if (this.nauseaIntensity == 0.0F && previousColor != -999) { //previous color prevents this from playing after a teleport. A tp sets the previousColor to -999 - PortalLink link = CustomPortalApiRegistry.getPortalLinkFromBase(CustomPortalHelper.getPortalBase(getWorld(), getInPortalPos())); - if (link != null && link.getInPortalAmbienceEvent().hasEvent()) { - this.client.getSoundManager().play(link.getInPortalAmbienceEvent().execute(this).getInstance()); - } else - this.client.getSoundManager().play(PositionedSoundInstance.ambient(SoundEvents.BLOCK_PORTAL_TRIGGER, this.random.nextFloat() * 0.4F + 0.8F, 0.25F)); - } - - this.nauseaIntensity += 0.0125F; - if (this.nauseaIntensity >= 1.0F) { - this.nauseaIntensity = 1.0F; - } - } else if (this.hasStatusEffect(StatusEffects.NAUSEA) && this.getStatusEffect(StatusEffects.NAUSEA).getDuration() > 60) { - this.nauseaIntensity += 0.006666667F; - if (this.nauseaIntensity > 1.0F) { - this.nauseaIntensity = 1.0F; - } - } else { - if (this.nauseaIntensity > 0.0F) { - this.nauseaIntensity -= 0.05F; - } - - if (this.nauseaIntensity < 0.0F) { - this.nauseaIntensity = 0.0F; - } - } - } -} diff --git a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/InGameHudMixin.java b/src/main/java/net/kyrptonaught/customportalapi/mixin/client/InGameHudMixin.java index f984a57..da64717 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/InGameHudMixin.java +++ b/src/main/java/net/kyrptonaught/customportalapi/mixin/client/InGameHudMixin.java @@ -3,19 +3,26 @@ import com.mojang.blaze3d.systems.RenderSystem; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.kyrptonaught.customportalapi.CustomPortalApiRegistry; +import net.kyrptonaught.customportalapi.CustomPortalBlock; import net.kyrptonaught.customportalapi.CustomPortalsMod; -import net.kyrptonaught.customportalapi.interfaces.ClientPlayerInColoredPortal; import net.kyrptonaught.customportalapi.util.ColorUtil; +import net.kyrptonaught.customportalapi.util.PortalLink; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.block.Portal; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.render.block.BlockModels; import net.minecraft.client.texture.Sprite; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ColorHelper; +import net.minecraft.world.dimension.PortalManager; import org.spongepowered.asm.mixin.Final; 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.Redirect; @@ -27,21 +34,44 @@ public class InGameHudMixin { @Final private MinecraftClient client; - @Redirect(method = "renderPortalOverlay", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;setShaderColor(FFFF)V", ordinal = 0)) - public void changeColor(DrawContext instance, float red, float green, float blue, float alpha) { - int color = ((ClientPlayerInColoredPortal) client.player).getLastUsedPortalColor(); - if (color >= 0) { - float[] colors = ColorUtil.getColorForBlock(color); - RenderSystem.setShaderColor(colors[0], colors[1], colors[2], alpha); - } else - RenderSystem.setShaderColor(red, green, blue, alpha); + @Unique + private int lastColor = -1; + + @Redirect(method = "renderPortalOverlay", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/ColorHelper;getWhite(F)I", ordinal = 0)) + public int changeColor(float alpha) { + isCustomPortal(client.player); + if (lastColor >= 0) + return ColorHelper.withAlpha(ColorHelper.channelFromFloat(alpha), lastColor); + return ColorHelper.getWhite(alpha); } @Redirect(method = "renderPortalOverlay", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockModels;getModelParticleSprite(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/texture/Sprite;")) public Sprite renderCustomPortalOverlay(BlockModels blockModels, BlockState blockState) { - if (((ClientPlayerInColoredPortal) client.player).getLastUsedPortalColor() >= 0) { + if (lastColor >= 0) { return this.client.getBlockRenderManager().getModels().getModelParticleSprite(CustomPortalsMod.portalBlock.getDefaultState()); } return this.client.getBlockRenderManager().getModels().getModelParticleSprite(Blocks.NETHER_PORTAL.getDefaultState()); } + + + @Unique + private void isCustomPortal(ClientPlayerEntity player) { + PortalManager portalManager = player.portalManager; + Portal portalBlock = portalManager != null && portalManager.isInPortal() ? ((PortalManagerAccessor) portalManager).getPortal() : null; + BlockPos portalPos = portalManager != null && portalManager.isInPortal() ? ((PortalManagerAccessor) portalManager).getPos() : null; + + if (portalBlock == null) { + return; + } + + if (portalBlock instanceof CustomPortalBlock) { + PortalLink link = CustomPortalApiRegistry.getPortalLinkFromBase(((CustomPortalBlock) portalBlock).getPortalBase(player.clientWorld, portalPos)); + if (link != null) { + lastColor = link.colorID; + return; + } + } + + lastColor = -1; + } } diff --git a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/PortalManagerAccessor.java b/src/main/java/net/kyrptonaught/customportalapi/mixin/client/PortalManagerAccessor.java new file mode 100644 index 0000000..be1f73b --- /dev/null +++ b/src/main/java/net/kyrptonaught/customportalapi/mixin/client/PortalManagerAccessor.java @@ -0,0 +1,17 @@ +package net.kyrptonaught.customportalapi.mixin.client; + +import net.minecraft.block.Portal; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.dimension.PortalManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(PortalManager.class) +public interface PortalManagerAccessor { + + @Accessor + Portal getPortal(); + + @Accessor + BlockPos getPos(); +} diff --git a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/SodiumBlendingFix.java b/src/main/java/net/kyrptonaught/customportalapi/mixin/client/SodiumBlendingFix.java deleted file mode 100644 index f9dd2f6..0000000 --- a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/SodiumBlendingFix.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.kyrptonaught.customportalapi.mixin.client; - -import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView; -import me.jellysquid.mods.sodium.client.model.quad.blender.ColorSampler; -import me.jellysquid.mods.sodium.client.util.color.ColorARGB; -import net.kyrptonaught.customportalapi.CustomPortalBlock; -import net.minecraft.block.BlockState; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.BlockRenderView; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Pseudo -@Mixin(targets = "me.jellysquid.mods.sodium.client.model.quad.blender.LinearColorBlender") -public abstract class SodiumBlendingFix { - - @Shadow(remap = false) - protected abstract int getBlockColor(BlockRenderView world, T state, ColorSampler sampler, int x, int y, int z, int colorIdx); - - @Inject(method = "getVertexColor", at = @At("HEAD"), cancellable = true, remap = false, require = 0) - private void onGetVertexColor(BlockRenderView world, BlockPos origin, ModelQuadView quad, ColorSampler sampler, T state, int vertexIdx, CallbackInfoReturnable info) { - // credit to https://github.com/Juuxel/unofficial-sodium-biome-blending-fix - if (state instanceof BlockState && ((BlockState) state).getBlock() instanceof CustomPortalBlock) { - int color = getBlockColor(world, state, sampler, origin.getX(), origin.getY(), origin.getZ(), quad.getColorIndex()); - info.setReturnValue(ColorARGB.toABGR(color)); - } - } -} diff --git a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/WorldRendererMixin.java b/src/main/java/net/kyrptonaught/customportalapi/mixin/client/WorldRendererMixin.java index f6c7de9..df3c40a 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/mixin/client/WorldRendererMixin.java +++ b/src/main/java/net/kyrptonaught/customportalapi/mixin/client/WorldRendererMixin.java @@ -7,30 +7,34 @@ import net.minecraft.client.render.WorldRenderer; import net.minecraft.client.sound.SoundInstance; import net.minecraft.client.sound.SoundManager; +import net.minecraft.client.world.WorldEventHandler; import net.minecraft.registry.Registries; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.WorldAccess; +import net.minecraft.world.WorldEvents; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(WorldRenderer.class) +@Mixin(WorldEventHandler.class) public class WorldRendererMixin { @Shadow @Final private MinecraftClient client; - @Redirect(method = "processWorldEvent", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/sound/SoundManager;play(Lnet/minecraft/client/sound/SoundInstance;)V")) + @Redirect(method = "processWorldEvent(ILnet/minecraft/util/math/BlockPos;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/sound/SoundManager;play(Lnet/minecraft/client/sound/SoundInstance;)V")) public void CPA$postTPSoundEvent(SoundManager instance, SoundInstance sound, int eventId, BlockPos pos, int data) { if (eventId == 1032 && data != 0) { Block block = Registries.BLOCK.get(data); PortalLink link = CustomPortalApiRegistry.getPortalLinkFromBase(block); - if (link != null && link.getPostTpPortalAmbienceEvent().hasEvent()) + if (link != null && link.getPostTpPortalAmbienceEvent().hasEvent()) { instance.play(link.getPostTpPortalAmbienceEvent().execute(client.player).getInstance()); - } else { - instance.play(sound); + return; + } } + instance.play(sound); } } diff --git a/src/main/java/net/kyrptonaught/customportalapi/networking/ForcePlacePacket.java b/src/main/java/net/kyrptonaught/customportalapi/networking/ForcePlacePacket.java new file mode 100644 index 0000000..1ae4f48 --- /dev/null +++ b/src/main/java/net/kyrptonaught/customportalapi/networking/ForcePlacePacket.java @@ -0,0 +1,27 @@ +package net.kyrptonaught.customportalapi.networking; + +import net.kyrptonaught.customportalapi.CustomPortalsMod; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; + +public record ForcePlacePacket(BlockPos pos, int axis) implements CustomPayload { + public static final CustomPayload.Id PACKET_ID = new CustomPayload.Id<>(Identifier.of(CustomPortalsMod.MOD_ID, "forceplace")); + public static final PacketCodec codec = PacketCodec.of(ForcePlacePacket::write, ForcePlacePacket::read); + + public static ForcePlacePacket read(RegistryByteBuf buf) { + return new ForcePlacePacket(buf.readBlockPos(), buf.readInt()); + } + + public void write(RegistryByteBuf buf) { + buf.writeBlockPos(pos); + buf.writeInt(axis); + } + + @Override + public Id getId() { + return PACKET_ID; + } +} \ No newline at end of file diff --git a/src/main/java/net/kyrptonaught/customportalapi/networking/ForcePlacePortalPacket.java b/src/main/java/net/kyrptonaught/customportalapi/networking/ForcePlacePortalPacket.java deleted file mode 100644 index 1e1a013..0000000 --- a/src/main/java/net/kyrptonaught/customportalapi/networking/ForcePlacePortalPacket.java +++ /dev/null @@ -1,47 +0,0 @@ -package net.kyrptonaught.customportalapi.networking; - -import io.netty.buffer.Unpooled; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; -import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; -import net.kyrptonaught.customportalapi.CustomPortalsMod; -import net.kyrptonaught.customportalapi.util.CustomPortalHelper; -import net.minecraft.block.BlockState; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; - -public class ForcePlacePortalPacket { - public static void sendForcePacket(ServerPlayerEntity player, BlockPos pos, Direction.Axis axis) { - PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); - buf.writeBlockPos(pos); - buf.writeInt(axis.ordinal()); - ServerPlayNetworking.send(player, NetworkManager.PLACE_PORTAL, buf); - } - - - @Environment(EnvType.CLIENT) - public static void registerReceive() { - ClientPlayNetworking.registerGlobalReceiver(NetworkManager.PLACE_PORTAL, (client, handler, packet, sender) -> { - BlockPos blockPos = packet.readBlockPos(); - - int axisOrdinal = packet.readableBytes() >= 4 ? packet.readInt() : -1; - - client.execute(() -> { - if (client.world == null) return; - - Direction.Axis axis; - if (axisOrdinal > -1) { - axis = Direction.Axis.values()[axisOrdinal]; - } else { - BlockState old = client.world.getBlockState(blockPos); - axis = CustomPortalHelper.getAxisFrom(old); - } - - client.world.setBlockState(blockPos, CustomPortalHelper.blockWithAxis(CustomPortalsMod.getDefaultPortalBlock().getDefaultState(), axis)); - }); - }); - } -} diff --git a/src/main/java/net/kyrptonaught/customportalapi/networking/LinkSyncPacket.java b/src/main/java/net/kyrptonaught/customportalapi/networking/LinkSyncPacket.java new file mode 100644 index 0000000..e096fb9 --- /dev/null +++ b/src/main/java/net/kyrptonaught/customportalapi/networking/LinkSyncPacket.java @@ -0,0 +1,27 @@ +package net.kyrptonaught.customportalapi.networking; + +import net.kyrptonaught.customportalapi.CustomPortalsMod; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.util.Identifier; + +public record LinkSyncPacket(Identifier blockID, Identifier dimID, int color) implements CustomPayload { + public static final CustomPayload.Id PACKET_ID = new CustomPayload.Id<>(Identifier.of(CustomPortalsMod.MOD_ID, "syncportals")); + public static final PacketCodec codec = PacketCodec.of(LinkSyncPacket::write, LinkSyncPacket::read); + + public static LinkSyncPacket read(RegistryByteBuf buf) { + return new LinkSyncPacket(buf.readIdentifier(), buf.readIdentifier(), buf.readInt()); + } + + public void write(RegistryByteBuf buf) { + buf.writeIdentifier(blockID); + buf.writeIdentifier(dimID); + buf.writeInt(color); + } + + @Override + public Id getId() { + return PACKET_ID; + } +} \ No newline at end of file diff --git a/src/main/java/net/kyrptonaught/customportalapi/networking/NetworkManager.java b/src/main/java/net/kyrptonaught/customportalapi/networking/NetworkManager.java index 6488a0a..9e4fa17 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/networking/NetworkManager.java +++ b/src/main/java/net/kyrptonaught/customportalapi/networking/NetworkManager.java @@ -1,17 +1,73 @@ package net.kyrptonaught.customportalapi.networking; + import net.fabricmc.api.DedicatedServerModInitializer; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.kyrptonaught.customportalapi.CustomPortalApiRegistry; import net.kyrptonaught.customportalapi.CustomPortalsMod; +import net.kyrptonaught.customportalapi.PerWorldPortals; +import net.kyrptonaught.customportalapi.util.CustomPortalHelper; +import net.kyrptonaught.customportalapi.util.PortalLink; +import net.minecraft.block.BlockState; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; public class NetworkManager implements DedicatedServerModInitializer { - public static final Identifier SYNC_PORTALS = new Identifier(CustomPortalsMod.MOD_ID, "syncportals"); - public static final Identifier PLACE_PORTAL = new Identifier(CustomPortalsMod.MOD_ID, "placeportal"); @Override public void onInitializeServer() { - PortalRegistrySync.registerSyncOnPlayerJoin(); + ServerPlayConnectionEvents.JOIN.register((serverPlayNetworkHandler, packetSender, minecraftServer) -> { + for (PortalLink link : CustomPortalApiRegistry.getAllPortalLinks()) { + packetSender.sendPacket(createPacket(link)); + } + }); + } + + public static void syncLinkToAllPlayers(PortalLink link, MinecraftServer server) { + for (ServerPlayerEntity player : server.getPlayerManager().getPlayerList()) { + syncLinkToPlayer(link, player); + } + } + + public static void syncLinkToPlayer(PortalLink link, ServerPlayerEntity player) { + ServerPlayNetworking.send(player, createPacket(link)); + } + + private static LinkSyncPacket createPacket(PortalLink link) { + return new LinkSyncPacket(link.block, link.dimID, link.colorID); + } + + public static void sendForcePacket(ServerPlayerEntity player, BlockPos pos, Direction.Axis axis) { + ServerPlayNetworking.send(player, new ForcePlacePacket(pos, axis.ordinal())); + } + + @Environment(EnvType.CLIENT) + public static void registerPackets() { + ClientPlayNetworking.registerGlobalReceiver(LinkSyncPacket.PACKET_ID, (payload, context) -> { + PerWorldPortals.registerWorldPortal(new PortalLink(payload.blockID(), payload.dimID(), payload.color())); + }); + + ClientPlayNetworking.registerGlobalReceiver(ForcePlacePacket.PACKET_ID, (payload, context) -> { + context.client().execute(() -> { + if (context.client().world == null) return; + + Direction.Axis axis; + if (payload.axis() > -1) { + axis = Direction.Axis.values()[payload.axis()]; + } else { + BlockState old = context.client().world.getBlockState(payload.pos()); + axis = CustomPortalHelper.getAxisFrom(old); + } + + context.client().world.setBlockState(payload.pos(), CustomPortalHelper.blockWithAxis(CustomPortalsMod.getDefaultPortalBlock().getDefaultState(), axis)); + + }); + }); } } \ No newline at end of file diff --git a/src/main/java/net/kyrptonaught/customportalapi/networking/PortalRegistrySync.java b/src/main/java/net/kyrptonaught/customportalapi/networking/PortalRegistrySync.java deleted file mode 100644 index 35fab25..0000000 --- a/src/main/java/net/kyrptonaught/customportalapi/networking/PortalRegistrySync.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.kyrptonaught.customportalapi.networking; - -import io.netty.buffer.Unpooled; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; -import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; -import net.kyrptonaught.customportalapi.CustomPortalApiRegistry; -import net.kyrptonaught.customportalapi.PerWorldPortals; -import net.kyrptonaught.customportalapi.util.PortalLink; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.util.Identifier; - -public class PortalRegistrySync { - public static void registerSyncOnPlayerJoin() { - ServerPlayConnectionEvents.JOIN.register((serverPlayNetworkHandler, packetSender, minecraftServer) -> { - for (PortalLink link : CustomPortalApiRegistry.getAllPortalLinks()) { - packetSender.sendPacket(createPacket(link)); - } - }); - } - - public static void syncLinkToAllPlayers(PortalLink link, MinecraftServer server) { - for (ServerPlayerEntity player : server.getPlayerManager().getPlayerList()) { - syncLinkToPlayer(link, player); - } - } - - public static void syncLinkToPlayer(PortalLink link, ServerPlayerEntity player) { - player.networkHandler.sendPacket(createPacket(link)); - } - - public static Packet createPacket(PortalLink link) { - PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); - buf.writeIdentifier(link.block); - buf.writeIdentifier(link.dimID); - buf.writeInt(link.colorID); - return new CustomPayloadS2CPacket(NetworkManager.SYNC_PORTALS, buf); - } - - @Environment(EnvType.CLIENT) - public static void registerReceivePortalData() { - ClientPlayNetworking.registerGlobalReceiver(NetworkManager.SYNC_PORTALS, (client, handler, packet, sender) -> { - Identifier frameBlock = packet.readIdentifier(); - Identifier dimID = packet.readIdentifier(); - int colorId = packet.readInt(); - PerWorldPortals.registerWorldPortal(new PortalLink(frameBlock, dimID, colorId)); - }); - } -} diff --git a/src/main/java/net/kyrptonaught/customportalapi/portal/PortalPlacer.java b/src/main/java/net/kyrptonaught/customportalapi/portal/PortalPlacer.java index 1072e6d..6cec108 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/portal/PortalPlacer.java +++ b/src/main/java/net/kyrptonaught/customportalapi/portal/PortalPlacer.java @@ -47,7 +47,8 @@ public static Optional createDestinationPortal(ServerWorld world, Blo PortalLink link = CustomPortalApiRegistry.getPortalLinkFromBase(frameBlock.getBlock()); PortalFrameTester portalFrameTester = link.getFrameTester().createInstanceOfPortalFrameTester(); - int topY = Math.min(world.getTopY(), world.getBottomY() + world.getLogicalHeight()) - 5; + int topY = Math.min(world.getTopYInclusive(), world.getBottomY() + world.getLogicalHeight()) - 5; + int bottomY = world.getBottomY() + 5; if (world.getRegistryKey().getValue().equals(link.dimID)) { diff --git a/src/main/java/net/kyrptonaught/customportalapi/portal/frame/FlatPortalAreaHelper.java b/src/main/java/net/kyrptonaught/customportalapi/portal/frame/FlatPortalAreaHelper.java index 9e987ca..deafc95 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/portal/frame/FlatPortalAreaHelper.java +++ b/src/main/java/net/kyrptonaught/customportalapi/portal/frame/FlatPortalAreaHelper.java @@ -4,12 +4,14 @@ import net.kyrptonaught.customportalapi.CustomPortalApiRegistry; import net.kyrptonaught.customportalapi.CustomPortalsMod; import net.kyrptonaught.customportalapi.util.CustomPortalHelper; +import net.kyrptonaught.customportalapi.util.CustomTeleporter; import net.kyrptonaught.customportalapi.util.PortalLink; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityDimensions; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; @@ -149,8 +151,8 @@ public BlockPos doesPortalFitAt(World world, BlockPos attemptPos, Direction.Axis @Override public Vec3d getEntityOffsetInPortal(BlockLocating.Rectangle arg, Entity entity, Direction.Axis portalAxis) { EntityDimensions entityDimensions = entity.getDimensions(entity.getPose()); - double xSize = arg.width - entityDimensions.width; - double zSize = arg.height - entityDimensions.width; + double xSize = arg.width - entityDimensions.width(); + double zSize = arg.height - entityDimensions.width(); double deltaX = MathHelper.getLerpProgress(entity.getX(), arg.lowerLeft.getX(), arg.lowerLeft.getX() + xSize); double deltaZ = MathHelper.getLerpProgress(entity.getZ(), arg.lowerLeft.getZ(), arg.lowerLeft.getZ() + zSize); @@ -159,15 +161,16 @@ public Vec3d getEntityOffsetInPortal(BlockLocating.Rectangle arg, Entity entity, } @Override - public TeleportTarget getTPTargetInPortal(BlockLocating.Rectangle portalRect, Direction.Axis portalAxis, Vec3d prevOffset, Entity entity) { + public TeleportTarget getTPTargetInPortal(ServerWorld world, Block frameBlock, BlockLocating.Rectangle portalRect, Direction.Axis portalAxis, Vec3d prevOffset, Entity entity) { EntityDimensions entityDimensions = entity.getDimensions(entity.getPose()); - double xSize = portalRect.width - entityDimensions.width; - double zSize = portalRect.height - entityDimensions.width; + double xSize = portalRect.width - entityDimensions.width(); + double zSize = portalRect.height - entityDimensions.width(); double x = MathHelper.lerp(prevOffset.x, portalRect.lowerLeft.getX(), portalRect.lowerLeft.getX() + xSize); double y = MathHelper.lerp(prevOffset.y, portalRect.lowerLeft.getY() - 1, portalRect.lowerLeft.getY() + 1); double z = MathHelper.lerp(prevOffset.z, portalRect.lowerLeft.getZ(), portalRect.lowerLeft.getZ() + zSize); - return new TeleportTarget(new Vec3d(x, portalRect.lowerLeft.getY() + 1, z), entity.getVelocity(), entity.getYaw(), entity.getPitch()); + TeleportTarget.PostDimensionTransition post = CustomTeleporter.sendTravelThroughPortalPacket(frameBlock).then(entityx -> entityx.addPortalChunkTicketAt(portalRect.lowerLeft)); + return new TeleportTarget(world, new Vec3d(x, portalRect.lowerLeft.getY() + 1, z), entity.getVelocity(), entity.getYaw(), entity.getPitch(), post); } } \ No newline at end of file diff --git a/src/main/java/net/kyrptonaught/customportalapi/portal/frame/PortalFrameTester.java b/src/main/java/net/kyrptonaught/customportalapi/portal/frame/PortalFrameTester.java index 317a225..19ec40a 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/portal/frame/PortalFrameTester.java +++ b/src/main/java/net/kyrptonaught/customportalapi/portal/frame/PortalFrameTester.java @@ -10,6 +10,7 @@ import net.minecraft.registry.Registries; import net.minecraft.registry.tag.BlockTags; import net.minecraft.registry.tag.FluidTags; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; @@ -54,7 +55,7 @@ public abstract class PortalFrameTester { public abstract Vec3d getEntityOffsetInPortal(BlockLocating.Rectangle arg, Entity entity, Direction.Axis portalAxis); - public abstract TeleportTarget getTPTargetInPortal(BlockLocating.Rectangle portalRect, Direction.Axis portalAxis, Vec3d prevOffset, Entity entity); + public abstract TeleportTarget getTPTargetInPortal(ServerWorld world, Block frameBlock, BlockLocating.Rectangle portalRect, Direction.Axis portalAxis, Vec3d prevOffset, Entity entity); protected BlockPos getLowerCorner(BlockPos blockPos, Direction.Axis axis1, Direction.Axis axis2) { if (!validStateInsidePortal(world.getBlockState(blockPos), VALID_FRAME)) diff --git a/src/main/java/net/kyrptonaught/customportalapi/portal/frame/VanillaPortalAreaHelper.java b/src/main/java/net/kyrptonaught/customportalapi/portal/frame/VanillaPortalAreaHelper.java index 912710c..2990bc6 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/portal/frame/VanillaPortalAreaHelper.java +++ b/src/main/java/net/kyrptonaught/customportalapi/portal/frame/VanillaPortalAreaHelper.java @@ -4,17 +4,22 @@ import net.kyrptonaught.customportalapi.CustomPortalApiRegistry; import net.kyrptonaught.customportalapi.CustomPortalsMod; import net.kyrptonaught.customportalapi.util.CustomPortalHelper; +import net.kyrptonaught.customportalapi.util.CustomTeleporter; import net.kyrptonaught.customportalapi.util.PortalLink; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityDimensions; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -import net.minecraft.world.*; +import net.minecraft.world.BlockLocating; +import net.minecraft.world.TeleportTarget; +import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; import java.util.Optional; import java.util.function.Predicate; @@ -121,8 +126,8 @@ protected boolean canHoldPortal(World world, BlockPos pos) { @Override public Vec3d getEntityOffsetInPortal(BlockLocating.Rectangle arg, Entity entity, Direction.Axis portalAxis) { EntityDimensions entityDimensions = entity.getDimensions(entity.getPose()); - double width = arg.width - entityDimensions.width; - double height = arg.height - entityDimensions.height; + double width = arg.width - entityDimensions.width(); + double height = arg.height - entityDimensions.height(); double deltaX = MathHelper.getLerpProgress(entity.getX(), arg.lowerLeft.getX(), arg.lowerLeft.getX() + width); double deltaY = MathHelper.getLerpProgress(entity.getY(), arg.lowerLeft.getY(), arg.lowerLeft.getY() + height); @@ -133,10 +138,10 @@ public Vec3d getEntityOffsetInPortal(BlockLocating.Rectangle arg, Entity entity, } @Override - public TeleportTarget getTPTargetInPortal(BlockLocating.Rectangle portalRect, Direction.Axis portalAxis, Vec3d prevOffset, Entity entity) { + public TeleportTarget getTPTargetInPortal(ServerWorld world, Block frameBlock, BlockLocating.Rectangle portalRect, Direction.Axis portalAxis, Vec3d prevOffset, Entity entity) { EntityDimensions entityDimensions = entity.getDimensions(entity.getPose()); - double width = portalRect.width - entityDimensions.width; - double height = portalRect.height - entityDimensions.height; + double width = portalRect.width - entityDimensions.width(); + double height = portalRect.height - entityDimensions.height(); double x = MathHelper.lerp(prevOffset.x, portalRect.lowerLeft.getX(), portalRect.lowerLeft.getX() + width); double y = MathHelper.lerp(prevOffset.y, portalRect.lowerLeft.getY(), portalRect.lowerLeft.getY() + height); double z = MathHelper.lerp(prevOffset.z, portalRect.lowerLeft.getZ(), portalRect.lowerLeft.getZ() + width); @@ -145,7 +150,9 @@ public TeleportTarget getTPTargetInPortal(BlockLocating.Rectangle portalRect, Di else if (portalAxis == Direction.Axis.Z) x = portalRect.lowerLeft.getX() + .5D; - return new TeleportTarget(new Vec3d(x, y, z), entity.getVelocity(), entity.getYaw(), entity.getPitch()); + + TeleportTarget.PostDimensionTransition post = CustomTeleporter.sendTravelThroughPortalPacket(frameBlock).then(entityx -> entityx.addPortalChunkTicketAt(portalRect.lowerLeft)); + return new TeleportTarget(world, new Vec3d(x, y, z), entity.getVelocity(), entity.getYaw(), entity.getPitch(), post); } public void lightPortal(Block frameBlock) { diff --git a/src/main/java/net/kyrptonaught/customportalapi/portal/linking/DimensionalBlockPos.java b/src/main/java/net/kyrptonaught/customportalapi/portal/linking/DimensionalBlockPos.java index ba0f62f..bda4e6e 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/portal/linking/DimensionalBlockPos.java +++ b/src/main/java/net/kyrptonaught/customportalapi/portal/linking/DimensionalBlockPos.java @@ -14,7 +14,7 @@ public DimensionalBlockPos(Identifier dimension, BlockPos pos) { } public static DimensionalBlockPos fromTag(NbtCompound tag) { - return new DimensionalBlockPos(new Identifier(tag.getString("dimID")), BlockPos.fromLong(tag.getLong("pos"))); + return new DimensionalBlockPos(Identifier.of(tag.getString("dimID")), BlockPos.fromLong(tag.getLong("pos"))); } public NbtCompound toTag(NbtCompound tag) { diff --git a/src/main/java/net/kyrptonaught/customportalapi/portal/linking/PortalLinkingStorage.java b/src/main/java/net/kyrptonaught/customportalapi/portal/linking/PortalLinkingStorage.java index 60d4085..c774786 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/portal/linking/PortalLinkingStorage.java +++ b/src/main/java/net/kyrptonaught/customportalapi/portal/linking/PortalLinkingStorage.java @@ -1,8 +1,10 @@ package net.kyrptonaught.customportalapi.portal.linking; +import net.minecraft.datafixer.DataFixTypes; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtList; import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.world.PersistentState; @@ -18,19 +20,23 @@ public PortalLinkingStorage() { super(); } - public static PersistentState fromNbt(NbtCompound tag) { + public static Type getPersistentStateType() { + return new Type<>(PortalLinkingStorage::new, PortalLinkingStorage::fromNbt, DataFixTypes.LEVEL); + } + + public static PortalLinkingStorage fromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { PortalLinkingStorage cman = new PortalLinkingStorage(); NbtList links = (NbtList) tag.get("portalLinks"); for (int i = 0; i < links.size(); i++) { NbtCompound link = links.getCompound(i); DimensionalBlockPos toTag = DimensionalBlockPos.fromTag(link.getCompound("to")); - cman.addLink(BlockPos.fromLong(link.getLong("fromPos")), new Identifier(link.getString("fromDimID")), toTag.pos, toTag.dimensionType); + cman.addLink(BlockPos.fromLong(link.getLong("fromPos")), Identifier.of(link.getString("fromDimID")), toTag.pos, toTag.dimensionType); } return cman; } - public NbtCompound writeNbt(NbtCompound tag) { + public NbtCompound writeNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { NbtList links = new NbtList(); portalLinks.keys().asIterator().forEachRemaining(dimKey -> { portalLinks.get(dimKey).forEach((blockPos, dimensionalBlockPos) -> { @@ -46,8 +52,9 @@ public NbtCompound writeNbt(NbtCompound tag) { } public DimensionalBlockPos getDestination(BlockPos portalFramePos, RegistryKey dimID) { - if (portalLinks.containsKey(dimID.getValue())) + if (dimID != null && portalFramePos != null && portalLinks.containsKey(dimID.getValue())) return portalLinks.get(dimID.getValue()).get(portalFramePos); + return null; } diff --git a/src/main/java/net/kyrptonaught/customportalapi/util/CustomTeleporter.java b/src/main/java/net/kyrptonaught/customportalapi/util/CustomTeleporter.java index 182b61a..bfff17a 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/util/CustomTeleporter.java +++ b/src/main/java/net/kyrptonaught/customportalapi/util/CustomTeleporter.java @@ -2,13 +2,13 @@ import net.kyrptonaught.customportalapi.CustomPortalApiRegistry; import net.kyrptonaught.customportalapi.CustomPortalsMod; -import net.kyrptonaught.customportalapi.interfaces.CustomTeleportingEntity; import net.kyrptonaught.customportalapi.portal.PortalPlacer; import net.kyrptonaught.customportalapi.portal.frame.PortalFrameTester; import net.kyrptonaught.customportalapi.portal.linking.DimensionalBlockPos; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; +import net.minecraft.network.packet.s2c.play.WorldEventS2CPacket; import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; @@ -17,10 +17,7 @@ import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import net.minecraft.util.math.*; -import net.minecraft.world.BlockLocating; -import net.minecraft.world.Heightmap; -import net.minecraft.world.TeleportTarget; -import net.minecraft.world.World; +import net.minecraft.world.*; import net.minecraft.world.border.WorldBorder; import net.minecraft.world.dimension.DimensionType; @@ -28,40 +25,35 @@ public class CustomTeleporter { - public static void TPToDim(World world, Entity entity, Block portalBase, BlockPos portalPos) { + public static TeleportTarget createTeleportTarget(World world, Entity entity, Block portalBase, BlockPos portalPos) { PortalLink link = CustomPortalApiRegistry.getPortalLinkFromBase(portalBase); - if (link == null) return; + if (link == null) return null; if (link.getBeforeTPEvent().execute(entity) == SHOULDTP.CANCEL_TP) - return; + return null; RegistryKey destKey = wrapRegistryKey(link.dimID); if (world.getRegistryKey().getValue().equals(destKey.getValue()))//if already in destination destKey = wrapRegistryKey(link.returnDimID); ServerWorld destination = ((ServerWorld) world).getServer().getWorld(destKey); - if (destination == null) return; - if (!entity.canUsePortals()) return; + if (destination == null) return null; + if (!entity.canUsePortals(false)) return null; destination.getChunkManager().addTicket(ChunkTicketType.PORTAL, new ChunkPos(BlockPos.ofFloored(portalPos.getX() / destination.getDimension().coordinateScale(), portalPos.getY() / destination.getDimension().coordinateScale(), portalPos.getZ() / destination.getDimension().coordinateScale())), 3, BlockPos.ofFloored(portalPos.getX() / destination.getDimension().coordinateScale(), portalPos.getY() / destination.getDimension().coordinateScale(), portalPos.getZ() / destination.getDimension().coordinateScale())); - TeleportTarget target = customTPTarget(destination, entity, portalPos, portalBase, link.getFrameTester()); - ((CustomTeleportingEntity) entity).setCustomTeleportTarget(target); - entity = entity.moveToWorld(destination); - if (entity != null) { - entity.setYaw(target.yaw); - entity.setPitch(target.pitch); - if (entity instanceof ServerPlayerEntity) - entity.refreshPositionAfterTeleport(target.position); - link.executePostTPEvent(entity); - } + return customTPTarget(destination, entity, portalPos, portalBase, link.getFrameTester()); } public static RegistryKey wrapRegistryKey(Identifier dimID) { return RegistryKey.of(RegistryKeys.WORLD, dimID); } - public static TeleportTarget customTPTarget(ServerWorld destinationWorld, Entity entity, BlockPos enteredPortalPos, Block frameBlock, PortalFrameTester.PortalFrameTesterFactory portalFrameTesterFactory) { + private static TeleportTarget customTPTarget(ServerWorld destinationWorld, Entity entity, BlockPos enteredPortalPos, Block frameBlock, PortalFrameTester.PortalFrameTesterFactory portalFrameTesterFactory) { Direction.Axis portalAxis = CustomPortalHelper.getAxisFrom(entity.getEntityWorld().getBlockState(enteredPortalPos)); BlockLocating.Rectangle fromPortalRectangle = portalFrameTesterFactory.createInstanceOfPortalFrameTester().init(entity.getEntityWorld(), enteredPortalPos, portalAxis, frameBlock).getRectangle(); + + if (fromPortalRectangle.lowerLeft == null) + return null; + DimensionalBlockPos destinationPos = CustomPortalsMod.portalLinkingStorage.getDestination(fromPortalRectangle.lowerLeft, entity.getEntityWorld().getRegistryKey()); if (destinationPos != null && destinationPos.dimensionType.equals(destinationWorld.getRegistryKey().getValue())) { @@ -70,7 +62,7 @@ public static TeleportTarget customTPTarget(ServerWorld destinationWorld, Entity if (!portalFrameTester.isAlreadyLitPortalFrame()) { portalFrameTester.lightPortal(frameBlock); } - return portalFrameTester.getTPTargetInPortal(portalFrameTester.getRectangle(), portalAxis, portalFrameTester.getEntityOffsetInPortal(fromPortalRectangle, entity, portalAxis), entity); + return portalFrameTester.getTPTargetInPortal(destinationWorld, frameBlock, portalFrameTester.getRectangle(), portalAxis, portalFrameTester.getEntityOffsetInPortal(fromPortalRectangle, entity, portalAxis), entity); } } return createDestinationPortal(destinationWorld, entity, portalAxis, fromPortalRectangle, frameBlock.getDefaultState()); @@ -89,15 +81,24 @@ public static TeleportTarget createDestinationPortal(ServerWorld destination, En PortalFrameTester portalFrameTester = CustomPortalApiRegistry.getPortalLinkFromBase(frameBlock.getBlock()).getFrameTester().createInstanceOfPortalFrameTester(); CustomPortalsMod.portalLinkingStorage.createLink(portalFramePos.lowerLeft, entity.getWorld().getRegistryKey(), portal.get().lowerLeft, destination.getRegistryKey()); - return portalFrameTester.getTPTargetInPortal(portal.get(), axis, portalFrameTester.getEntityOffsetInPortal(portalFramePos, entity, axis), entity); + return portalFrameTester.getTPTargetInPortal(destination, frameBlock.getBlock(), portal.get(), axis, portalFrameTester.getEntityOffsetInPortal(portalFramePos, entity, axis), entity); } return idkWhereToPutYou(destination, entity, blockPos3); } - protected static TeleportTarget idkWhereToPutYou(ServerWorld world, Entity entity, BlockPos pos) { CustomPortalsMod.logError("Unable to find tp location, forced to place on top of world"); BlockPos destinationPos = world.getTopPosition(Heightmap.Type.WORLD_SURFACE, pos); - return new TeleportTarget(new Vec3d(destinationPos.getX() + .5, destinationPos.getY(), destinationPos.getZ() + .5), entity.getVelocity(), entity.getYaw(), entity.getPitch()); + return new TeleportTarget(world, new Vec3d(destinationPos.getX() + .5, destinationPos.getY(), destinationPos.getZ() + .5), entity.getVelocity(), entity.getYaw(), entity.getPitch(), TeleportTarget.NO_OP); + } + + + public static TeleportTarget.PostDimensionTransition sendTravelThroughPortalPacket(Block portalFrame) { + int portalFrameBlockID = Registries.BLOCK.getRawId(portalFrame); + return entity -> { + if (entity instanceof ServerPlayerEntity serverPlayerEntity) { + serverPlayerEntity.networkHandler.sendPacket(new WorldEventS2CPacket(WorldEvents.TRAVEL_THROUGH_PORTAL, BlockPos.ORIGIN, portalFrameBlockID, false)); + } + }; } } \ No newline at end of file diff --git a/src/main/java/net/kyrptonaught/customportalapi/util/PortalLink.java b/src/main/java/net/kyrptonaught/customportalapi/util/PortalLink.java index 0996a79..029417d 100644 --- a/src/main/java/net/kyrptonaught/customportalapi/util/PortalLink.java +++ b/src/main/java/net/kyrptonaught/customportalapi/util/PortalLink.java @@ -21,7 +21,7 @@ public class PortalLink { public PortalIgnitionSource portalIgnitionSource = PortalIgnitionSource.FIRE; private CustomPortalBlock portalBlock = CustomPortalsMod.portalBlock; public Identifier dimID; - public Identifier returnDimID = new Identifier("overworld"); + public Identifier returnDimID = Identifier.of("overworld"); public boolean onlyIgnitableInReturnDim = false; public int colorID; public int forcedWidth, forcedHeight; diff --git a/src/main/resources/customportalapi.mixins.json b/src/main/resources/customportalapi.mixins.json index 3dae024..ed7f5ff 100644 --- a/src/main/resources/customportalapi.mixins.json +++ b/src/main/resources/customportalapi.mixins.json @@ -2,20 +2,17 @@ "required": true, "minVersion": "0.8", "package": "net.kyrptonaught.customportalapi.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "mixins": [ - "EntityMixin", - "ServerPlayerMixin", "portalLighters.AbstractFireMixin", "portalLighters.FluidBlockPlacedMixin", "portalLighters.PotionEntityMixin" ], "client": [ - "client.ClientPlayerMixin", - "client.ClientPlayNetworkHandlerMixin", + "client.ClientPlayerEntityMixin", "client.InGameHudMixin", - "client.WorldRendererMixin", - "client.SodiumBlendingFix" + "client.PortalManagerAccessor", + "client.WorldRendererMixin" ], "injectors": { "defaultRequire": 1