C:MO编辑器Lua脚本示例教学

这里将介绍一些实用的Lua脚本示例教学。即使是没有接触过Lua的人,也可以自由使用这里的代码并进行改造,从而学习Lua的使用方法!

如果你根本不知道如何使用Lua,请先学习Lua编程入门。

C:MO手册 pp.110-116 “5.3 Lua脚本” 也可以参考

开始

C:MO中,可以使用Lua脚本进行游戏操作。虽然通常玩家不会直接使用它,但如果想使用Scenario Editor创建高级场景,这是必备技能。然而,掌握计算机语言非常困难。因此,本节准备了一些易于使用的Lua脚本实用示例。如果你想详细了解C:MO中的Lua脚本函数,请参考官方的 Command Lua API Documentation, v1502

Lua脚本使用方法

主要使用的地方是Lua脚本 ConsoleSpecial ActionsEvent内的ConditionAction

  • Lua脚本 Console:主菜单 > Editor 的最下方,或快捷键 Ctrl+Shift+C

  • Special Actions:主菜单 > Editor > Event > Special Actions,打开后通过Create New Special Actions创建

  • Event内的Condition和Action:参考这里

Tips

  • DBID是在DB viewer中显示单位时左上角出现的数字。

  • GUID是场景中存在的对象(阵营、单位、任务、事件等)的唯一ID编号,例如:


{name='JASDF Tsuiki Air Base', guid='588456b9-d277-4a6e-9aeb-249cdce5ad0e'}

{name='ROKAF Gimhae Air Base', guid='9f7c59ab-a123-4e56-bc3f-40c61c3300c5'}

{name='ROKAF 8355th Unit (Ullung-do)', guid='801b49bb-96d7-45bd-b085-8fcd5b4a0ced'}

GUID可以通过选择单位,右键 > Scenario Editor > copy unit ID to clipboard 或按 Ctrl+C 键获取。将其粘贴到记事本中即可阅读。

显示单位、任务、事件的属性

显示各单位、任务、事件所拥有的属性。各属性项目的列表可以参考这里。

属性项目的修改

通过 local unit=ScenEdit_GetUnit() 等获取属性后,使用 unit.heading 这样的冒号指定属性项目,并通过 unit.heading=135 进行修改(只读项目不可修改)。使用 ScenEdit_Setxx() 函数也可以得到相同的结果。


ScenEdit_SetUnit({name=unitname, heading=135})

阵营


local name ="阵营名"

local side = VP_GetSide ({side="阵营名"})

print(side)

单位


local side = "阵营名"

local name = "单位的名字"

local unit = ScenEdit_GetUnit({side=side, name=name})

print(unit)

local guid = "单位的guid"

local unit = ScenEdit_GetUnit({guid=guid})

print(unit)

示例如下:


ScenEdit_GetUnit({name="306 TFS #904"})

print(unit)

返回结果:


>> unit {

type = 'Aircraft',

subtype = '2001',

name = '306 TFS #904',

side = 'Japan',

guid = 'b237eecf-302f-449b-9951-818ff49f0af0',

class = 'F-15J Eagle',

proficiency = 'Regular',

latitude = '36.3938888888889',

longitude = '136.407777777778',

altitude = '6',

heading = '0',

speed = '350',

throttle = 'Loiter',

autodetectable = 'False',

base = 'JASDF Komatsu Air Base',

mission = 'JPN CAP',

mounts = '2',

magazines = '2',

unitstate = 'Tasked',

fuelstate = 'None',

weaponstate = 'None',

AllowMultiMission = 'False',

AssignedMissionsQueue = 'table',

}

与单位相同,可以使用 ScenEdit_GetUnit() 函数,但单位返回的是Unit包装器,而组返回的是Group包装器。


local group = "groupname"

return GetUnit ({name=group})

接触


local guid = "接触的guid"

local contact = VP_GetContact({guid=guid})

print(contact)

任务


local side = "阵营名"

local mission = "任务名"

local mission = ScenEdit_GetMission(side,mission)

print(mission)

示例如下:


-- 对空巡逻任务 "JPN CAP" 的信息

local side = "Japan"

local mission = "JPN CAP"

