-
Notifications
You must be signed in to change notification settings - Fork 31
地图脚本制作指南
一个地图脚本文件的入口函数是WorldLoaded
, 你可以在这个函数里面加入一些初始化代码,比如获取玩家,添加任务目标等等
你可以使用如下代码定义这个入口函数:
WorldLoaded = function()
.....
end
任务目标就是玩家需要在这个任务完成的一些目标,有些任务目标失败不会影响游戏进程,但是有些任务目标失败将会导致游戏结束, 如果你想要创建一个任务目标的话,你可以使用下面的代码:
player = Player.GetPlayer("PLAYER NAME")
player.AddPrimaryObjective("Description String") -[[添加一个主要任务目标]]
player.AddSecondaryObjective("Description String") -[[添加一个次要任务目标]]
一个任务目标有三个触发器, OnObjectiveAdded, OnObjectiveCompleted和OnObjectiveFailed
当 AddPrimaryObjective
或者AddSecondaryObjective
被调用的时候OnObjectiveAdded
会被触发
当调用MarkCompletedObjective
的时候OnObjectiveCompleted
会被触发
当调用MarkFailedObjective
的时候OnObjectiveFailed
会被触发
像这样:
ObjectiveObject = player.AddPrimaryObjective("blah")
player.MarkCompletedObjective(ObjectiveObject)
player.MarkFailedObjective(ObjectiveObject)
Trigger.OnObjectiveAdded = function(player, function(p, objectiveID))
--[[ 你可以使用 p.GetObjectiveDescription(objectiveID) 方法去获取任务目标的描述 ]]
end
Trigger.OnObjectiveCompleted = function(player, function(p, objectiveID))
--[[ 你可以使用 p.GetObjectiveDescription(objectiveID) 方法去获取任务目标的描述 ]]
end
Trigger.OnObjectiveFailed = function(player, function(p, objectiveID))
--[[ 你可以使用 p.GetObjectiveDescription(objectiveID) 方法去获取任务目标的描述 ]]
end
当任意主要任务目标失败, OnPlayerLost
触发器将会被触发, 相反地,当所有主要任务目标完成的时候, OnPlayerWon
将会被触发
你可以自己挂钩这两个触发器
Trigger.OnPlayerLost = (player, LostFunction)
Trigger.OnPlayerWon = (player, WonFunction)
所有在map.yaml
定义的Actor都可以在地图脚本文件中被引用, 比方说, 我们有一个像这样的map.yaml
文件:
MapFormat: 11
RequiresMod: example
Title: Placeholder
Author: BlahBlahBlah
Tileset: TILESET
MapSize: 100,200
Bounds: 2,5,96,188
Visibility: Lobby
Categories: Conquest
Players:
PlayerReference@Neutral:
Name: Neutral
OwnsWorld: True
NonCombatant: True
Faction: Random
PlayerReference@Creeps:
Name: Creeps
NonCombatant: True
Faction: Random
Actors:
Actor0: ACTOR_TYPE
Location: 95,3
Owner: Neutral
Actor1: ACTOR_TYPE
Location: 114,26
Owner: Neutral
如果我们想要在脚本文件中引用Actor0
以检测其是否死亡,我们可以这样做:
if Actor0.IsDead then
.....
end
我们可以直接使用在map.yaml
定义的Actor的ID在地图脚本文件中使用, 并且可以访问这个Actor的所有属性.
因此,你最好把在map.yaml
定义的Actor的ID修改得可读性强一些.
在脚本文件中Tick方法将会被引擎调用当引擎要更新游戏的时候,因此这意味着我们可以将一些我们需要持续调用的方法放在Tick方法里面,比如检测Actor状态,或者循环发送部队。
一个tick
方法像如下这样:
Tick = function()
......
end
map.yaml
文件在OpenRA地图系统中很重要, 你不仅可以在这个文件中定义基本信息,比如作者,名称等等. 你还可以定义这个地图中存在的玩家已经Actor
尤其是, 你可以在这个文件重写规则文件和武器文件(就像在红警地图编辑器里面一样).
地图基本信息包含地图文件所有信息:
MapFormat
- 地图YAML文件格式, 通常是11
RequiresMod
- 这个地图适用的模组
Title
- 在地图浏览器里面显示的名称
Author
- 在地图浏览器里面显示的作者
Tileset
- 地图使用的地形
MapSize
- 地图大小
Bounds
- 地图边界
Visibility
- 决定地图显示的位置,可用的取值: Lobby
, Shellmap
和MissionSelector
-
Lobby
- 地图将会在地图浏览器里面显示 -
Shellmap
- 地图将作为一个启动的地图 -
MissionSelector
- 地图将会显示在任务列表里面
Categories
- 分组, 可以填写任意值
玩家在地图中的作用很重要,在地图中发生的所有游戏事件都是发生在这些玩家之间,一个玩家可以是由人操作的,也可以由AI控制的。一个玩家不意味着一个阵营,实际上,两个玩家,都可以是同一个阵营。
PlayerReference@Greece:
Name: Greece
Playable: True
AllowBots: False
Required: True
LockFaction: True
Faction: allies
LockColor: True
Color: ABB7E4
LockSpawn: True
LockTeam: True
Allies: England
Enemies: USSR
PlayerReference@Greece
- 这告诉引擎,我们将要开始一个玩家定义块,其ID是Greece
Name: Greece
- 玩家的名称是Greece
Playable: True
和AllowBots: False
- 告诉引擎这是由人操作的玩家
Required: True
- 这意味着这个游戏位置必须被赋予,否则的话将无法开始游戏
LockFaction: True
- 其阵营将会被锁定
Faction: allies
- 这个玩家所使用的阵营是allies
LockColor: True
- 这个玩家使用的颜色不能被改变
Color: ABB7E4
- 如果LockColor
是True
, 那你必须指定一个颜色
LockSpawn: True
- 系统将锁定其刷出点
LockTeam: True
- 其队伍不会变更
Allies
- 这个玩家不会被Allies
所定义的玩家所攻击,比方说,现在,这个Allies
定义了England
,那么这个玩家就不会被名为England
的玩家所攻击
Enemies
- 这个玩家将会被Enemies
所定义的玩家攻击, 比方说, 现在,这个Enemies
定义了USSR
, 那么这个玩家将会被名为USSR
的玩家所攻击
一旦你在map.yaml
定义好了玩家, 之后你就可以在脚本中使用以下代码引用这个玩家:
player = Player.GetPlayer("PLAYERNAME")
对于我们之前分析那个玩家,我们可以通过如下的代码引用:
greece = Player.GetPlayer("Greece")
所有的Actor定义信息要在Actors:
节点下定义
ACTORID: ACTOR_TYPE
Location: 0, 0
Facing: 100
Owner: PLAYERNAME
ACTORID
- Actor的ID,你可以在脚本文件直接使用这个id
ACTOR_TYPE
- 你在规则文件中所定义的actor的类型
Location
- Actor在地图中的位置
Facing
- Actor在地图中的朝向
Owner
- Actor的拥有者,需要玩家的名称
如果你需要在这个地图中做一些限制,比如单位限制,科技限制,甚至建筑限制,亦或者你想在本地图中让我方或者敌方生产一些特定的单位,你可以使用规则重写定义块,这个块可以覆盖规则文件中的定义
所有规则重写必须位于Rules:
节点之下,定义方式与规则文件里面定义的方法一致
ACTORTYPE:
Trait List....
或者你可以使用一个外部的地图规则文件,比如下面的代码:
Rules: map-rules.yaml
它会在与map.yaml
相同目录下找到这个文件
有些时候我们需要对武器进行一些修改, 但是又不想影响到其他地图正常使用,我们可以在map.yaml
中使用武器重写定义块
武器重写定义块里面的内容和通常的武器定义没有任何区别
同样地,武器重写定义块也可以使用外部文件定义的方式,比如下面的代码
Weapons: map-weapons.yaml
它会在与map.yaml
相同目录下找到这个文件
variable = 1
if 条件表达式 then
....
end
while 条件表达式 do
.....
end
或者
for x in arr do
....
end
或者使用OpenRA版本
Utils.Do(arr, function(element)
....
end)
--[[这是一个单行注释]]
--[[
这些是多行注释
--]]
arr = {"element1", "element2", "element3"}
tb = {}
tb["key"]="value"
element = arr[index]
函数名称 = function(函数参数)
....
end
函数名称(函数参数)
return
OpenRA Lua API: https://github.com/OpenRA/OpenRA/wiki/Lua-API