How can I teleport players between dimensions with the correct ratios with a data pack?

I'm creating a data pack where when entities go below bedrock or past the height limit you teleport to a different dimension like this:

END
Y -128 --> Y 320
Y 384 --> Y -64
OVERWORLD
Y -128 --> Y 320
Y 384 --> Y -64
NETHER

And I want to teleport with a 1:8 ratio in the Nether and End. Examples:

Overworld -821 385 511 --> End -6568 -64 4088
End 140 -128 -4843 --> Overworld 17 320 -605
Nether 3583 -128 283 --> Nothing (You can't go below the Nether)

I want it to be compatible with as many entities as possible and not be too laggy.


Solution 1:

Similar to this answer you need a dummy entity whose position is stored and can be set in NBT.
All of this needs to be executed in one tick, for example as a function.

Assumtions: Player is tagged as "teleportMe", scoreboards x and z exist.

Summon dummy entity at player:

execute at @a[tag=teleportMe] run summon armor_stand ~ ~ ~ {NoGravity:1,NoAI:1,Invisible:1,Marker:1,ActiveEffects:[{Id:11,Amplifier:9,Duration:9}],Tags:["teleportHelper"]}

Get coordinates of the entity into scoreboards:

execute as @e[tag=teleportHelper] store result score @s x run data get entity @s Pos[0] 71
execute as @e[tag=teleportHelper] store result score @s z run data get entity @s Pos[2] 71

Scoreboards are always integers, so multiplying by 71 and later dividing by 71·8 gives you the best accurracy.

Put scaled coordinates back into NBT:

execute as @e[tag=teleportHelper] store result entity @s Pos[0] double 0.001760563380281690140845070422535211267605633802816901408450704225352112676056338028169014084507042253521126760563380281690140845070422535211267605633 run scoreboard players get @s x
execute as @e[tag=teleportHelper] store result entity @s Pos[2] double 0.001760563380281690140845070422535211267605633802816901408450704225352112676056338028169014084507042253521126760563380281690140845070422535211267605633 run scoreboard players get @s z

Teleport player to dummy entity coordinates, but in another dimension and higher:

execute at @e[tag=teleportHelper] in the_end run tp @a[tag=teleportMe] ~ ~512 ~

Clean up:

kill @e[tag=teleportHelper]