local mission = ScenEdit_GetMission(side,mission)

print(mission)

返回结果:


>>mission {

guid = '0a35715c-b8b7-443f-bf32-003d68a53cc4',

name = 'JPN CAP',

side = 'Japan',

type = 'Patrol',

subtype = 'AAW Patrol',

isactive = 'True',

starttime = '',

endtime = '',

SISH = 'False',

aar = 'table',

unitlist = 'table',

}

在任务信息中,可以在 ScenEdit_GetMission() 之后添加以下字符串,以显示各类型任务的更详细信息:

  • .ferrymission

  • .mineclearmission

  • .minemission

  • .supportmission

  • .patrolmission

  • .strikemission

  • .cargomission

示例如下:


-- 防空巡逻任务 "JPN CAP" 的信息

local side = "Japan"

local mission = "JPN CAP"

local mission = ScenEdit_GetMission (side,mission)

print(mission.patrolmission)

返回结果:


>> { ProsecutionZone = {[1] = { name = 'JADIZ #2' },[2] = { name = 'JADIZ #3' },[3] = { name = 'JADIZ #4' },[4] = { name = 'JADIZ #5' },[5] = { name = 'JADIZ #18' },[6] = { name = 'JADIZ #19' }},

TransitThrottleAircraft = Loiter,

GroupMemberEngageDistance = 5,

StationThrottleShip = Loiter,

BoatsToInvestigate = Group_x1,

UseFlightSize = 'Yes',

StationThrottleAircraft = Loiter,

CheckOPA = 'Yes',

StationThrottleSubmarine = Loiter,

GroupSize = 'Command_Core.Mission+_GroupSize',

FlightsToInvestigate = Flight_x1,

AttackDistanceAircraft = 80,

PatrolZone = {[1] = { name = '0deg @10nm' },[2] = { name = '60deg @10nm' },[3] = { name = '120deg @10nm' },[4] = { name = '180deg @10nm' },[5] = { name = '240deg @10nm' },[6] = { name = '300deg @10nm' }},

AttackTerrainFollowingAircraft = 'No',

FlightSize = 'Command_Core.Mission+_FlightSize',

UseGroupSize = 'No',

LoopType = RandomWithinArea,

WingmanEngageDistance = 5,

OneThirdRule = 'Yes',

TransitTerrainFollowingAircraft = 'No',

OnStation = 0,

ActiveEMCON = 'No',

CheckWWR = 'Yes',

BoatsToEngage = All,

Type = AAW,

TransitThrottleSubmarine = Cruise,

FlightsToEngage = All,

MinAircraftReq = 'NoPreferences',

StationTerrainFollowingAircraft = 'No',

TransitThrottleShip = Cruise }

阵营级别的操作

中立·友方的改变

可以改变阵营的敌友关系。

ScenEdit_SetSidePosture('A', 'B', 'H')

这样,A 和 B 作为Side name(阵营的名字),A 将 B 视为Hostile(敌人)。

(B 的敌友关系在攻击执行之前不会改变)

  • H 表示 Hostile 敌对

  • U 表示 Unfriendry不友好

  • N 表示 Neutral中立

  • F 表示 Friendry友好

可以更改玩家阵营

使用 switchto 选项可以强制切换玩家操作的阵营


local side = side -- 阵营名

ScenEdit_SetSideOptions ({Side=side, switchto=true})

设置雷区 - ScenEdit_AddMinefield() 和 ScenEdit_DeleteMinefield()

ScenEdit_AddMinefield()

ScenEdit_DeleteMinefield()

地雷的DBID(根据种类有最大铺设深度),地雷数量(通常不会全部铺设),启动延迟时间,雷区区域的顶点RP需要设置

  • 2416 - Dummy

  • 2463 - Bottom, Simple 150ft 左右

  • 2462 - Bottom, Advanced

  • 2464 - Bottom, Unsweepable, Shallow-only

  • 2466 - Bottom, Unsweepable

  • 2465 - Bottom, Unsweepable

  • 632 - Bottom Magnetic

  • 2461 - Bottom Total Field Magnetometer Fuze

  • 2582 - Drifting - 似乎不会铺设

  • 634 - Floating

  • 633 - Moored

  • 2581 - Rising

  • 876 - SLMM Mod.1

  • 662 - SLMM Mod.2

  • 2422 - CAPTOR(潜艇专用)

  • 3404 - PMK-2(潜艇专用)

  • 3465 - PMT-1

  • 3398 - EM-52

  • 2086 - Mk62 (Mk82)

  • 2088 - Mk83

  • 2089 - Mk65 (2000lb)


