传奇单机架设怪物只攻击怪物不攻击人物的完整脚本设置教程详解

来源: 作者: 点击:
怪物挑谁下手,分三层判定。第一层看目标身份,引擎会把人物、英雄、分身、宝宝、怪物、NPC 分开处理,不同类型走不同分支。第二层看这只怪自己的行为模板,也就是 Monster.DB 里的 Race 和 Racelmg,Race 决定它怎么动、打不打人,Racelmg 决定它动手时的表现。第三层看关系,也就是国家与阵营。想让怪物眼里只剩同类,思路就是把第二层的模板换成不打人的那种,再用第三层的关系给怪物造一个能打的对手。指望在 QFunction 里写一段脚本直接改写怪物的目标选择,做不到,脚本能管的是刷怪时给怪物发什么身份、被攻击时怎么处理后续。

一、用国家参数刷怪,这是最贴近需求的做法

GEE、翎风这类内核带国战系统,刷怪命令的最后几列就是给怪物指定国家、以及规定它和同国玩家、异国怪物的关系。先在服务端目录 Envir\Nations\Nations.ini 里确认国家名字,默认只定义了三个:

[Names]
NationalNames1=沧月国
NationalNames2=凌风国
NationalNames3=炎天国

名字没定义的国家,脚本里写进去也加不进人,怪物归属同样无效。

接着打开 Mir200\Envir\MonGen.txt,按完整列写怪物:

地图 坐标X 坐标Y 怪物名字 范围 数量 间隔 集中刷新坐标机率 名字颜色 内功怪物(0,1) 国家ID 同国家玩家是否可攻击(0,1) 不同国家怪物是否可PK(0,1)

假设地图编号 3,想在盟重附近造一个怪物对打的场地:

3 330 330 沃玛卫士 5 20 30 0 255 0 1 1 1
3 340 340 黑野猪 5 20 30 0 255 0 2 1 1

倒数第三列是这批怪挂到哪个国家,上面两行分别挂到 1 国和 2 国。倒数第二列管本国玩家能不能打它,想让玩家还能插手上场就填 1,填 0 的话本国玩家连碰都碰不到。最后一列填 1,允许不同国家的怪物互相开打。GEE 内核有一条固有规则,国家怪物不会攻击本国,所以人物只要归到和怪物同一个国家,怪物就不会对他动手,而两个国家的怪照面就掐起来。

如果习惯用脚本刷怪,MONGENEX 的完整写法是:

[@MonFight]
#IF
CHECKHUM 3 1
#ACT
ClearMapMon 3
MONGENEX 3 330 330 沃玛卫士 5 20 255 0 1 1 1
MONGENEX 3 340 340 黑野猪 5 20 255 0 2 1 1
Break

这里最容易出错的地方是省略颜色那一列。参数按位置读取,颜色位空掉不写占位,后面几列整体往前挪,国家就填错了地方。内功怪物位同理,不想要也得留着 0。

短命令和 GM 命令也能用,格式分别是:

MonGen 怪物名 X Y 国家ID 同国家玩家是否可攻击(0,1) 不同国家怪物是否可PK(0,1)
@mob 怪物名 数量 等级 国家ID 同国家玩家是否可攻击(0,1) 不同国家怪物是否可PK(0,1)

单机自己调试的时候,用 @mob 刷两批不同国家的怪最省事,站在旁边看它们打就行了。

玩家一侧要在脚本里把人物拉进同一个国家。多数内核的登录触发段(有的版本叫 @Login,以你引擎说明为准)里加这几行:

[@Login]
#IF
CheckNation 0
#ACT
JoinNation 1

CheckNation 0 表示这个人还没加入任何国家,JoinNation 后面跟的是国家编号。想临时退出用 ExitNation,不同内核命令名不一样,铁血那套用的是 JoinNational 国家名、CheckNational 国家名,照着自己引擎的说明写。另外记得在引擎控制台里把国战相关开关打开,参数设置里能找到国战模式控制一类的选项,不开的话国家关系不参与判定。

