[楓之谷私服] 最簡單的輪迴碑石(提高怪物生成倍率)教學

最後更新於 2022 年 6 月 18 日

終於還是來履行我的承諾了… 之前說有空就來研究一下輪迴怎麼做,最近剛好閒下來就開搞,目前這個版本是使用消耗品召喚輪迴(怪物)將地圖上的怪物數量 *2倍

本篇教學示範版本為 v120,應該大部分版本都適用。

效果演示

新增輪迴碑石怪物

首先用 HaRepacker 打開 Mob.wz,並且隨意新增一個 Image,比如我是新增 999026.img,內容節點請複製 9990013.img 的,然後將 hit1 整個節點刪除。

  • die1 改名為 die ,並且將 0 ~ 5 節點圖片換成輪迴碑石圖包 die 資料夾的圖片。
  • stand 的 0 ~ 8 節點圖片換成輪迴碑石圖包 stand 資料夾的圖片。
  • stand 圖片 origin X: 55, Y: 210
  • die 圖片 1, 2 origin X: 55, Y: 210 ; 3 origin X: 85, Y: 210 ; 4 origin X: 80, Y: 65 ; 5 origin X: 85, Y: 51
image 8 [楓之谷私服] 最簡單的輪迴碑石(提高怪物生成倍率)教學

info 節點的內容 :

bodyAttack: 0
elemAttr: S1H3
acc: 150
boss: 1
eva: 30
exp: 0
level: 200
MADamage: 0
maxHP: 5000000
maxMP: 5000
MDDamage: 0
PADamage: 0
PDDamage: 0
pushed: 3000
removeAfter: 300 (以秒為單位, 自行設定)
speed: -20
summonType: 0
undead: 0

最後結構如下:

image 6 [楓之谷私服] 最簡單的輪迴碑石(提高怪物生成倍率)教學

新增輪迴消耗道具

接著用 HaRepacker 打開 Item.wz,進入 Consume (消耗) 節點,找到 0210.img 雙擊展開,隨意新增一個 sub 節點,我這邊以 02109013 作為示範,內容節點直接複製 02101081 就可以。

  • icon 及 iconRaw 換成輪迴圖包中的 輪迴.png,icon及 iconRaw 的 origin 為 X:-2 , Y: 33
  • info 節點內容:
    • 新增 notSale (int) 節點為 1
    • slotMax 設為 100 (一格欄位最多能堆疊多少個)
    • timeLimited 設為 1
    • type 設為 1
  • mob 節點內容:
  • 0 – id 設為輪迴怪物代碼 (像我就是 999026 )
  • 0 – prob 設為 100
image 9 [楓之谷私服] 最簡單的輪迴碑石(提高怪物生成倍率)教學

最後結構如下:

image 4 [楓之谷私服] 最簡單的輪迴碑石(提高怪物生成倍率)教學

如果以上步驟都做完,在遊戲中下指令 !drop 2109013 獲取輪迴之後使用,地圖上應該就會出現輪迴,如果你的輪迴有被叫出來就可以繼續下面的步驟了。

順帶一提,String.wz 也要加上 2109013 的節點,不然你的輪迴消耗道具是不會有名字和描述的。

判斷地圖上有輪迴就加速怪物生長

有了輪迴怪物和輪迴召喚包後,我們還需要修改 SRC 來判斷地圖上是否有輪迴,如果有就將該地圖的怪物數量乘以你指定的倍率,但如果是特殊地圖或者有 BOSS 的地圖就不會生效。

打開 SRC,在 server.maps 裡新增 MobConstants.java,內容如下:

/*
 * 輪迴碑石
 */
package server.maps;

import server.maps.MapleMap;
import server.maps.MapleMapObject;
import server.life.MapleMonster;
import constants.MapConstants;

public class MobConstants {
    public static int[] REINCARNATION_MOB = new int[]{ 9990026, 2 }; // 輪迴怪物代碼, 生怪數量倍率

    public static int isMonsterSpawn(MapleMap map) {
        int addition = 1;
        if (MapConstants.isBossMap(map.getId()) || MapConstants.isEventMap(map.getId())) { // 判斷是否為特殊地圖, 輪迴不會在特殊地圖生效
            return 1;
        }
        for (MapleMapObject obj : map.getAllMonstersThreadsafe()) { // 判斷地圖有boss, 回傳倍率1
            final MapleMonster mob = (MapleMonster) obj;
            if (mob.getStats().isBoss() && !isReincarnationMob(mob.getId())) {
                return 1;
            }
        }
        if (map.getMonsterById(REINCARNATION_MOB[0]) != null) { // 判斷是否有輪迴
            addition *= REINCARNATION_MOB[1]; // 乘以倍率
        }
        return addition;
    }