local side= ScenEdit_PlayerSide()

local dbid = 633

local number = 20

local delay = 0

local area = {"Minefield #1", "Minefield #2", "Minefield #3", "Minefield #4"}

ScenEdit_AddMinefield ( {side=side, dbid=dbid, number=number, delay=delay, area=area } )

使用 ScenEdit_DeleteMinefield() 删除指定区域内的地雷


local side= ScenEdit_PlayerSide()

local area = {"Minefield #1", "Minefield #2", "Minefield #3", "Minefield #4"}

ScenEdit_DeleteMinefield({side=side, area=area } )

地图操作

在指定坐标生成基准点


lat='N40.00.00'

lon='W70.40.00'

ScenEdit_AddReferencePoint({side="playerside", lat=lat, lon=lon, locked=true})

以基准点1为基础生成基准点2


local side = ScenEdit_PlayerSide() -- 阵营

local rpname = "RP-4" -- 基准点1

local bearing = 90 -- 基准点1的角度

local distance = 10 -- 基准点1的距离

-- 生成基准点2

local rpfrom =ScenEdit_GetReferencePoint({side=side, name=rpname})

local newrp = World_GetPointFromBearing({latitude=rpfrom.latitude, longitude=rpfrom.longitude, bearing=bearing, distance=distance})

ScenEdit_AddReferencePoint({side=side, latitude=newrp.latitude, longitude=newrp.longitude, highlighted=false, locked=true})

在选定单位的周围生成基准点


local side= ScenEdit_PlayerSide()

local guid = ScenEdit_SelectedUnits().units[1].guid

local unit = ScenEdit_GetUnit({guid=guid})

local circle = World_GetCircleFromPoint({latitude=unit.latitude,longitude=unit.longitude, numpoints=24,radius=150})

for k, v in ipairs(circle) do

ScenEdit_AddReferencePoint({side=side, latitude=v.latitude,longitude=v.longitude, highlighted=true, locked=false})

end

单位级别的操作

单位的设置

生成新单位

要生成新单位,使用ScenEdit_AddUnit()。如果需要进行未预设的增援等操作,可以使用此方法


ScenEdit_AddUnit({type = '单位类型', unitname = '单位名', dbid = DBID, side = '阵营', Lat="纬度",Lon="经度",guid = 'GUID设置'})

  • type 可以是 ‘Facility’, ‘Ship’, ‘Submarine’, ‘Aircraft’ 之一

  • DBID 是在 DB viewer 中显示单位时左上角出现的数字

示例 - 单位类型是 (陆上) 设施,名字是 Kadena AFB,DBID 是 430,阵营是 JSDF,纬度是北纬21度21分12秒(南纬为负,-nn.nn.nn),经度是东经127度45分55秒(西经为负),GUID(场景内单位的ID,用于后续用途)是 Kadena123


ScenEdit_AddUnit({type = 'Facility', unitname = 'Kadena AFB', dbid = 430, side = 'JSDF', Lat="26.21.12",Lon="127.45.55",guid = 'kadena123'})


-- 在 N36.10.50, E140.24.52 处添加名为 "Hyakuri Airbase" 的机场

local side = ScenEdit_PlayerSide()

local name = 'Hyakuri Airbase'

local unittype = 'Facility'

local dbid = 1714

local lat = '36.10.50'

local lon = '140.24.52'

local heading = 45 -- 机场的航向在游戏中不会显示,但会影响着陆机的飞行方向

local unit = ScenEdit_AddUnit({side=side, name=name, type=unittype, dbid=dbid, lat=lat, lon=lon, heading=heading})

更改现有单位的位置

要更改场景中已存在的单位的位置,可以修改Unit表中的latitudelongitude


