Magical-H 发表于 2025-2-22 14:04:02

【服务端】[GMS083] [事件脚本] 如何实现最简单的Boss召唤功能

本帖最后由 Magical-H 于 2025-2-22 14:15 编辑

使用事件脚本实现最简单的Boss召唤功能

本教程以北斗服务端(https://github.com/BeiDouMS/BeiDou-Server)为基础进行制作

北斗服务端自带有一个包含中文注释的事件模板,路径位于:scripts-zh-CN/event/0_EXAMPLE.js
但是召唤Boss这些功能还需要另外构造代码,本贴简单讲解如何实现召唤。

本次例子以修复东方神州大王蜈蚣事件为例子(NPC使用NextLevel语法构造):
事件与NPC脚本均有注释以方便理解

以下代码为事件自带的变量,可以根据需求自定义
// 事件实例化变量
var isPq = true; // 是否为PQ(Party Quest)类型事件。
var minPlayers = 1, maxPlayers = 6; // 该事件实例允许的队伍成员数量范围。
var minLevel = 25, maxLevel = 90;   // 合格队伍成员的等级范围。
var entryMap = 701010323;               // 事件启动时玩家进入的初始地图。
var exitMap = 701010320;                // 玩家未能完成事件时被传送至此地图。
var recruitMap = 701010322;             // 玩家必须在此地图上才能开始此事件。
var clearMap = 701010323;               // 玩家成功完成事件后被传送至此地图。

var minMapId = 701010323;               // 事件发生在此地图ID区间内。若玩家超出此范围则立即从事件中移除。
var maxMapId = 701010323;

var eventTime = 10;            // 事件的最大允许时间,以分钟计。

const maxLobbies = 1;       // 并发活跃大厅的最大数量。

var BossID = 9600009;                   // 待生成的BOSS
var PosX = 2261 , PosY = 823;         // 生成的坐标
var Difficulty = true;                  // 根据传入的难度值以倍数方式提高怪物的各项指标,在BossID有效的情况下。

var BossDropList = ;                  // 掉落物品列表
var BossDropCount = ;               // 掉落最大数量
var BossDropChance = ;                // 掉率

const GameConfig = Java.type('org.gms.config.GameConfig');
minPlayers = GameConfig.getServerBoolean("use_enable_solo_expeditions") ? 1 : minPlayers;// 如果解除远征队人数限制,则最低人数改为1人
以下为设置事件要求信息/**
* 设置并显示事件的要求信息。
*/
function setEventRequirements() {
    var reqStr = "";

    reqStr += "\r\n   组队人数: ";
    if (maxPlayers - minPlayers >= 1) {
      reqStr += minPlayers + " ~ " + maxPlayers;
    } else {
      reqStr += minPlayers;
    }

    reqStr += "\r\n   等级要求: ";
    if (maxLevel - minLevel >= 1) {
      reqStr += minLevel + " ~ " + maxLevel;
    } else {
      reqStr += minLevel;
    }

    reqStr += "\r\n   时间限制: ";
    reqStr += eventTime + " 分钟";

    em.setProperty("party", reqStr);
}

以下为设置事件召唤Boss关键代码
/**
* 设置事件实例。
* @param {number} level - 事件级别。
* @param {number} lobbyid - 大厅ID。
* @returns {EventInstanceManager} 事件实例管理器。
*/
function setup(level, lobbyid) {
    let eim = em.newInstance(em.getName() + lobbyid);
    eim.setProperty("level", level);

    respawnStages(eim);
    eim.startEventTimer(eventTime * 60000);
    setEventRewards(eim);
    setEventExclusives(eim);

    /**
   * 以下为自定义召唤指定Boss,如BossID为null或者不存在则使用默认的地图生怪。
   * @type {any}
   */
    if(BossID != null && BossID > 0) {
      const LifeFactory = Java.type('org.gms.server.life.LifeFactory');
      let mob = LifeFactory.getMonster(BossID);
      if(mob != null) {
            let map = eim.getMapInstance(entryMap);
            map.killAllMonsters();      // 杀死原本地图上的所有怪物
            if(Difficulty) {
                level = level <= 0 ? 1 : level; //最小难度为1
                let stats = mob.getStats();
                let HpMax = mob.getMaxHp() * level;
                  HpMax = HpMax > 2147483647 ? 2147483647 : HpMax;
                let MpMax = mob.getMaxMp() * level;
                  MpMax = MpMax > 2147483647 ? 2147483647 : MpMax;
                mob.setStartingHp(HpMax);
                mob.setMp(MpMax);
                //以下属性似乎没有作用,先留着
                stats.setPADamage(stats.getPADamage() * level);
                stats.setPDDamage(stats.getPDDamage() * level);
                stats.setMADamage(stats.getMADamage() * level);
                stats.setMDDamage(stats.getMDDamage() * level);
                mob.setStats(stats);
            }
            map.spawnMonsterOnGroundBelow(mob, new java.awt.Point(PosX, PosY));   //生成指定怪物在指定坐标
      }
    }

    const DropList = BossDropList;                                  // 掉落物品列表
    const DropCount = BossDropCount;                              // 掉落最大数量
    const DropChance = BossDropChance;                              // 掉率
    BossDropList = [];
    for (let i = 0; i < DropList.length; i++) {
      const chance = DropChance * 10000;
      for (let j = 0; j < DropCount; j++) {
            if (Math.random() * 10000 < chance) {
                BossDropList.push(DropList);
            }
      }
    }
    return eim;
}以下为NPC开始事件代码function levelEnter() {
    let msg;
    //4103和8512均为寻找赤珠的任务,似乎是不同版本的任务。
    if(!isRepeat && (cm.isQuestCompleted(4103) || cm.isQuestCompleted(8512))) {//完成了赤珠任务将传送到一个地图
      let level = cm.getLevel();
      if(level >= LevelMin && level <= LevelMax) {
            cm.warp(mapID);
      } else {
            msg = '你目前无法执行这个#b秘密任务#k,因你不符合要求:\r\n\r\n';
            msg += `等级要求:${LevelMin} ~ ${LevelMax}`;
      }
    } else {
      var eli = em.getEligibleParty(cm.getParty());
      if (eli.size() > 0) {
            if (!em.startInstance(cm.getParty(), cm.getPlayer().getMap(), EventLevel)) {
                msg = '已经有其他人员在执行#b秘密任务#k了,请稍后再试。';
            }
      } else {
            msg = '你目前无法执行这个#b秘密任务#k,因你不符合要求:' + em.getProperty('party');
      }
    }
    if(msg) cm.sendOk(msg);
    leveldispose();
}关键代码基本上就由这几部分组成,剩下的请参考完整代码里的注释

由于篇幅受限,完整代码改为附件形式。
1、将下方附件下载后重名为并保存到路径:scripts-zh-CN/event/WuGongPQ.js



2、将下方附件下载后重名为并保存到路径:scripts-zh-CN/npc/9310006.js




至此,完成了大王蜈蚣召唤事件。

BurgerKing 发表于 2025-2-24 18:21:28

正在學習事件方面的,太感謝了。:loveliness:
页: [1]
查看完整版本: 【服务端】[GMS083] [事件脚本] 如何实现最简单的Boss召唤功能