Class MapReactorManager

java.lang.Object
server.maps.MapReactorManager

public final class MapReactorManager extends Object
地圖反應爐(reactor)的生命週期與查詢協作者,由 P5 God class 拆分自 MapleMap

本類別封裝反應爐的生成 / 銷毀 / 重載 / 重置 / 洗牌(PQ 用)/ 依 id·oid·名稱查詢,以及嘉年華 守護獸反應爐的建立邏輯。MapleMap 以**逐字搬移**的方式把這些方法移入此處,並對每個對外公開 方法保留**簽名完全相同**的委派(delegate),因此 ~700 個 Java 呼叫端與 ~2,700 支腳本完全不受影響。

所有反應爐狀態仍存放在所屬 MapleMapmapobjects / mapobjectlocks(同 package 存取);本協作者僅持有對該地圖的回參考並沿用其讀寫鎖語意。

  • Method Summary

    Modifier and Type
    Method
    Description
    final void
    destroyReactor(int oid)
    依物件 id(oid)銷毀單一反應爐。
    final void
    destroyReactors(int first, int last)
    銷毀 reactor id 落在指定區間 [first, last](含端點)內的所有反應爐。
    取得地圖中目前所有反應爐的快照清單。
    在反應爐讀鎖保護下複製出地圖中所有反應爐的清單。
    依 reactor id 查詢地圖中第一個相符的反應爐。
    依名稱(不分大小寫)查詢地圖中第一個相符的反應爐。
    getReactorByOid(int oid)
    依物件 id(oid)查詢反應爐。
    final void
    limitReactor(int rid, int num)
    限制地圖中每種反應爐 id 的數量上限,銷毀超出上限的反應爐。
    final boolean
    makeCarnivalReactor(int team, int num)
    在嘉年華(Carnival PQ)地圖中為指定隊伍建立一個守護獸反應爐。
    final void
    重載地圖中的所有反應爐:先全部銷毀,再重生非自訂(非 PQ 守護獸)反應爐。
    final void
    將地圖中所有反應爐重置為狀態 0(供 GM / NPC 使用)。
    final void
    setReactorDelay(int state)
    在讀鎖保護下統一設定地圖中所有反應爐的重生延遲。
    final void
    將地圖中所有反應爐強制設為狀態 1
    final void
    setReactorState(byte state)
    在讀鎖保護下將地圖中所有反應爐強制命中為指定狀態。
    final void
    洗牌(隨機重排)地圖中所有反應爐的座標位置,供解謎類 PQ(如 ZPQ / LMPQ)使用。
    final void
    shuffleReactors(int first, int last)
    洗牌 reactor id 落在指定區間 [first, last](含端點)內的反應爐座標位置。
    final void
    將反應爐加入地圖並向範圍內玩家廣播其生成封包。
    final void
    於指定座標生成一個自訂(custom)反應爐。

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • getAllReactor

      public List<MapleReactor> getAllReactor()
      取得地圖中目前所有反應爐的快照清單。

      此為 getAllReactorsThreadsafe() 的別名,回傳的是複製出的新 List, 對其增刪不影響地圖內部狀態。

      Returns:
      目前地圖內所有 MapleReactor 的快照(可能為空,不為 null
    • getAllReactorsThreadsafe

      public List<MapleReactor> getAllReactorsThreadsafe()
      在反應爐讀鎖保護下複製出地圖中所有反應爐的清單。

      整個迭代過程持有 mapobjectlocks.get(REACTOR) 的讀鎖,確保與並行的生成 / 銷毀互斥; 回傳的是新建的 ArrayList,可在鎖外安全走訪。

      Returns:
      目前地圖內所有 MapleReactor 的快照(可能為空,不為 null
    • limitReactor

      public final void limitReactor(int rid, int num)
      限制地圖中每種反應爐 id 的數量上限,銷毀超出上限的反應爐。

      先在讀鎖保護下統計各 reactor id 的出現次數,凡同一 id 已達 num 個者,多出的反應爐 會被收集;隨後(鎖外)對每個多餘反應爐呼叫 destroyReactor(int),因此會對地圖內玩家 廣播反應爐銷毀封包並可能排定重生。

      注意:參數 rid 在搬移前的原始實作中並未被使用(保留原行為)。

      Parameters:
      rid - 反應爐 id(目前未使用,保留原始簽名)
      num - 每種反應爐 id 允許保留的最大數量
    • destroyReactors

      public final void destroyReactors(int first, int last)
      銷毀 reactor id 落在指定區間 [first, last](含端點)內的所有反應爐。

      先在讀鎖保護下收集符合條件的反應爐,再於鎖外對每一個呼叫 destroyReactor(int) (會廣播銷毀封包並可能排定重生)。

      Parameters:
      first - 反應爐 id 區間下界(含)
      last - 反應爐 id 區間上界(含)
    • destroyReactor

      public final void destroyReactor(int oid)
      依物件 id(oid)銷毀單一反應爐。

      副作用:向地圖內所有玩家廣播反應爐銷毀封包(CField.destroyReactor(MapleReactor))、將反應爐標記為 非存活並自 mapobjects 移除、停用其計時器。若該反應爐設有延遲(getDelay() > 0), 會透過 Timer.MapTimer 在延遲後重生(respawnReactor)。

      若找不到對應 oid 的反應爐則直接返回,不做任何事。

      Parameters:
      oid - 反應爐的物件 id
    • reloadReactors

      public final void reloadReactors()
      重載地圖中的所有反應爐:先全部銷毀,再重生非自訂(非 PQ 守護獸)反應爐。

      在讀鎖保護下對每個反應爐廣播銷毀封包(CField.destroyReactor(MapleReactor))、標記非存活並停用計時器並 收集;隨後(鎖外)逐一自 mapobjects 移除,並對 !isCustom() 的反應爐立即重生 (自訂的 cpq 守護獸反應爐不重生)。

    • resetReactors

      public final void resetReactors()
      將地圖中所有反應爐重置為狀態 0(供 GM / NPC 使用)。

      等同呼叫 setReactorState(byte) 並傳入 0

      注意(見上方原始註解):此功能未經完整測試——已被銷毀的反應爐會自 mapobjects 移除, 對於不重生的反應爐若有多份副本,理想上應建立 instance 隔離。

    • setReactorState

      public final void setReactorState()
      將地圖中所有反應爐強制設為狀態 1

      等同呼叫 setReactorState(byte) 並傳入 1

    • setReactorState

      public final void setReactorState(byte state)
      在讀鎖保護下將地圖中所有反應爐強制命中為指定狀態。

      整個迭代持有 mapobjectlocks.get(REACTOR) 讀鎖,對每個反應爐呼叫 forceHitReactor(state)

      Parameters:
      state - 目標反應爐狀態
    • setReactorDelay

      public final void setReactorDelay(int state)
      在讀鎖保護下統一設定地圖中所有反應爐的重生延遲。

      整個迭代持有 mapobjectlocks.get(REACTOR) 讀鎖,對每個反應爐呼叫 setDelay(state)

      Parameters:
      state - 重生延遲(毫秒)
    • shuffleReactors

      public final void shuffleReactors()
      洗牌(隨機重排)地圖中所有反應爐的座標位置,供解謎類 PQ(如 ZPQ / LMPQ)使用。

      等同呼叫 shuffleReactors(int, int) 並傳入涵蓋全部的 id 區間 [0, 9999999]

    • shuffleReactors

      public final void shuffleReactors(int first, int last)
      洗牌 reactor id 落在指定區間 [first, last](含端點)內的反應爐座標位置。

      分兩階段、各自取得 mapobjectlocks.get(REACTOR) 讀鎖:第一階段收集符合區間之反應爐的 現有座標,於鎖外以 Collections.shuffle(List) 打亂;第二階段再把打亂後的座標逐一指派回符合條件的 反應爐(setPosition)。

      副作用:直接變更反應爐的座標。注意兩階段之間鎖會釋放再重取,期間若反應爐集合變動可能造成座標 數量與反應爐數量不一致(保留搬移前的原始行為)。

      Parameters:
      first - 反應爐 id 區間下界(含)
      last - 反應爐 id 區間上界(含)
    • getReactorById

      public MapleReactor getReactorById(int id)
      依 reactor id 查詢地圖中第一個相符的反應爐。

      整個查詢持有 mapobjectlocks.get(REACTOR) 讀鎖;找到第一個 id 相符者即返回。

      Parameters:
      id - 要查詢的 reactor id
      Returns:
      第一個 id 相符的 MapleReactor;若無相符則為 null
    • getReactorByOid

      public final MapleReactor getReactorByOid(int oid)
      依物件 id(oid)查詢反應爐。

      透過 MapleMap.getMapObject(int, MapleMapObjectType) 取得反應爐型別的地圖物件。

      Parameters:
      oid - 反應爐的物件 id
      Returns:
      對應的 MapleReactor;若不存在則為 null
    • getReactorByName

      public final MapleReactor getReactorByName(String name)
      依名稱(不分大小寫)查詢地圖中第一個相符的反應爐。

      整個查詢持有 mapobjectlocks.get(REACTOR) 讀鎖,以 equalsIgnoreCase 比對反應爐名稱。

      Parameters:
      name - 要查詢的反應爐名稱(不分大小寫)
      Returns:
      第一個名稱相符的 MapleReactor;若無相符則為 null
    • spawnReactorOnGroundBelow

      public final void spawnReactorOnGroundBelow(MapleReactor mob, Point pos)
      於指定座標生成一個自訂(custom)反應爐。

      將反應爐座標設為 pos(反應爐不需附著於 foothold)、標記為自訂(setCustom(true), 因此不會被 reloadReactors() 重生),再委派 spawnReactor(MapleReactor) 加入地圖。

      Parameters:
      mob - 要生成的反應爐
      pos - 生成座標
    • spawnReactor

      public final void spawnReactor(MapleReactor reactor)
      將反應爐加入地圖並向範圍內玩家廣播其生成封包。

      把反應爐的所屬地圖設為本地圖,再透過 MapleMap.spawnAndAddRangedMapObject(MapleMapObject, MapleMap.DelayedPacketCreation) 將其登錄到 mapobjects,並以 MapleMap.DelayedPacketCreation 對進入範圍的玩家送出 CField.spawnReactor(MapleReactor) 封包。

      Parameters:
      reactor - 要生成的反應爐
    • makeCarnivalReactor

      public final boolean makeCarnivalReactor(int team, int num)
      在嘉年華(Carnival PQ)地圖中為指定隊伍建立一個守護獸反應爐。

      流程:

      • 若名為 team + "" + num 的反應爐已存在且狀態 < 5(仍有效),則不重複建立、回傳 false
      • 於該隊(或中立 -1)的守護點中尋找尚未被占用(無狀態 < 5 之反應爐占據)的座標。
      • 找到可用座標後,以 reactor id 9980000 + team 建立反應爐、狀態設 1、命名為 team + "" + num,並透過 spawnReactorOnGroundBelow(MapleReactor, Point) 生成(會廣播生成封包); 再對該隊所有怪物施加對應守護獸技能(MapleCarnivalFactory.MCSkill)的效果。

      副作用:可能新增反應爐並廣播封包、對隊伍怪物套用技能效果。

      Parameters:
      team - 隊伍編號
      num - 守護獸編號(對應 MapleCarnivalFactory 中的守護獸技能,並用於反應爐命名)
      Returns:
      成功建立守護獸反應爐則為 true;若已存在或找不到可用守護點則為 false