local guid = '87YZY5-0HMNQ0PA58NEB' -- 单位的 GUID

local unit = ScenEdit_GetUnit({guid=guid})

unit.latitude = "N11.22.33"

unit.longitude ="E11.22.33"

-- 如果想要让预先调整过弹药库或挂载等的单位作为增援登场,可以先将单位放置在地球的另一侧等与场景无关的地方待机,然后使用此方法让单位登场

添加卫星

参考链接:

向基地添加单位

使用ScenEdit_AddUnit()并指定base值,生成的单位将被收纳在指定的基地单位内

ScenEdit_AddUnit()

一机的情况

示例 -


ScenEdit_AddUnit({type = 'Air', unitname = '67th Fighter Squadron', dbid = 4638, side = 'JSDF', base = 'kadena123', LoadoutID = 25580, ignoremagazines = 1})

单位类型是飞机,单位名称是67th Fighter Squadron,DBID是4638,阵营是JSDF,基地的GUID是kadena123,LoadoutID是25580,ignoremagazines为1表示不需要确认基地的武器库存(需要确认则为0)。

  • 单位类型可以是’Facility’, ‘Ship’, ‘Submarine’, 'Aircraft’中的一个。

  • DBID是在DB viewer中显示单位时左上角出现的数字。

  • LoadoutID是在DB viewer中查看飞机时,Aircraft Loadouts栏最右边出现的DB ID#数字。

  • ignoremagazines = 1表示即使该基地没有武器库存,也可以武装。

多机的情况

示例 -


for planes = 1, 12, 1 do

ScenEdit_AddUnit({type = 'Air', unitname = '67th Fighter Squadron #'..planes, dbid = 4638, side = 'JSDF', base = 'kadena123', LoadoutID = 25580, ignoremagazines = 1})

end

for planes = 1, 12, 1 可以添加12架飞机。中间的数字可以更改单位的数量。单位名称的#后面会依次添加从1开始的数字。

在基地中储存武器

即使通过Lua添加了基地,如果没有武器库存,也无法重新武装,因此需要添加武器。


ScenEdit_AddWeaponToUnitMagazine({guid = '基地的GUID', wpn_dbid= DBID, number=数量})

示例 - 基地的Guid是kadena123,武器的DBID是51,添加200个。


ScenEdit_AddWeaponToUnitMagazine({guid = 'kadena123', wpn_dbid= 51, number=200})

GUID在这种情况下是指储存武器的单位的GUID,如果是single unit Airfield,则是基地的GUID,但如果是由多个单位组成的滑行道单位等,则需要指定Ammo Revetment等的GUIDDBID是在DB viewer中显示单位时左上角出现的数字。

可以通过指定LoadoutID来实现“添加30次导弹A 4发和导弹B 2发的装载”(LoadoutID可以在飞机DB viewer的装载列表中查看)。


local unit = 'Cheng Air Base'

local loadoutid = 627

local quantity = 30

ScenEdit_FillMagsForLoadout({unit= unit, loadoutid=loadoutid, quantity=quantity})

单位阵营变更 - ScenEdit_SetUnitSide()

ScenEdit_SetUnitSide()

如果错误地将单位放置在错误的阵营中,重新放置会很麻烦,可以使用这个功能。(如果将战斗机放置在航母上,不仅需要对航母进行操作,还需要对飞机进行操作,请注意。)当然,可以在事件的Action中使用Lua脚本在游戏中再现相同的效果。在更改指挥下的部队时可以使用。

脚本本身如下所示。


ScenEdit_SetUnitSide({side="单位目前所在阵营",name="单位名称",newside="想放入的阵营"})

如果想要将JAPAN阵营的PG 824 Hayabusa更改为JAPAN (JMSDF),则如下所示。


ScenEdit_SetUnitSide({side="JAPAN",name="PG 824 Hayabusa",newside="JAPAN (JMSDF)"})

如果无法正常工作,可以从Rename功能中复制并粘贴阵营名称等,可能会成功。应避免使用双字节字符。

将原阵营的所有单位更改为新阵营

通过VP_GetSide()获得的Side包装器包含阵营的单位列表(units),因此可以对每个单位执行SetUnitSide()


