feat(delta): void dimension at 2:1 coordinate scale, plus World#convertLocation
Build Delta / Build paperclip jar (push) Successful in 7m57s
Build Delta / Build paperclip jar (push) Successful in 7m57s
Мир пустоты как кастомное измерение датапаком и пересчёт координат между мирами с разным масштабом. Механизм масштаба — тот же, что у Незера: поле coordinate_scale в типе измерения, а пересчёт при переходе равен делению масштаба источника на масштаб назначения. Для пустоты нужно ровно 2.0, то есть один блок пустоты на два блока оверворлда. Проверено на сервере: coord scale overworld=1.0 void=2.0. Биом сделан своим (delta_void:void), а не переопределением ванильного minecraft:the_void. Переопределение трогало бы данные Mojang и конфликтовало с любыми другими датапаками. Отличия от ванильного — только цвета: sky_color и fog_color в ноль, плюс выключенный туман и вода. Что потребовалось по дороге, все три ошибки поймал сервер, а не я: 1. У типа измерения в 1.21.8 обязательное поле logical_height. Без него сервер отказывается стартовать: "No key logical_height". 2. Файл измерения не принимает дискриминатор "type": "minecraft:dimension". Кодек LevelStem читает поле type как ССЫЛКУ на тип измерения, и мой дискриминатор уходил в неё как имя типа. Правильно — "type" со значением delta_void:void. 3. getAllLevels() живёт на MinecraftServer, а не на DedicatedServer, который отдаёт CraftServer#getHandle(). И dimensionType() в Paper уже разворачивает Holder, так что .value() там не нужен и ломает компиляцию. Отдельно: World#getCoordinateScale() в Paper УЖЕ есть, причём реализован ровно так, как я собрался писать. Для чтения масштаба ядро менять не нужно. А вот пересчёта координат в API нет ни в Paper, ни в Bukkit: Player#teleport его не делает, потому что телепорт не портал. Добавлен default-метод World#convertLocation с той же формулой, что и ванильная, и без изменения Y. Хорошая новость про отказ сервера: на битый датапак он не стартует, а падает в safeMode. Тихая загрузка сломанной генерации была бы хуже. Диагностика частиц всё ещё в CraftWorld, снимается после проверки прицела.
This commit is contained in:
@@ -4111,6 +4111,39 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
spawnParticle(particle, x, y, z, count, offsetX, offsetY, offsetZ, extra, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Переводит точку из этого мира в другой с учётом масштаба координат.
|
||||
*
|
||||
* <p>Масштаб самого мира Paper уже отдаёт через {@link #getCoordinateScale()},
|
||||
* не надо лезть в ядро. Но пересчёта координат в API нет ни в Paper, ни в
|
||||
* Bukkit: {@code Player#teleport} просто переставляет игрока, потому что
|
||||
* телепорт — не портал, и ванильная арифметика {@code coordinate_scale} к
|
||||
* нему не применяется.
|
||||
*
|
||||
* <p>Поэтому переход между мирами с разным масштабом плагин обязан посчитать
|
||||
* сам. Без этого игрок выходит не туда: пустота с масштабом 2.0 выкинет его
|
||||
* в вдвое дальнюю точку оверворлда, чем он рассчитывал.
|
||||
*
|
||||
* <p>Множитель берётся ровно так же, как в
|
||||
* {@code DimensionType#getTeleportationScale}: масштаб источника делим на
|
||||
* масштаб назначения. Для перехода оверворлд → Незер это 1.0 / 8.0 = 0.125,
|
||||
* то есть x и z уменьшаются в восемь раз.
|
||||
*
|
||||
* <p>Высота не пересчитывается: по вертикали измерения не масштабируются, и
|
||||
* так же поступает ванильная арифметика порталов.
|
||||
*
|
||||
* <p>По умолчанию точка переносится как есть: для миров с одинаковым
|
||||
* масштабом это и есть правильный ответ, а реализация {@link World}, которая
|
||||
* метод не переопределяет, не ломает пересчёт.
|
||||
*
|
||||
* @param target мир, в который переводим
|
||||
* @param loc точка в этом мире
|
||||
* @return та же точка в координатах целевого мира
|
||||
*/
|
||||
public default @NotNull Location convertLocation(@NotNull Location target, @NotNull Location loc) {
|
||||
return loc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the closest nearby structure of a given {@link StructureType}.
|
||||
* Finding unexplored structures can, and will, block if the world is
|
||||
|
||||
Reference in New Issue
Block a user