总体介绍
此脚本可以实现很多DCS编辑器中原本没有或要设置一大串触发器才能实现的功能。它的原理是将其判定的内容写入用户指定的旗标中,以完成相应触发。
比如,我们想根据战区内的玩家数量动态调整游戏难度,只有在玩家数大于某个值时才会出生额外的敌机。
使用OMS可以将该区域内的玩家数写入一个旗标值中,之后可以通过游戏自带的触发器判断,如果旗标值大于XX,则激活额外敌机群组。
此脚本已在狐狸大导演(PP-FOX)精心制作的 马夫湖 和 暴风雪 多人战役中成功应用
注意:使用此脚本前,你需要已经对DCS任务编辑器,尤其是如何使用触发器和旗标有一个完整的认识,如果还不能做到这一点,推荐先观看:蛋卷的DCS任务编辑器综合教学
蛋卷的OMS脚本是在MIST脚本基础上编写,更多信息可以看 这里
使用准备
载入脚本
触发器 当任务开始
- 条件 空
- 动作 执行脚本文件
载入 mist_x_x_xxx.lua
和 OMS_xxx.lua
,注意mist需要在OMS之上
定义参与判定的玩家列表
如果跳过下列操作,则玩家列表定义为所有 客户端
可选单位
自定义设置可用于排除某些单位(如想让制空组玩家不参与触发器判定)或额外添加某些单位(如把某些AI飞机同样当作玩家参与判定),设置方法为:
触发器 当任务开始
- 条件 空
- 动作 执行脚本
,然后写所需的代码(看下面)
玩家单位列表储存在变量 oms.players
中,有几种不同的定义方式,详细解释可以看 这里
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| --定义地图上的所有中国单位为参与判定的玩家:(慎用,这样也包括AI飞机和地面单位)
oms.players = {'[c]China'}
--定义所有美国固定翼单位为参与判定的玩家:
oms.players = {'[c][plane]USA'}
--定义群组uzi-1、uzi-2为参与判定的玩家
oms.players = {'[g]uzi-1','[g]uzi-1'}
--定义单位'colt-1-1'、'colt-1-2'为参与判定的玩家
oms.players = {'colt-1-1'、'colt-1-2'}
--可混用,比如:
--定义所有中国单位、美国直升机和单位'sabre'为参与判定的玩家
oms.players = {'[c]China','[c][helicopter]USA','sabre'}
|
这种使用 {'[x]xxx','xxx'}
的定义方式被成为 Unit Name Table (UNT)
,在之后使用具体函数时会用到
使用方法
输出值
OMS的函数可以用触发器动作中的 执行脚本
运行,并把结果写入你指定的旗标中
如需要持续运行,可以用
触发器 持续
- 条件 空
- 动作 执行脚本
也可以根据任务情况,自定义开始运行的条件和是否需要多次运行
大部分的OMS函数都同时具有把结果输出到旗标或变量名的功能,如检测触发区内有多少玩家的函数 oms.inZone
1
2
3
4
5
6
7
8
9
10
| --可以把玩家数量写入一个旗标(如写入10号旗标),此时不用在前面写输出的变量名
oms.inZone({'Combat Zone'},10)
--虽然旗标值必须是非负整数,但旗标名不一定需要是数字
--可以设置成具体的名字,如给旗标起名'playerCount'
oms.inZone({'Combat Zone'},'playerCount')
--也可以把玩家数量输出到一个变量中(如写入playerCount变量)
playerNumber = oms.inZone({'Combat Zone'})
--如果你之后还写了自己的代码,即可调用playerNumber变量
|
这样你可以使用编辑器自带的旗标判定系统,也可以用后续自己写的代码对输出值进行判断。
所有输出高度、速度、航向和航向差的函数,正常运行时最小输出值均为 1
。只有未判定成功时才会输出 0
(通常由于需要被判定的单位不存在、已被摧毁或还未出生)。
在编辑器中,旗标值为 0
等同于旗标为假。在使用这些函数时,最好同时判定其输出值大于 0
或旗标为真。
指定单位列表
同时判定多个单位的函数,如上面提到的检测触发区内有多少玩家的函数 oms.inZone
,默认会使用一开始定义的所有玩家列表 oms.players
。
如果需要对其他的单位列表进行判定,可以在使用时输入其UNT,区别如下:
1
2
3
4
5
| --判定所有玩家中,有几人在触发区内,并写入旗标inZoneCount
oms.inZone({'Combat Zone'},'inZoneCount')
--只判定uzi-1和uzi-2小队有几人在触发区内,并写入旗标inZoneCount
oms.inZone({'Combat Zone'},'inZoneCount',{'[g]uzi-1','[g]uzi-2'})
|
具体功能
判定触发区内单位数
1
2
3
4
5
6
7
8
9
10
| number = oms.inZone(zoneNames, flag, UNT)
输入值
zoneNames --触发区列表,如{'zone1','zone2'},
--可以是多个触发区的组合,且这些触发区不一定要相连
--即使只有一个触发区,也要写大括号
flag --输出的旗标名,如输出到变量则可不填
UNT --判定的单位列表,如使用全体玩家则可不填
输出值
number --在触发区内的单位数量
|
判定移动触发区内单位数
触发区跟随某单位移动,但不需要在编辑器实际画出触发区,只需要放置其中心的单位即可
1
2
3
4
5
6
7
8
9
10
11
12
13
| number = oms.inMvZone(zoneUnitNames, zoneRadius, zoneType, flag, UNT)
输入值
zoneUnitNames --触发区中心单位列表,如{'arco','shell'},即使只有一个单位,也要写大括号
zoneRadius --触发区半径,已上述各单位为中心,单位米
zoneType --触发区形状,'c'为圆柱体,无限高度,判定2D距离,'s'为球形,即判定3D距离
flag --输出的旗标名,如输出到变量则可不填
UNT --判定的单位列表,如使用全体玩家则可不填
输出值
number --在触发区内的单位数量
--举例 --判断在加油机arco附近1000米内有多少玩家,并写入旗标nearTanker
oms.inMvZone({'arco'}, 1000, 's', 'nearTanker')
|
多个单位中最高高度
高度单位:英尺
输出为实际海拔高度,非离地高度或气压高度
1
2
3
4
5
6
7
8
9
10
11
12
| altitude = oms.maxASL(flag, zoneNames, UNT)
输入值
flag --输出的旗标名,如输出到变量则可不填
zoneNames --触发区列表,用于只在某区域内进行判定,如判定全图可不填
UNT --判定的单位列表,如使用全体玩家则可不填
输出值
altitude --最高单位的高度
--注意 --正常运行时最小输出值为1,如未进行判定(单位不存在)则输出0
举例 --找到在触发区CombatZone内飞得最高的玩家,将其高度写入旗标'altitude'
oms.maxASL('altitude', {'CombatZone'})
|
多个单位中最低高度
高度单位:英尺
输出为实际海拔高度,非离地高度或气压高度
1
2
3
4
5
6
7
8
9
10
| altitude = oms.mimASL(flag, zoneNames, UNT)
输入值
flag --输出的旗标名,如输出到变量则可不填
zoneNames --触发区列表,用于只在某区域内进行判定,如判定全图可不填
UNT --判定的单位列表,如使用全体玩家则可不填
输出值
altitude --最低单位的高度
注意 --正常运行时最小输出值为1,如未进行判定(单位不存在)则输出0
|
在空中的单位数量
只包括已出生且在天上的单位,不包括未出生或已坠毁单位
1
2
3
4
5
6
7
8
| number = oms.inAir(flag, zoneNames, UNT)
输入值
flag --输出的旗标名,如输出到变量则可不填
zoneNames --触发区列表,用于只在某区域内进行判定,如判定全图可不填
UNT --判定的单位列表,如使用全体玩家则可不填
输出值
number --在空中的单位数量
|
在地面的单位数量
只包括已出生且在地面的单位,不包括未出生或已坠毁单位
1
2
3
4
5
6
7
8
| number = oms.onGnd(flag, zoneNames, UNT)
输入值
flag --输出的旗标名,如输出到变量则可不填
zoneNames --触发区列表,用于只在某区域内进行判定,如判定全图可不填
UNT --判定的单位列表,如使用全体玩家则可不填
输出值
number --在地面的单位数量
|
报名系统:固定触发区
当有且只有一个单位进入某区域时,输出其单位名
比如可用于确定所有玩家的长机(如将跑道设置为触发区,第一个上跑道的玩家被定义为长机)
或用于选定某玩家去达成某项挑战等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| name = oms.signUp(zoneNames, flag, UNT)
输入值
zoneNames --触发区列表
flag --输出的旗标名
--旗标值为0 --区域内无单位
--旗标值为1 --单个单位进入区域报名成功
--旗标值为2 --报名失败,区域内单位太多
UNT --判定的单位列表,如使用全体玩家则可不填
输出值
name --成功报名的单位名,注意时编辑器里写的名字,不是玩家名
如超过一个单位会输出'Too Many'
如无单位会输出'No Unit'
--这个名字还会写入全局变量oms.challenger中
|
注意:如果这条代码放在持续运行的触发区中,只有单个单位保持在区域内才会输出其名字,如果之后这个单位离开或过多单位进入,都会导致其名字被替换。如果希望持续记住这个单位的名字,可以使用一个额外的触发器:
触发器 只运行一次
- 条件 旗标值为1
- 动作 执行脚本
1
2
| permName = oms.challenger
--这样即使后来条件变化,该单位的名字也会一直存在permName变量中
|
报名系统:移动触发区
1
2
| name = oms.signUpMv(zoneUnitNames, zoneRadius, zoneType, flag, UNT)
--
|
详见 报名系统:固定触发区
单个单位的海拔高度
高度单位:英尺
输出为实际海拔高度,非离地高度或气压高度
1
2
3
4
5
6
7
8
9
| altitude = oms.unitASL(flag, name)
输入值
flag --输出的旗标名,如输出到变量则可不填
name --单位名(不是玩家名),如不填则为默认报名者oms.challenger
输出值
altitude --当前海拔高度
注意 --正常运行时最小输出值为1,如未进行判定(单位不存在)则输出0
|
单个单位的速度
速度单位:节
输出为3D空间内的绝对速度,非空速
1
2
3
4
5
6
7
8
9
| speed = oms.unitSpeed(flag, name)
输入值
flag --输出的旗标名,如输出到变量则可不填
name --单位名(不是玩家名),如不填则为默认报名者oms.challenger
输出值
speed --当前速度,相对固定地面的3D速度
注意 --正常运行时最小输出值为1,如未进行判定(单位不存在)则输出0
|
单个单位的地速
速度单位:节
输出为相对地面的2D水平速度,非空速
1
2
3
4
5
6
7
8
9
| speed = oms.unitGndSpeed(flag, name)
输入值
flag --输出的旗标名,如输出到变量则可不填
name --单位名(不是玩家名),如不填则为默认报名者oms.challenger
输出值
speed --当前低速,相对固定地面的水平2D速度
注意 --正常运行时最小输出值为1,如未进行判定(单位不存在)则输出0
|
单个单位的爬升率
单位:英尺/分钟
计算所使用的速度和高度均为绝对速度和海拔高度
1
2
3
4
5
6
7
8
9
| rate = oms.unitClimbRate(flag, name)
输入值
flag --输出的旗标名,如输出到变量则可不填
name --单位名(不是玩家名),如不填则为默认报名者oms.challenger
输出值
rate --爬升率
注意 --正常运行时最小输出值为1(即单位在平飞或下降),如未进行判定(单位不存在)则输出0
|
单个单位的下降率
单位:英尺/分钟
计算所使用的速度和高度均为绝对速度和海拔高度
1
2
3
4
5
6
7
8
9
| rate = oms.unitDiveRate(flag, name)
输入值
flag --输出的旗标名,如输出到变量则可不填
name --单位名(不是玩家名),如不填则为默认报名者oms.challenger
输出值
rate --下降率
注意 --正常运行时最小输出值为1(即单位在平飞或爬升),如未进行判定(单位不存在)则输出0
|
单个单位的爬升角度
单位:度
为速度矢量所指向的角度,非机头指向角度
1
2
3
4
5
6
7
8
9
| angle = oms.unitClimbAngle(flag, name)
输入值
flag --输出的旗标名,如输出到变量则可不填
name --单位名(不是玩家名),如不填则为默认报名者oms.challenger
输出值
angle --爬升角度
注意 --正常运行时最小输出值为1(即单位在平飞或俯冲),如未进行判定(单位不存在)则输出0
|
单个单位的俯冲角度
单位:度
为速度矢量所指向的角度,非机头指向角度
1
2
3
4
5
6
7
8
9
| angle = oms.unitDiveAngle(flag, name)
输入值
flag --输出的旗标名,如输出到变量则可不填
name --单位名(不是玩家名),如不填则为默认报名者oms.challenger
输出值
angle --俯冲角度
注意 --正常运行时最小输出值为1(即单位在平飞或爬升),如未进行判定(单位不存在)则输出0
|
单个单位的航向
1
2
3
4
5
6
7
8
9
| heading = oms.unitHeading(flag, name)
输入值
flag --输出的旗标名,如输出到变量则可不填
name --单位名(不是玩家名),如不填则为默认报名者oms.challenger
输出值
heading --当前航向,单位度,可能会与机舱内看到的磁航向有偏差
注意 --正常运行时最小输出值为1,航向正北输出360,如未进行判定(单位不存在)则输出0
|
两个单位的航向差
1
2
3
4
5
6
7
8
9
10
11
| diff = oms.headingDiff(name1, name2, flag)
输入值
flag --输出的旗标名,如输出到变量则可不填,为实际偏差的绝对值
name1 --1号单位名(不是玩家名)
name2 --2号单位名(不是玩家名)
输出值
diff --航向差,单位度。单位2比单位1航向偏右输出正值,偏左输出负值
注意 --正常运行时最小输出值为1,即使航向完全相同,如未进行判定(单位不存在)则输出0
--使用变量输出可看到正负和0,但旗标则只能输出绝对值
|
随机旗标值
限定一个最小值和最大值,在两者之间随机选中一个整数写入旗标值中
如果不写最大最小值,则默认为 1
~ 100
1
2
3
4
5
6
7
8
| num = oms.randFlag(flag, lowerBound, upperBound)
输入值
flag --输出的旗标名,如输出到变量则可不填
lowerBound --随机数最小值
upperBound --随机数最大值
输出值
num --生成的随机数
|
随机时间间隔
时间单位:秒
限定一个最小值和最大值,在两者之间随机选中一个整数作为时间间隔
在此秒数后,将选定的旗标设定为 1
1
2
3
4
5
6
7
8
| dt = oms.randTimer(flag, lowerBound, upperBound)
输入值
flag --在时间间隔达成后,要设定为1的旗标名
lowerBound --随机时间最小值
upperBound --随机时间最大值
输出值
dt --生成的随机时间间隔
|