local oldside = "原本的阵营的阵营名称和GUID"

local newside = "新的阵营的阵营名称和GUID"

local side = VP_GetSide ({side = oldside})

for k, v in pairs(side.units) do

ScenEdit_SetUnitSide({side = oldside, guid = v.guid, newside = newside})

end

单位损坏/破坏

损坏 - ScenEdit_SetUnitDamage ()

https://commandlua.github.io/assets/Function_ScenEdit_SetUnitDamage.html

执行单位的强制损坏。可以用于再现自爆等。


ScenEdit_SetUnitDamage({side='阵营名称', unitname='单位名称', fire=(火灾程度),flood=(浸水程度),dp=(damage point),components={{'受损部位','Heavy/Meidium/Small之一'}}})

示例 - 对North Korea的间谍船的发动机室造成重度损坏,火灾2%,浸水3%,并给予5dp伤害点。


ScenEdit_SetUnitDamage({side='North Korea', unitname='Commercial Fishing Boat [35m, Spy Boat]', fires=2,flood=3,dp=5,components={{'Diesels','Heavy'}}})

间谍船有35dp,因此会变成小破程度。Components是仅在需要部位破坏时添加的。

使单位通信中断 - OutOfComms=true/false

通过 ScenEdit_SetUnit()设置OutOfComms=true,无论单位通信设备是否故障,都会强制进入通信中断状态。如果想要恢复通信,则设置OutOfComms=false


local guid = guid

ScenEdit_SetUnit({guid =guid, OutOfComms=true})

ScenEdit_SetUnit({guid =guid, OutOfComms=false})

删除单位/破坏单位 - DeleteUnit()和KillUnit()

  • ScenEdit_DeleteUnit()

  • ScenEdit_KillUnit()

两者最终都会导致单位消失,但处理方式不同。ScenEdit_DeleteUnit()只是删除单位。以单位破坏为触发的事件不会发生。ScenEdit_KillUnit()则是破坏单位。破坏触发事件会发生,并且会计入阵营的损失。


ScenEdit_DeleteUnit({side = "United States", unitname = "USS Abcd" })

ScenEdit_KillUnit({side = "United States", unitname = "USS Abcd" })

单位燃料状态显示/燃料剩余量变更

燃料状态显示

显示由以下燃料类型组成的Fuel表

  • 1001 = NoFuel

  • 2001 = AviationFuel(航空燃料)

  • 3001 = DieselFuel(舰艇柴油燃料)

  • 3002 = OilFuel

  • 3003 = GasFuel

  • 4001 = Battery(潜艇电池剩余量)

  • 4002 = AirIndepedent(潜艇AIP燃料)

  • 5001 = RocketFuel

  • 5002 = TorpedoFuel

-5003 = WeaponCoast


local guid = '87YZY5-0HMNQ0PA58NEB' --单位的GUID

local unit = ScenEdit_GetUnit({guid=guid})

print(unit.fuel)

燃料剩余量变更

参考:

  • Starting Diesel Submarine/Ship Fuel Level

  • RE: Script To Generate Random Merchant Location + Traffic

通过ScenEdit_SetUnit设置fuel = { {燃料ID, 数値} }可以更改燃料剩余量(这里将3001=柴油燃料的剩余量更改为9000)。注意fuel值的括号和燃料类型各自的括号需要双重。


local guid = '8558e224-d1e3-4040-a087-9283267b1d1c' --单位的GUID

ScenEdit_SetUnit({guid=guid, fuel= { {3001, 9000} } })

max值=如果想要按最大容量的比例更改,数值必须是整数(有小数点会报错),所以使用math.floor()。


local guid = '8558e224-d1e3-4040-a087-9283267b1d1c' --单位的GUID

local unit = ScenEdit_GetUnit({guid=guid})

ScenEdit_SetUnit({guid=guid, fuel= { {3001, math.floor(0.5+unit.fuel[3001].max*0.7)} } })

为单位创建航点

为单位添加航点


ScenEdit_SetUnit({guid='单位的GUID',course={{latitude='纬度', longitude='经度'}}, manualAltitude = '高度'})

示例-