二、不想动国家系统,就直接换 Race 模板

Monster.DB 里几个现成的值本身就写着"不打普通玩家"。

Race 11 是大刀卫士那类模板,主动攻击怪物和红名,白名玩家从旁边过它不理。Race 12 是巡逻卫士版本,行为一样,多坐标巡逻。Race 210 和 211 也是大刀卫士式的打法,一个原地打一下回位,一个可以走动。这四种是拿来主义,换上外形和属性就能用。

Race 112 只主动攻击红名,射程 11,只要人物不红名就绝对安全,喜欢挂机旁观的话这个最稳。

Race 108 不攻击人,同时也不被攻击伤害,必须配合 MOBPLACE 系列的刷怪命令使用,适合做背景装饰怪。

Race 141 不攻击人物和宝宝,会自动往指定坐标走,做护送、做场景摆件都行。

Race 51 和 52 是被动型,挨打才会掉血,52 还有几率逃跑,作为"只挨打不还手"的素材也常用。

改完别忘了一件事,Race 和 Racelmg 得成对。Race 决定逻辑,Racelmg 决定动作,把一只近战怪的 Racelmg 单独改掉,表现出来就是原地抽搐、打不出伤害。用 DBC2000 打开 Monster.DB 改完,要重启 M2 才吃设置。

三、地图参数和人物侧的两道保险

MapInfo.txt 里可以给单张地图加限制:

[GA1 皇宫后院] ATTACKLEVEL(100)

这行写在原有的地图参数后面,意思是这张图里的怪物不会主动攻击 100 级以下的人物,等级压制型的保护场就这么做。国战地图还有专门的 FIGHT5 参数,FIGHT5 默认死亡不掉落,写 FIGHT5(1) 才会掉东西,怪物对打的场地用这个比较合适。

人物这一侧还有一条命令,强制和平模式:

#IF
#ACT
SetHumAttackMode 1 3600 *

参数 1 是和平模式,3600 是持续秒数,星号代表全地图生效。这条不能阻止怪物打你,但能防止玩家自己乱开红,做观看场地的时候顺手加上不难。

四、脚本层面判断对手到底是人还是怪

有些场景没法完全靠国家参数解决,比如被打之后要不要还手、本国玩家打怪要不要额外补偿。人物脚本里用 CHECKCURRTARGETRACE 判断对方身份,0 是人物,1 是英雄,151 是分身,其余数值基本是怪物。写在 QFunction-0.txt 里的样子:

[@Struck]
#IF
CHECKCURRTARGETRACE <> 0
#ACT
SENDMSG 6 你被怪物【<CURRRTARGETNAME>】攻击了 Break #IF CHECKCURRTARGETRACE = 0 #ACT SENDMSG 6 攻击来自人物【<CURRRTARGETNAME>】
Break

物理被打走 [@Struck],魔法被打走 [@MagicStruck],自己打人走 [@Attack]。这类判断只能改提示、补血、加状态,不能把怪物已经锁定你的目标取消掉,别指望用它实现"怪不打人"。

BLUE 一系的内核在怪物表上多了攻击触发字段,monster 表的 HitTrigger 设成 1,再配合 QFunction 里的 [@Attack] 和 [@UnderAttack],可以在怪物动手的瞬间读到攻击方身份,变量是 <
𝐴
𝑇
𝑇
𝐼
𝑁
𝐹
𝑂
𝑅
𝐴
𝐶
𝐸
>
、
<
ATTINFO
R
​

ACE>、<TARINFO_RACE>、<
𝐴
𝑇
𝑇
𝐼
𝑁
𝐹
𝑂
𝐼
𝑆
ℎ
𝑒
𝑟
𝑜
>
。这里
𝑅
𝑎
𝑐
𝑒
为
1
通常是玩家,非玩家就是随从一类,脚本里写
𝐶
𝑂
𝑀
𝑃
𝑉
𝐴
𝐿
<
ATTINFO
I
​

