Skip to content

🧲 Вакуумное движение и фазовый сдвиг (MC 26.2)

📌 Отказ от ответственности за исходный код репозитория: Документация в этой Wiki отражает текущее состояние исходного кода в репозитории, которое может включать недавние невыпущенные коммиты или функции в разработке до публичных релизов на CurseForge и Modrinth.

Инфоблок механикиТехнические параметры
Системный классnet.instantgratification.magnet.MagnetMovement
Событие срабатыванияСерверный тик игрока (PlayerMixin $\rightarrow$ MagnetManager.tick)
Радиус притягивания по умолчанию12 блоков (ig:magnet_range)
Предельная скорость по умолчанию80% ($0.8\text{ блоков/тик} = 16.0\text{ м/с}$)
Ускорение по умолчанию10% ($0.10\text{ фактор lerp/тик}$)
Фазовый сдвиг (NoClip)Включен (ig:magnet_noclip = true)
Вектор целиПозиция глаз игрока (player.getEyePosition())
Смещение от земли$+0.05\text{ м}$ по оси Y, когда entity.onGround()

📖 Обзор системы

Основная механика вакуума в моде Magnet, Let me get that! сканирует выпадающие сущности ItemEntity в пределах заданного радиуса игрока на каждом серверном тике и плавно притягивает их к уровню глаз с использованием нелинейной интерполяции.

Чтобы предметы не цеплялись за края блоков, выступы руд или кроны деревьев, мод активирует Фазовый сдвиг (NoClip), позволяя летящим предметам беспрепятственно проходить сквозь твердые воксели блоков.

+-------------+      Линия обзора OK       +----------------------+      Применена скорость Lerp      +------------------+
| Item Entity | -------------------------> | Вкл NoClip (2 тика)  | --------------------------------> | Глаза игрока     |
+-------------+                            +----------------------+                                   +------------------+
                                                       |
                                                       v
                                            [Отмена выталкивания]
                                            [Игнорирование коллизий]
                                            [Отмена гравитации в блоке]

🧮 Физика и векторная математика

При притягивании предмета траектория рассчитывается непосредственно в 3D евклидовом пространстве:

1. Вектор к цели

Пусть $\vec{p}{\text{entity}} = (x_e, y_e, z_e)$ — текущая позиция предмета, а $\vec{p}{\text{eye}} = (x_p, y_p + h_{\text{eye}}, z_p)$ — позиция глаз игрока. $$\vec{v}{\text{target}} = \vec{p}{\text{eye}} - \vec{p}{\text{entity}}$$ $$\hat{d} = \frac{\vec{v}{\text{target}}}{|\vec{v}{\text{target}}|} = \frac{\vec{v}{\text{target}}}{\sqrt{\Delta x^2 + \Delta y^2 + \Delta z^2}}$$

2. Желаемая предельная скорость

Вектор целевой скорости масштабирует единичный вектор направления $\hat{d}$ с учетом настроенного параметра скорости: $$\text{Скаляр скорости } s = \frac{\text{GameRule}(\text{ig:magnet_speed})}{100.0}$$ $$\vec{u}_{\text{target}} = \hat{d} \times s$$ При стандартном значении ($80%$), $s = 0.8\text{ блоков/тик}$. При $20\text{ тиках/с}$ предельная скорость равна $16.0\text{ м/с}$.

3. Нелинейное ускорение (Lerp)

Скорость обновляется линейной интерполяцией (Vec3.lerp) на основе коэффициента ускорения $a$: $$\text{Коэффициент ускорения } a = \frac{\text{GameRule}(\text{ig:magnet_acceleration})}{100.0}$$ $$\vec{v}{\text{new}} = \vec{v}{\text{current}} + (\vec{u}{\text{target}} - \vec{v}{\text{current}}) \times a$$

4. Устранение трения о землю

Если предмет лежит на поверхности блока (entity.onGround() == true), контактное трение мгновенно сбрасывается для предотвращения волочения по полу:

java
if (entity.onGround()) {
    entity.setOnGround(false);
    entity.setPos(entity.position().add(0, 0.05, 0));
}

🧱 Фазовый сдвиг (Движок NoClip)

Когда параметр ig:magnet_noclip активен, предметам присваивается окно NoClip длительностью в 2 тика:

  1. Активация состояния: Вызов ((IMagnetEntity) entity).ig_magnet$setMagnetNoClip() устанавливает noClipTicks = 2.
  2. Перехват перемещения (MixinEntity.java):
    • move(MoverType, Vec3): Инъекция @Inject(at = @At("HEAD")) сохраняет originalNoPhysics и принудительно устанавливает entity.noPhysics = true.
    • move(MoverType, Vec3): Инъекция @Inject(at = @At("RETURN")) восстанавливает entity.noPhysics = originalNoPhysics.
  3. Отмена выталкивания из блоков: @Inject(method = "moveTowardsClosestSpace", at = @At("HEAD"), cancellable = true) блокирует ванильное выталкивание предметов из геометрии блоков.
  4. Условное отключение гравитации: @Inject(method = "applyGravity", at = @At("HEAD"), cancellable = true) отменяет гравитацию вниз только тогда, когда предмет физически пересекает воксель блока (!level.noCollision(...)), сохраняя естественную дуговую траекторию в воздухе.

⚙️ Связанные настройки и игровые правила (GameRules)

GameRuleТипПо умолчаниюДиапазон / ЕдиницыОписание
ig:magnet_enabledBooleantruetrue/falseГлавный переключатель всей логики вакуума.
ig:magnet_rangeInteger121..64 блоковМаксимальный сферический радиус вакуума.
ig:magnet_speedInteger801..1000%Процент предельной скорости ($80 = 0.8\text{ б/т}$).
ig:magnet_accelerationInteger101..1000%Процент ускорения притягивания ($10 = 10%\text{ lerp/тик}$).
ig:magnet_noclipBooleantruetrue/falseВключает прохождение сквозь блоки при притягивании.

🔗 Связанная документация Вики

Official documentation & web portal for Dasik Igaijinn mods.