GUIDsubmarine1,纬度为北纬17.0565979083558,经度为西经-89.2178220232281,高度0(如果是潜艇则=上浮)的航点创建。


ScenEdit_SetUnit({guid='submarine1',course={{latitude='17.0565979083558', longitude='-89.2178220232281'}}, manualAltitude = '0'})

如果需要多个航点,首先定义一个空的course表,然后使用table.insert逐步添加航点表


local unit = EcenEdit_GetUnit({guid=GUID})

local course = {}

table.insert (course, {TypeOf = 'ManualPlottedCourseWaypoint', latitude=wp1.latitude, longitude= wp1.longitude, presetAltitude=6, presetThrottle=2})

table.insert (course, {TypeOf = 'ManualPlottedCourseWaypoint', latitude=wp2.latitude, longitude= wp2.longitude, presetAltitude=6, presetThrottle=2})

table.insert (course, {TypeOf = 'LandingMarshal', latitude=wp3.latitude, longitude= wp3.longitude, presetAltitude=6, presetThrottle=2})

unit.course=course

删除单位的航点


local guid = '87YZY5-0HMNOB5T4SJ1U'

ScenEdit_SetUnit({guid=guid, course= {} })

使单位加入任务


ScenEdit_AssignUnitToMission("单位名称或GUID", "任务名称")

为任务添加目标

Strike Mission添加目标。


ScenEdit_AssignUnitToMission('目标名称或GUID', '任务名称')

GUID为「a1d75aac-d6b1-4e35-8ce4-34969f115cd3」的目标添加到名为killer 552的任务中


ScenEdit_AssignUnitToMission('a1d75aac-d6b1-4e35-8ce4-34969f115cd3', 'killer 552')

显示单位的Bark

C:MO v1.05开始,可以在单位旁边显示称为Bark的文本。


local unit = "东方号" --要显示Bark的单位名称

local text = "发现敌方潜艇!" --Bark的内容

local R = 255 --文本颜色的红色成分 (0-255)

local B = 255 --文本颜色的蓝色成分 (0-255)

local G = 127 --文本颜色的绿色成分 (0-255)

local moveUpward = true --如果为false,文本不会上浮

local fade = true --如果为false,文本不会淡出

local lifeTime = 5 --文本的显示秒数

local fontSize = 30 --文本字体的大小

ScenEdit_CreateBarkNotification_Unit(unit, text, R, B, G,moveUpward,fade,lifeTime,fontSize)

将单位GUID转换为接触GUID