    public static boolean isReincarnationMob(int mobid) { // 判斷是否為輪迴怪物
        if (REINCARNATION_MOB[0] == mobid) {
            return true;
        }
        return false;
    }

    public static boolean isSpawnSpeed(MapleMap map) {
        if (map.getMonsterById(REINCARNATION_MOB[0]) != null) {
            return true;
        }
        return false;
    }
}

接著打開 server.maps.MapleMap.java,在最上方引入 MobConstants

import server.maps.MobConstants;

接著在 MapleMap.java 中 ctrl + f 搜尋「public void respawn」,將 numShouldSpawn 改為以下程式碼:

final int numShouldSpawn = monsterSpawn.size() * MobConstants.isMonsterSpawn(this) - spawnedMonstersOnMap.get(); // 輪迴倍率
// final int numShouldSpawn = monsterSpawn.size() - spawnedMonstersOnMap.get();

完整的 respawn 函式程式碼為:

public void respawn(final boolean force) {
        lastSpawnTime = System.currentTimeMillis();
        if (force) { //cpq quick hack
            final int numShouldSpawn = monsterSpawn.size() * MobConstants.isMonsterSpawn(this) - spawnedMonstersOnMap.get(); // 輪迴倍率
            // final int numShouldSpawn = monsterSpawn.size() - spawnedMonstersOnMap.get();

            if (numShouldSpawn > 0) {
                int spawned = 0;

                for (Spawns spawnPoint : monsterSpawn) {
                    spawnPoint.spawnMonster(this);
                    spawned++;
                    if (spawned >= numShouldSpawn) {
                        break;
                    }
                }
            }
        } else {
            final int numShouldSpawn = maxRegularSpawn * MobConstants.isMonsterSpawn(this) - spawnedMonstersOnMap.get(); // 輪迴倍率
            // final int numShouldSpawn = maxRegularSpawn - spawnedMonstersOnMap.get();
            if (numShouldSpawn > 0) {
                int spawned = 0;

                final List<Spawns> randomSpawn = new ArrayList<Spawns>(monsterSpawn);
                Collections.shuffle(randomSpawn);

                for (Spawns spawnPoint : randomSpawn) {
                    if (spawnPoint.shouldSpawn() || GameConstants.isForceRespawn(mapid)) {
                        spawnPoint.spawnMonster(this);
                        spawned++;
                    }
                    if (spawned >= numShouldSpawn) {
                        break;
                    }
                }
            }
        }
    }

繼續在 MapleMap.java 中搜索 canSpawn,將 function 內容改為:

public final boolean canSpawn() {
    createMobInterval = (short) (MobConstants.isSpawnSpeed(this) ? 0 : 9000); // 有輪迴時怪物重生時間間隔為 0
    return lastSpawnTime > 0 && isSpawns && lastSpawnTime + createMobInterval < System.currentTimeMillis();
    // return true;
}

若地圖上有輪迴就不能再放

image 7 [楓之谷私服] 最簡單的輪迴碑石(提高怪物生成倍率)教學

1.打開 server.life.MapleMonsterStats.java 最上面 private int 處加上 ,SpawnChrId

接著在最下面加上:

public int getSpawnChrId() {
   return SpawnChrId;
}

2.打開 server.life.MapleMonster.java 最下面加上:

public final int getSpawnChrid(){
   return stats.getSpawnChrId();
}

3.在 client.MapleCharacter.java 最下方加上:(這個函式是用來判斷地圖上是否有輪迴)

public boolean isReincarnationMob() {
        for (MapleMonster monster : getMap().getAllMonster()) {
            if (monster.getId() == 9990026 && monster.getSpawnChrid() != this.getId()) { // 輪迴 mob id
                return true;
            }
        }
        return false;
    }

4.打開 handling.channel.handlerInventoryHandler.java,加上 UseSummonBagNotCSP 函式:

public static int UseSummonBagNotCSP(int itemId) {
        int result = 0;
        switch (itemId) {
            case 2109013: // 輪迴道具 ID
                result = 1;
                break;
        }
        return result;
}

