Class MapleMonsterSpawnManager

java.lang.Object
server.maps.MapleMonsterSpawnManager

public final class MapleMonsterSpawnManager extends Object
地圖怪物的「生成(spawn)子系統」協作者,由 P5 God class 拆分自 MapleMap

本類別封裝怪物的生成(一般 / 復活 / 假怪 / 沙漠炸彈 / 札昆 / 混沌札昆 / 帶特效)、生成點 (monsterSpawn)的管理與重生(respawn)排程、生成率計算(loadMonsterRate)、 以及嘉年華怪物生成。MapleMap 以**逐字搬移**的方式把這些方法移入此處,並對每個對外公開 方法保留**簽名完全相同**的委派(delegate),因此 src/ 的呼叫端與 ~2,700 支腳本完全不受影響。

所有生成相關狀態仍存放在所屬 MapleMap(同 package 存取的 package-private 欄位: monsterSpawn / spawnedMonstersOnMap / maxRegularSpawn / monsterRate / partyBonusRate / fixedMob / lastSpawnTime / createMobInterval / isSpawns / mapid / channel / squadSchedule / nodes);本協作者 僅持有對該地圖的回參考。怪物的擊殺 / 掉落 / 經驗(killMonster / dropFromMonster) 仍留在 MapleMap(牽涉 characters/EXP/成就,屬後續拆分區塊)。

  • Method Details

    • spawnMonster_sSack

      public final void spawnMonster_sSack(MapleMonster mob, Point pos, int spawnType)
      在指定座標下方的地面生成怪物(以指定的生成動畫類型)。

      先以 MapleMap.calcPointBelow(Point)pos 校正到地面落點(再往上 1 像素) 作為怪物座標,接著委派給 spawnMonster(MapleMonster, int)。會送出生成封包並使 地圖上的存活怪物計數遞增。

      Parameters:
      mob - 欲生成的怪物實例(座標會被改寫)
      pos - 參考座標,實際生成點為其下方地面
      spawnType - 生成動畫 / 特效類型
    • spawnMonsterOnGroundBelow

      public final void spawnMonsterOnGroundBelow(MapleMonster mob, Point pos)
      在指定座標下方的地面生成怪物(使用預設生成類型 -2)。

      等同以 spawnType = -2 呼叫 spawnMonster_sSack(MapleMonster, Point, int)。 會送出生成封包並使地圖上的存活怪物計數遞增。

      Parameters:
      mob - 欲生成的怪物實例(座標會被改寫)
      pos - 參考座標,實際生成點為其下方地面
    • spawnMonsterWithEffectBelow

      public final int spawnMonsterWithEffectBelow(MapleMonster mob, Point pos, int effect)
      在指定座標下方的地面生成帶特效的怪物。

      先以 MapleMap.calcPointBelow(Point) 校正到地面落點,再委派給 spawnMonsterWithEffect(MapleMonster, int, Point)。會送出生成封包並使地圖上的 存活怪物計數遞增。

      Parameters:
      mob - 欲生成的怪物實例
      pos - 參考座標,實際生成點為其下方地面
      effect - 生成時播放的特效類型
      Returns:
      生成成功時回傳該怪物的物件 ID;發生例外時回傳 -1
    • spawnZakum

      public final void spawnZakum(int x, int y)
      在指定座標生成札昆(Zakum)王及其所有手臂部位。

      本體(怪物 ID 8800000)以假怪形式生成(spawnFakeMonster(MapleMonster)), 隨後逐一以生成類型 -2 生成八個手臂部位(88000038800010)。所有部位 皆放置於本體下方地面的同一落點。若所屬地圖已有小隊(squad)排程,會呼叫 MapleMap.cancelSquadSchedule(boolean) 取消之。

      會送出多個生成封包並使地圖上的存活怪物計數遞增。

      Parameters:
      x - 生成參考座標的 X
      y - 生成參考座標的 Y
    • spawnChaosZakum

      public final void spawnChaosZakum(int x, int y)
      在指定座標生成混沌札昆(Chaos Zakum)王及其所有手臂部位。

      行為與 spawnZakum(int, int) 相同,但使用混沌版本的怪物 ID:本體為 8800100 (以假怪形式生成),手臂部位為 88001038800110(以生成類型 -2 生成)。 若所屬地圖已有小隊排程,會呼叫 MapleMap.cancelSquadSchedule(boolean) 取消之。

      會送出多個生成封包並使地圖上的存活怪物計數遞增。

      Parameters:
      x - 生成參考座標的 X
      y - 生成參考座標的 Y
    • spawnFakeMonsterOnGroundBelow

      public final void spawnFakeMonsterOnGroundBelow(MapleMonster mob, Point pos)
      在指定座標下方的地面生成「假怪」(fake monster)。

      假怪不參與一般戰鬥流程,通常作為視覺擺設或召喚母體使用。座標先以 MapleMap.calcPointBelow(Point) 校正到地面後再上移 1 像素,接著委派給 spawnFakeMonster(MapleMonster)。會送出生成封包並使地圖上的存活怪物計數遞增。

      Parameters:
      mob - 欲生成的假怪實例(座標與 fake 旗標會被改寫)
      pos - 參考座標,實際生成點為其下方地面
    • spawnRevives

      public final void spawnRevives(MapleMonster monster, int oid)
      生成由某隻怪物「復活 / 召喚」(revive)出來的子怪物。

      會設定怪物所屬地圖、依其 removeAfter 設定登記自動消滅 (checkRemoveAfter(MapleMonster))、並以 oid 連結到召喚來源。生成封包的 召喚動畫類型取自怪物的 summonType<= 1 時改用 -3)。隨後更新怪物 控制者並使地圖上的存活怪物計數遞增。

      Parameters:
      monster - 欲生成的復活 / 召喚怪物
      oid - 召喚來源的物件 ID,將設為此怪物的 link OID
    • spawnMonster

      public final void spawnMonster(MapleMonster monster, int spawnType)
      在地圖上生成怪物(不覆寫怪物自身的召喚類型)。

      等同以 overwrite = false 呼叫 spawnMonster(MapleMonster, int, boolean)。 會送出生成封包並使地圖上的存活怪物計數遞增。

      Parameters:
      monster - 欲生成的怪物實例(會被設定所屬地圖)
      spawnType - 生成動畫 / 特效類型
    • spawnMonster

      public final void spawnMonster(MapleMonster monster, int spawnType, boolean overwrite)
      在地圖上生成怪物,核心生成實作。

      流程:設定所屬地圖 → 依 removeAfter 登記自動消滅 → 處理若干特例 → 送出生成封包並 加入地圖物件、更新怪物控制者、遞增存活怪物計數。

      特例與副作用:

      • 競技場沙漠炸彈(怪物 ID 9300166)會以隨機延遲透過 Timer.MapTimer 排程,稍後 廣播擊殺封包使其自爆。
      • ServerConstants.EnableHellCh 開啟且當前頻道為地獄頻道時,會依等級調整怪物強度 (changeLevelmod)。
      • 實際送出的召喚動畫類型:當怪物 summonType <= 1summonType == 27overwrite 為真時採用傳入的 spawnType,否則採用怪物自身的 summonType
      Parameters:
      monster - 欲生成的怪物實例(會被設定所屬地圖)
      spawnType - 生成動畫 / 特效類型
      overwrite - 為 true 時強制以 spawnType 覆寫怪物自身的召喚類型
    • spawnMonsterWithEffect

      public final int spawnMonsterWithEffect(MapleMonster monster, int effect, Point pos)
      在指定座標生成帶特效的怪物。

      設定怪物所屬地圖與座標後,以指定 effect 作為生成動畫送出封包並加入地圖物件,接著更新 怪物控制者並遞增存活怪物計數。整個流程包在 try/catch 中:任何例外都會被吞掉並回傳 -1 (生成失敗)。

      Parameters:
      monster - 欲生成的怪物實例
      effect - 生成時播放的特效類型
      pos - 怪物的生成座標
      Returns:
      生成成功時回傳該怪物的物件 ID;發生例外時回傳 -1
    • spawnFakeMonster

      public final void spawnFakeMonster(MapleMonster monster)
      在怪物目前座標生成「假怪」(fake monster)。

      會設定所屬地圖並將怪物標記為 fake,以固定召喚動畫類型 -4 送出生成封包並加入地圖物件, 接著更新怪物控制者並遞增存活怪物計數。假怪通常作為札昆本體等視覺擺設 / 召喚母體使用。

      Parameters:
      monster - 欲生成的假怪實例(所屬地圖與 fake 旗標會被改寫)
    • getNumSpawnPoints

      public final int getNumSpawnPoints()
      取得本地圖目前登記的生成點數量。
      Returns:
      monsterSpawn 清單的大小
    • loadMonsterRate

      public final void loadMonsterRate(boolean first)
      依生成點數量與地圖生成率,計算並設定地圖的最大常規生成數,並重新排序生成點。

      計算規則:

      • 生成點 >= 20 或有組隊加成(partyBonusRate > 0)時, maxRegularSpawn = round(生成點數 / monsterRate);否則 maxRegularSpawn = ceil(生成點數 * monsterRate)
      • 若設有固定怪數(fixedMob > 0)則直接採用之;否則將結果夾在下限 2 與 生成點數之間(超出時取 max(10, 生成點數))。

      接著把生成點重新排序——將 BOSS 生成點移到清單前段、一般怪在後,並過濾掉嘉年華隊伍 (carnivalTeam >= 2)的生成點。

      first 為真且有生成點時,會記錄 lastSpawnTime、對強制重生地圖把 createMobInterval 設為 15000,並立即呼叫 respawn(boolean) 預先鋪怪 (免去玩家進場後的等待)。

      副作用:會改寫 maxRegularSpawn 並重建 monsterSpawn 清單;first 路徑 另會送出生成封包。

      Parameters:
      first - 是否為地圖首次載入(為真時會立即觸發一次重生)
    • addMonsterSpawn

      public final SpawnPoint addMonsterSpawn(MapleMonster monster, int mobTime, byte carnivalTeam, String msg)
      依怪物目前座標新增一個生成點(不立即生成怪物)。

      座標先以 MapleMap.calcPointBelow(Point) 校正到地面後再上移 1 像素。若 carnivalTeam > -1(屬於某嘉年華隊伍)則插入清單最前端,否則附加於末端。

      Parameters:
      monster - 該生成點所要生成的怪物樣板
      mobTime - 重生間隔(秒);0 表示僅生成一次
      carnivalTeam - 嘉年華隊伍編號,-1 表示非嘉年華
      msg - 生成時顯示的訊息,可為 null
      Returns:
      新建立並加入清單的 SpawnPoint
    • addMonsterSpawn

      public final SpawnPoint addMonsterSpawn(MapleMonster monster, int mobTime, byte carnivalTeam, String msg, boolean spawn)
      依怪物目前座標新增一個生成點,並可選擇立即生成一隻怪物。

      行為與 addMonsterSpawn(MapleMonster, int, byte, String) 相同;若 spawn 為真, 額外呼叫該生成點的 SpawnPoint.spawnMonster(MapleMap) 立即生成一隻怪物(會送出生成封包並 遞增存活怪物計數)。

      Parameters:
      monster - 該生成點所要生成的怪物樣板
      mobTime - 重生間隔(秒);0 表示僅生成一次
      carnivalTeam - 嘉年華隊伍編號,-1 表示非嘉年華
      msg - 生成時顯示的訊息,可為 null
      spawn - 為 true 時於新增後立即生成一隻怪物
      Returns:
      新建立並加入清單的 SpawnPoint
    • addAreaMonsterSpawn

      public final void addAreaMonsterSpawn(MapleMonster monster, Point pos1, Point pos2, Point pos3, int mobTime, String msg, boolean shouldSpawn)
      新增一個「區域 BOSS」生成點(SpawnPointAreaBoss),怪物可在三個落點之間隨機出現。

      三個座標各自以 MapleMap.calcPointBelow(Point) 校正到地面後上移 1 像素。若三者皆無法 落地(全為 null)則記錄警告並放棄生成;否則以任一有效座標補齊其餘 null 座標, 最後將生成點加入 monsterSpawn

      Parameters:
      monster - 該區域生成點所要生成的怪物樣板
      pos1 - 第一個候選落點,可為 null
      pos2 - 第二個候選落點,可為 null
      pos3 - 第三個候選落點,可為 null
      mobTime - 重生間隔(秒)
      msg - 生成時顯示的訊息,可為 null
      shouldSpawn - 是否允許自動生成
    • respawn

      public void respawn(boolean force)
      對地圖執行一次怪物重生(以目前系統時間為時間基準)。

      等同以 now = System.currentTimeMillis() 呼叫 respawn(boolean, long)

      Parameters:
      force - 為 true 時忽略各生成點的重生冷卻,直接補滿到生成點總數(CPQ 快速 hack)
    • respawn

      public void respawn(boolean force, long now)
      對地圖執行一次怪物重生,核心重生實作。

      會先把 lastSpawnTime 更新為傳入的 now。兩種模式:

      • force(CPQ 快速 hack):應生成數 = 生成點總數 − 目前存活數,依清單順序逐點生成 直到補足,忽略個別生成點的冷卻條件。
      • 一般:目標數為強制重生地圖的生成點總數、否則 maxRegularSpawn,減去目前存活數; 將生成點清單洗牌(Collections.shuffle(List))後逐點檢查——非 isSpawns 地圖會跳過 具 mobTime 的生成點,並僅在生成點冷卻已過 / 屬強制重生地圖 / 小隊加成的小地圖條件 成立時才生成,直到補足為止。

      副作用:會更新 lastSpawnTime 並對每個被選中的生成點送出生成封包、遞增存活怪物計數。

      Parameters:
      force - 為 true 時忽略各生成點的重生冷卻,直接補滿到生成點總數
      now - 作為重生判定基準的時間戳(毫秒)
    • resetAllSpawnPoint

      public final void resetAllSpawnPoint(int mobid, int mobTime)
      將地圖上所有生成點重設為改生成指定怪物 ID 的新生成點。

      流程:快照現有生成點 → 呼叫 MapleMap.resetFully() 完全重置地圖 → 清空 monsterSpawn → 依每個舊生成點的朝向 / 足跡 / 座標建立新怪物並透過 addMonsterSpawn(MapleMonster, int, byte, String) 重新登記(carnivalTeam = -1、 無訊息)→ 最後以 loadMonsterRate(boolean)first = true)重算生成率並觸發重生。

      副作用:會清掉地圖既有狀態並重建生成點,且立即觸發一次生成。

      Parameters:
      mobid - 重設後各生成點所要生成的怪物 ID
      mobTime - 新生成點的重生間隔(秒)
    • resetSpawns

      public final void resetSpawns()
      移除所有嘉年華生成點並重新啟用一般生成。

      逐一從 monsterSpawn 移除 carnivalId > -1 的生成點,並呼叫 MapleMap.setSpawns(boolean)(true) 開啟生成。只有在確實移除過嘉年華生成點時, 才會以 loadMonsterRate(boolean)first = true)重算生成率並觸發重生。

    • makeCarnivalSpawn

      public final boolean makeCarnivalSpawn(int team, MapleMonster newMons, int num)
      為怪物嘉年華(CPQ)在指定隊伍的可用生成節點上新增一個怪物生成點。

      從地圖節點資料(MapleNodes.MonsterPoint)中尋找屬於該隊伍或共用(team == -1) 且尚未被既有嘉年華生成點佔用的節點;找到後依該節點的座標 / 朝向 / 足跡等設定怪物,透過 addMonsterSpawn(MapleMonster, int, byte, String)mobTime = 1)登記生成點,並以 num 標記其嘉年華屬性。若無可用節點則不新增。

      Parameters:
      team - 嘉年華隊伍編號
      newMons - 欲生成的怪物實例(多項座標 / 朝向欄位會被改寫)
      num - 嘉年華生成點的編號標記(傳給 SpawnPoint.setCarnival(int)
      Returns:
      成功找到節點並新增生成點時回傳 true,否則 false
    • canSpawn

      public final boolean canSpawn(long now)
      判斷距上次生成是否已過足夠時間、可再次觸發重生。
      Parameters:
      now - 目前時間戳(毫秒)
      Returns:
      lastSpawnTime > 0 且已超過 lastSpawnTime + createMobInterval 時回傳 true,否則 false
    • addMaxMobInMap

      public void addMaxMobInMap()
      將地圖的最大常規生成數加一。

      副作用:遞增所屬地圖的 maxRegularSpawn 欄位。