单位的GUID和接触GUID不同,因此需要进行转换。将value.guid改为value.name即可,转换为接触名称(例如: SKUNK #53)并返回。

如果没有探测到,则不返回任何内容,因此可以与Target Is Detected等触发器结合使用。


function getContactGUID(detecterside_guid, originalunitguid)

local unitA = ScenEdit_GetUnit({guid=originalunitguid})

for key, value in pairs(unitA.ascontact)do

if value.side == detecterside_guid

then return value.guid

else return "none"

end

end

end

示例

在上面的function之后


local A1 = getContactGUID("NNQBOL-0HMLCELCRRE66","dd153-yugiri")

print(A1)

从接触GUID转换为单位GUID

这非常简单


local contact = VP_GetContact({guid=contactguid})

return contact.actualunitid

为指定单位添加挂载

例如,为指定单位添加卡里布导弹发射器(DBID=2914)(4个挂载=16发)


local guid= '87YZY5-0HMNQ0PA3EA88' --目标单位的GUID

local dbid = 2914

local arc_mount = {"SMF2", "SMF1", "SMA2", "SMA1", "PMF2", "PMF1", "PMA2", "PMA1"}

for i = 1, 4 do

ScenEdit_UpdateUnit({guid=guid, mode="add_mount", dbid=dbid, arc_mount=arc_mount})

i = i+1

end

使单位爆炸

  • ScenEdit_AddExplosion( table )

使用ScenEdit_AddExplosion()可以在任意地点引发爆炸

使用ScenEdit_GetUnit()获取单位的坐标,然后指定爆炸弹头的DBID(在DB Viewer中查找Weapon条目)。顺便使用ScenEdit_PlaySound()播放爆炸音效


--[[弹头DBID的例子 (CWDB/DB3K)

-210 = 250lb Mk81

-549/288 = 500lb Mk82

-302 = 1000lb Mk83

-521/299 = 2000lb Mk84

-1033 = 1kT nuclear]]

local guid = "87YZY5-0HMFCCN38FA5J" --单位的GUID(或者指定单位名称)

local warheadid = 157 --爆炸弹头的DBID

---

local target = ScenEdit_GetUnit({guid=guid})

ScenEdit_AddExplosion({warheadid=warheadid, latitude=target.latitude, longitude=target.longitude, alitude=target.altitude})

ScenEdit_PlaySound("Impact_directhit_large.mp3")

组操作

也可参考

创建组·将单位编入组


local unit1 = ScenEdit_GetUnit({name='unit1name', guid="unit1guid"})

local unit2 = ScenEdit_GetUnit({name='unit2name', guid="unit2guid"})

local group = "groupname" --要将单位编入的组名(如果没有则新建)

unit1.group = group

unit2.group = group

将指定单位设为组领导


local unit1 = ScenEdit_GetUnit({name='unit1name', guid="unit1guid"})

local group = ScenEdit_GetUnit({name='groupname', guid="groupguid"})

group.group.lead = unit1.guid

更改组成员位置


local unit1 = ScenEdit_GetUnit({name='unit1name', guid="unit1guid"}) --组领导

local unit2 = ScenEdit_GetUnit({name='unit2name', guid="unit2guid"}) --组成员

--bearing是组领导视角下组成员的方位

--值必须在0-360之间(其他数值会导致成员位置设置不正确)

bearing2=unit1.heading+120 --bearing2=unit1的航向+120度

指定单位从组中移除

C:MO中,如果舰艇组中的一艘船失去行动能力,整个组可能会因此减速,甚至在某些情况下停止。如果你想创建一个新组并将其编入,需要指定组名。


ScenEdit_SetUnit({side="阵营", guid ="单位GUID", group = "任意名称"})

示例如下:


ScenEdit_SetUnit({side="Red", unitname="DD 154 Amagiri", group = "unitv"})

如果只是想从组中移除,可以指定group="none"


local unit1 = ScenEdit_GetUnit({guid=unit1guid})

unit1.group="none"

事件等操作

激活/停用事件

可以用在EventCondition中,替代手动在Lua中编写。有时这样可能更方便。将true改为false可以停止事件。


ScenEdit_SetEvent('事件名', {Isactive='true'})

激活/停用Special Action


ScenEdit_SetSpecialAction({ActionNameOrID='Special Action的名称或ID',Isactive=true})

true改为false可以停用。

显示游戏内的UNIX时间

这可以在Lua控制台中使用。


TimeA = ScenEdit_CurrentTime()

print(TimeA)

在指定时间返回boolean值

这可以在Event内的Condition中使用。


TimeA = ScenEdit_CurrentTime()

if (TimeA == 时间) then

return true

else

return false

end

时间使用UNIX时间。转换网站见此:https://tool.chinaz.com/tools/unixtime.aspx。

事件启动后指定时间后触发另一个事件

这可以在事件的Lua action中使用。

策略是:

(1) 首先获取当前时间并加上指定时间。

(2) 获取的时间是UNIX时间,需要转换为触发器可读的普通格式。

(3) 为了调试,使用print()输出。

(4) 创建触发器。然后创建事件并添加触发器和动作。

  • 创建示例触发器

local timeEVENT1_unix = ScenEdit_CurrentTime() + 20; -- 首先获取当前时间,然后在此基础上加上20秒

timeEVENT1_string = os.date("%Y/%b/%d %H:%M:%S", timeEVENT1_unix) -- 现在得到的变量是unix时间,所以需要转换为字符串类型

print(timeEVENT1_string) -- 调试目的,检查EVENT1_string的时间是否正确

ScenEdit_SetTrigger({Description = "trigger1", Mode = "add", name = "Trigger1", type = "Time", Time = timeEVENT1_string}) -- 根据EVENT1_string的时间创建名为trigger1的触发器

最后一行,ScenEdit_SetTriggerDescription = "trigger1" 可以使用name代替Description,应该没有问题。

  • 创建事件

ScenEdit_SetEvent("event1", {Description = "Event1", Mode = "add"}) -- 创建名为event1的事件

ScenEdit_SetEventTrigger("event1", {mode = "add", name = "trigger1"}) -- 为event1添加名为trigger1(上述创建)的触发器

ScenEdit_SetEventAction('event1', {mode = 'add', name = "msg:temp"})

ScenEdit_SetEvent中的 Description = "Event1" 部分仅在需要区分显示(description)和实际名称(name)时使用。可能不常用。

关于行动(Action),可以像平常一样在编辑器中预先创建,然后在这里添加。

关于行动,可以在同一个事件中用lua创建,但我认为预先创建会使得代码更简洁。

综上所述,总结如下:


local timeEVENT1_unix = ScenEdit_CurrentTime() +20; -- 获取当前时间,加上20秒

timeEVENT1_string = os.date("%Y/%b/%d %H:%M:%S",timeEVENT1_unix) -- 将UNIX时间转换为字符串格式

print(timeEVENT1_string) -- 调试目的,检查时间字符串

ScenEdit_SetTrigger ({Description = "trigger1", Mode = "add", name = "Trigger1", type = "Time", Time = timeEVENT1_string}) -- 基于timeEvent1创建时间触发器

ScenEdit_SetEvent ("event1", {Description = "Event1", Mode = "add"}) -- 创建名为"event1"的事件,显示为"Event1"

ScenEdit_SetEventTrigger ("event1",{mode = "add", name = "trigger1"}) -- 将Trigger1添加到"event1"

ScenEdit_SetEventAction('event1', {mode='add', name = "msg:temp"}) -- 将msg:temp动作添加到"event1"

  • 用途

用途包括在玩家行动后产生时间延迟。例如,玩家请求空中加油机支援后一小时,友方阵营出动;或玩家开始越境攻击后三小时,核弹头导弹发射。

如果需要随机时间,可以通过设置两个时间变量来实现类似效果。

播放音效(如“解放!”)

准备工作:获取音源,文件名改为适当名称(如"jiefang.mp3")。将"jiefang.mp3"移动到"C:MO游戏文件/Sound/Effects/"。如果音效文件在"voices"文件夹中,需指定路径。


ScenEdit_PlaySound("jiefang.mp3")


ScenEdit_PlaySound("voices/jiefang.mp3")

这可以在事件发生时播放任意音效(如“发现敌方潜艇!”)。

显示带选项的消息对话框

使用UI_CallAdvancedDialog()可以显示带选项的消息对话框。


UI_CallAdvancedDialog ( title, description, interactions )

示例如下:


local title = "冬季战争"

local description = [[ 1939年8月,德国和苏联签订了互不侵犯条约,战争的矛头转向芬兰。\n这是所有的秘密协定。然而,随着时间的推移,这些密约逐渐为芬兰政府所知。在苏联与芬兰之间的军事紧张局势加剧的情况下,当芬兰向德国寻求援助时,德国却表现出不回应的态度。如果与苏联发生战争,芬兰将不得不独自面对大国。在这样的情况下,苏联要求在芬兰领土内建设军事基地的许可。然而,芬兰拒绝了这一要求。于是,1939年11月30日,苏联废除了1932年签订的互不侵犯条约,开始入侵芬兰。\n由此开始的“冬季战争”于1940年3月13日以莫斯科和平条约的签署而结束,芬兰被迫将东南部割让给苏联。]]

local interactions = {"来吧!犯我国土者,虽远必诛!","为了后代的和平,接受这个结果!"}

local decision = UI_CallAdvancedDialog (title, description, interactions)

print(decision)

(全文完)

3 个赞

CMO编辑器Lua脚本示例.pdf (612.1 KB)

您好,我在设置Time类型触发器时,遇到了一个很神奇的问题,事件总在脚本执行后立即自动触发了,哪怕没有到达设定的时间,我看CMO官方论坛中也有人遇到过类似问题(How to set a timer - Matrix Games Forums),但我看原帖也没有讨论出明确的解决方法,因此想请教一下您,谢谢!!