5.接著搜索 UseSummonBag,在這段程式碼下方加上:

if (c.getPlayer().isGM() || !FieldLimitType.SummoningBag.check(chr.getMap().getFieldLimit())) {
   final List<Pair<Integer, Integer>> toSpawn = MapleItemInformationProvider.getInstance().getSummonMobs(itemId);

   if (toSpawn == null) {
       c.getSession().write(MaplePacketCreator.enableActions());
       return;
    }

   /* 加上下方這段 */
   if (UseSummonBagNotCSP(toUse.getItemId()) > 0) {
       int result = UseSummonBagNotCSP(toUse.getItemId());
       if (result > 0) {
          if (chr.isReincarnationMob()) {
              switch (result) {
                  case 1: {
                      chr.dropMessage("地圖上有人施放了輪迴");
                      break;
                   }
              }
              c.getSession().write(MaplePacketCreator.enableActions());
              return;
          }
       }
   }
   //....

結語

至此簡單的輪迴功能就實現了,還有很多種可以實現輪迴的方式,比如輪迴技能也是其中之一,大家可以自己多嘗試看看。這篇教學其實還有一些小問題沒有解決,就留給大家自己腦力激盪了!

4e52d54f6bc42abb41d26eb5b0df6517?s=250&d=wavatar&r=g [楓之谷私服] 最簡單的輪迴碑石(提高怪物生成倍率)教學
5 2 評分數
Article Rating
訂閱
通知
guest
11 Comments
在線反饋
查看所有評論
Month
Month
3 月 前

請問這是用在自己架設私服單人上,還是可以用在別人開的私服上呢

soya1377
soya1377
3 月 前

佛 我是直接全地圖改數量跟重生,沒有另外弄東西去觸發,感恩分享輪迴效果的做法

小白研究摸索
小白研究摸索
1 月 前

我想請問一下 按照上面的修改法 會造成無法刷出怪物的問題 v113

問題好像是在respawn 用原本語法 正常刷怪
改了respawn 之後 變成無法正常刷怪出來

小白研究摸索
小白研究摸索
回复  pluto
1 月 前

不會上傳圖片
有//的地方 是原本要修改的部分
我目前適用原版語法 把改的部分目前先標記調
還是看不懂的話我的DC 鬼魅魍魎#5079

  public void respawn(final boolean force) {
    lastSpawnTime = System.currentTimeMillis();
    if (force) { //cpq quick hack
      //final int numShouldSpawn = monsterSpawn.size() * MobConstants.isMonsterSpawn(this) – spawnedMonstersOnMap.get(); // 輪迴倍率
       final int numShouldSpawn = monsterSpawn.size() – spawnedMonstersOnMap.get();

      if (numShouldSpawn > 0) {
        int spawned = 0;

        for (Spawns spawnPoint : monsterSpawn) {
          spawnPoint.spawnMonster(this);
          spawned++;
          if (spawned >= numShouldSpawn) {
            break;
          }
        }
      }
    } else {
      //final int numShouldSpawn = maxRegularSpawn * MobConstants.isMonsterSpawn(this) – spawnedMonstersOnMap.get(); // 輪迴倍率
       final int numShouldSpawn = maxRegularSpawn – spawnedMonstersOnMap.get();
      if (numShouldSpawn > 0 && monsterSpawn.size() > 0) {
        final List<Spawns> randomSpawn = new ArrayList<>(monsterSpawn);
        Collections.shuffle(randomSpawn);
        for (Spawns spawnPoint : randomSpawn) {
          if (spawnPoint.shouldSpawn() || GameConstants.isForceRespawn(mapid)) {
            spawnPoint.spawnMonster(this);
          }
        }
      }
    }
  }

小白研究摸索 最後編輯於 1 月 前
小白研究摸索
小白研究摸索
回复  pluto
1 月 前

我是用113的端口 忘了說

補充說明 我自己改寫語法 完成設定 感謝版大耐心教學
語法設定上有點小錯誤

小白研究摸索 最後編輯於 1 月 前
july
july
26 日 前

作者你好 請問前面第一階段新增輪迴怪物做完後 進去遊戲輸入!drop 2109013後成功丟出輪迴 但是點擊輪迴後並沒有輪迴出現 而且後台還跑出了下面的錯誤訊息 請問是什麼原因造成的?

543.jpg