Shero>。这里Race为1通常是玩家,非玩家就是随从一类,脚本里写COMPVAL<ATTINFO_RACE> ! 1 就能把"人打的"和"怪打的"分开处理,被打时给主人补血、不触发还手逻辑,观感上就很接近你要的效果。

翎风内核还有一套怪物标识系统,SetRangeMonAddByte 批量标记范围内怪物,M.SetMonAddByte 标记当前攻击的怪,M.CheckMonAddByte 和 M.GetMonAddByte 用来读标识。配合攻击触发,可以把参与互殴的怪单独标出来,做只对怪生效的伤害或者额外掉落的判断。这套东西不能改变怪物选目标,但能让"怪打怪"的场面更好控制。

五、单机环境下的完整操作顺序

第一步,备份 Mir200\Envir 整个目录和 DB 目录下的 Monster.DB,改坏了能退回来。

第二步,用 DBC2000 打开 Monster.DB,挑两支队伍的怪物,把 Race 改成 11 或者 112,Racelmg 按原表配套的值留着别乱动,改完保存。

第三步,打开 Nations.ini 确认至少两个国家有名字。

第四步,在 MonGen.txt 里写两条分属不同国家的刷怪记录,避开原有的刷怪点,坐标差开几格。

第五步,在登录触发里把上线人物 JoinNation 到 1 国。

第六步,引擎控制台打开国战相关选项。

第七步,重启 M2Server,上线站到刷怪点旁边,看怪物之间是否互相攻击、怪物是否对你视若无睹。

第八步,如果国家这一套跑不出效果,把 Race 换成 112 只打红名的写法作为保底,人物保持白名,观感同样达标。

六、改完不生效的排查顺序

先看你现在用的号是不是 GM。GM 号默认带隐身状态,怪物看到你也不会动手,换个普通号测试最清楚。其次是 Monster.DB 里的 CoolEye,这个值管反隐形范围,调得过大,隐身戒指都失效,调得过小,远处的怪看不见你,也会让人误以为设置成功。

然后核对怪物名字。MonGen.txt 里的名字必须和 Monster.DB 里的完全一致,中间不能有空格,缩写、别名、多打一个空格都刷不出来。

再看国家名字是否真的定义过。NationalNames 后面留空的国家,怪物挂上去等于没挂。

最后确认有没有重启 M2。MonGen.txt 和 Monster.DB 都在启动时读取,改完不重启,一切照旧。

七、几个容易忽略的坑

参数别跨列留空。MONGENEX 和 MonGen.txt 都是按位置读参数,颜色、内功怪物这些位即使不用也要占位写 0,一旦空掉,后面的国家编号就会往前窜,怪物要么不刷,要么挂错阵营。

地图参数前的分号要用半角;写错成全角,整行不生效还可能让地图读取出错。

怪物互殴会掉经验也会掉落,经验和爆率照常结算给最后一击的怪,跟人物无关,想控制产出就得从 MonItems 那边的爆率文件下手。

人物的宝宝和英雄仍然会被邻国怪物当作目标,想让召唤物也安全,得用脚本让它们同步加入同一国家,或者干脆把这类怪的 Race 调成不打宝宝的那几种。

怪物数量多起来之后留意引擎性能。M2 控制台的性能参数里有怪物处理间隔,几十只怪对打不用管,成百上千只同屏互殴就把间隔往上调,机器的负载会明显下来。

最后回到那个原始问题。能靠一段脚本直接改掉怪物目标选择的引擎不多,真正稳的做法是用国家参数把人群和怪群分开,再让不同国家的怪互相下手;退一步就用 Race 里的现成模板,11、12、112 这几个值本身就是"不打白名玩家"的逻辑。两条路配合着用,单机里造一个怪物自己打自己的场面并不难。