Skip to content

🧲 吸引移動與穿相邏輯 (MC 26.2)

📌 倉庫原始碼聲明:本 Wiki 中的文件反映了倉庫中的當前原始碼狀態,可能包含領先於 CurseForge 與 Modrinth 上公開發布版本的最新未發布提交或開發中功能。

功能資訊面板技術參數
系統核心類別net.instantgratification.magnet.MagnetMovement
觸發事件伺服端玩家 Tick (PlayerMixin $\rightarrow$ MagnetManager.tick)
預設牽引半徑12 格 (ig:magnet_range)
預設終端速度80% ($0.8\text{ 格/tick} = 16.0\text{ m/s}$)
預設加速度10% ($0.10\text{ 插值係數/tick}$)
穿相移動 (NoClip)已啟用 (ig:magnet_noclip = true)
目標向量玩家眼部位置 (player.getEyePosition())
地面防摩擦高度加成處於地面時 Y 軸 $+0.05\text{ m}$ (entity.onGround())

📖 系統概覽

Magnet, Let me get that! 的核心磁吸機制會在每個伺服器 Tick 掃描玩家設定半徑內的掉落物 ItemEntity 實體,並使用平滑非線性插值將其拉向玩家的眼部位置。

為了防止掉落物卡在鵝卵石邊緣、樹冠頂部或礦脈裂縫中,本模組激活了**穿相移動(NoClip)**機制,使飛行中的物品可以無害地穿過實心方塊體積。

+-------------+        視線檢查通過        +----------------------+        應用動態插值速度        +------------------+
|   掉落物    | -------------------------> | 設定 NoClip (2 Ticks)| ------------------------------> |  玩家眼部位置    |
+-------------+                            +----------------------+                                 +------------------+
                                                       |
                                                       v
                                             [取消方塊擠出推力]
                                             [繞過方塊碰撞檢測]
                                             [取消方塊內部重力]

🧮 物理與向量數學

當牽引一個實體時,軌跡直接在三維歐幾里得空間中計算:

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{ 格/tick}$。以 $20\text{ ticks/s}$ 計算,終端速度為 $16.0\text{ m/s}$。

3. 非線性加速度插值 (Lerp)

速度依據加速度插值係數 $a$ 使用線性插值(Vec3.lerp)進行動態更新: $$\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 啟用時,實體將被打上 2-tick 的 NoClip 狀態標記:

  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

遊戲規則 Identifier類型預設值單位 / 範圍描述與效果
ig:magnet_enabledBooleantruetrue/false控制所有磁吸牽引邏輯的全域總開關。
ig:magnet_rangeInteger121..64玩家吸引掉落物的最大球面方塊半徑。
ig:magnet_speedInteger801..1000%終端飛行速度百分比($80 = 0.8\text{ 格/tick}$)。
ig:magnet_accelerationInteger101..1000%牽引加速度插值百分比($10 = 10%\text{ 插值/tick}$)。
ig:magnet_noclipBooleantruetrue/false是否允許被牽引物品在飛行中穿透實心方塊。

🔗 相關 Wiki 文件

Official documentation & web portal for Dasik Igaijinn mods.