Starbound mod 武器制作教程(一)

本教程将通过一把近战武器来了解武器文件和脚本的方方面面,很多地方由于wiki上都没有注释,只能靠我猜了,因为如果有建议请评论提出。

以维奥大剑作为开始,我们来了解一下武器的文件结构。没用过的可以去游戏里用一下了解下这把武器。

首先武器是一种item,而且是activeitem,因为武器是可以拿在手上互动的。我们从items/active/weapons/protectorate/broadsword/violiumbroadsword/violiumbroadsword.activeitem打开这个文件,这个acitveitem文件定义了violiumbroadsword的基本属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
{
"itemName" : "violiumbroadsword",
"price" : 960,
"level" : 6,
"maxStack" : 1,
"rarity" : "Legendary",
"description" : "This hardened violium hilt houses the projector for a wicked energy blade.",
"shortdescription" : "Violium Broadsword",
"tooltipKind" : "sword",
"category" : "broadsword",
"twoHanded" : true,
"itemTags" : ["weapon", "melee", "broadsword"],

"inventoryIcon" : "violiumbroadswordicon.png",

"animation" : "/items/active/weapons/melee/broadsword/energybroadsword.animation",
"animationParts" : {
"handle" : "handle.png",
"handleFullbright" : "handlefullbright.png",
"blade" : "blade.png"
},
"animationCustom" : {
"sounds" : {
"fire" : [ "/sfx/melee/laser_weapon_swing1.ogg", "/sfx/melee/laser_weapon_swing2.ogg", "/sfx/melee/laser_weapon_swing3.ogg" ],
"fire2" : [ "/sfx/melee/laser_weapon_swing1.ogg", "/sfx/melee/laser_weapon_swing2.ogg", "/sfx/melee/laser_weapon_swing3.ogg" ],
"fire3" : [ "/sfx/melee/laser_weapon_swing1.ogg", "/sfx/melee/laser_weapon_swing2.ogg", "/sfx/melee/laser_weapon_swing3.ogg" ]
}
},

"scripts" : ["/items/active/weapons/melee/energymeleeweapon.lua"],

"activeTime" : 3.0,

"elementalType" : "physical",

"primaryAbilityType" : "broadswordcombo",
"primaryAbility" : {
"fireTime" : 0.83,
"baseDps" : 11.5,

"stances" : {
"windup1" : {
"duration" : 0.15
}
}
},

"altAbilityType" : "flipslash",

"builder" : "/items/buildscripts/buildunrandweapon.lua"
}

前面一堆都很好理解,我们看下这几个
animation :定义了武器使用的animation文件,一会我们再看。
animationCustom 因为上面用的不一定是仅针对该武器的动画配置,可能是通用动画配置,因此在这里进行了一些修改或补充。
scripts 用了 energymeleeweapon.lua 作为武器的脚本,一会看。
activeTime 应该是激活时间,可以看到维奥剑经过一段时间光刃就会收回。
primaryAbilityType 主功能,即左键启动的武器能力,这里使用了 broadswordcombo ,即大剑连斩,这个ability的文件储存在items\active\weapons\melee\abilities\broadsword\broadswordcombo.weaponability里面。
primaryAbility 对上面引用的weaponability的内容进行补全,以适配特定武器,也就是说broadswordcombo.weaponability和这一条里面的内容合在一起就是该武器使用的主功能配置。
altAbilityType 右键启动的功能,这里没有对应的altAbility作补充,应该是因为 flipslash 的文件里面写得很全了。
builder 大概是spawnitem用的?

先看animation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
{
"globalTagDefaults" : {
"paletteSwaps" : ""
},

"animatedParts" : {
"stateTypes" : {
"swoosh" : {
"default" : "idle",
"states" : {
"idle" : {},
"fire" : {
"frames" : 3,
"cycle" : 0.1,
"mode" : "transition",
"transition" : "idle"
},
"fire2" : {
"frames" : 3,
"cycle" : 0.1,
"mode" : "transition",
"transition" : "idle"
},
"fire3" : {
"frames" : 3,
"cycle" : 0.1,
"mode" : "transition",
"transition" : "idle"
}
}
},
"blade" : {
"default" : "inactive",
"states" : {
"inactive" : {
"properties" : {
"lightsOff" : ["glow"],
"particleEmittersOff" : ["blade"]
}
},
"extend" : {
"frames" : 5,
"cycle" : 0.15,
"mode" : "transition",
"transition" : "active",
"properties" : {
"lightsOn" : ["glow"],
"particleEmittersOn" : ["blade"],
"immediateSound" : "/sfx/tools/energypickaxe_start.ogg"
}
},
"active" : {
"frames" : 9,
"cycle" : 0.5,
"mode" : "loop",
"properties" : {
"lightsOn" : ["glow"],
"particleEmittersOn" : ["blade"],
"persistentSound" : "/sfx/tools/energypickaxe_idle.ogg"
}
},
"retract" : {
"frames" : 5,
"cycle" : 0.15,
"mode" : "transition",
"transition" : "inactive",
"properties" : {
"lightsOn" : ["glow"],
"particleEmittersOn" : ["blade"],
"immediateSound" : "/sfx/tools/energypickaxe_stop2.ogg"
}
}
}
}
},

"parts" : {
"blade" : {
"properties" : {
"zLevel" : 0,
"centered" : true,
"fullbright" : true,
"offset" : [0, 1.875],
"transformationGroups" : ["weapon"],
"rotationCenter" : [0, 0],
"damageArea" : [[-0.7, -1.0], [-0.7, 2.5], [0.5, 2.5], [0.5, -1.0]]
},

"partStates" : {
"blade" : {
"inactive" : {
"properties" : {
"image" : ""
}
},
"extend" : {
"properties" : {
"image" : "<partImage>:extend.<frame>?<directives>?<bladeDirectives>"
}
},
"active" : {
"properties" : {
"image" : "<partImage>:active.<frame>?<directives>?<bladeDirectives>"
}
},
"retract" : {
"properties" : {
"image" : "<partImage>:retract.<frame>?<directives>?<bladeDirectives>"
}
}
}
}
},
"handle" : {
"properties" : {
"zLevel" : 1,
"centered" : true,
"image" : "<partImage><paletteSwaps>?<directives>",
"offset" : [0, 1.875],
"transformationGroups" : ["weapon"],
"rotationCenter" : [0, 0]
}
},
"handleFullbright" : {
"properties" : {
"zLevel" : 2,
"centered" : true,
"fullbright" : true,
"image" : "<partImage><paletteSwaps>?<directives>",
"offset" : [0, 1.875],
"transformationGroups" : ["weapon"],
"rotationCenter" : [0, 0]
}
},
"swoosh" : {
"properties" : {
"zLevel" : -1,
"centered" : true,
"fullbright" : true,
"transformationGroups" : ["swoosh"],
"rotationCenter" : [0, 0]
},

"partStates" : {
"swoosh" : {
"idle" : {
"properties" : {
"image" : ""
}
},
"fire" : {
"properties" : {
"image" : "/items/active/weapons/melee/broadsword/swoosh/energyswoosh.png:<frame>",
"offset" : [0, 2.5],
"damageArea" : [[-5, 2], [-2.5, 3], [1, 3], [4, 1.75], [5, -0.25], [5, -2.25], [4, -3.25], [0, -2.5]]
}
},
"fire2" : {
"properties" : {
"image" : "/items/active/weapons/melee/broadsword/swoosh2/energyswoosh.png:<frame>",
"offset" : [5.0, 1.0],
"damageArea" : [[-4, 1], [2.5, 1], [2.5, -2], [-4, -2]]
}
},
"fire3" : {
"properties" : {
"image" : "/items/active/weapons/melee/broadsword/swoosh3/energyswoosh.png:<frame>",
"offset" : [3.5, 0],
"damageArea" : [[-4.75, 1.5], [3, 1], [3, -1], [-4.75, -1.5]]
}
}
}
}
}
}
},

"transformationGroups" : {
"weapon" : {},
"swoosh" : {}
},

"particleEmitters" : {
"physicalswoosh" : {
"active" : false,
"transformationGroups" : ["swoosh"],
"burstCount" : 4,
"particles" : [
{ "particle" : "energyblade"},
{ "particle" : "energyblade2"}
]
},
"blade" : {
"active" : false,
"transformationGroups" : ["weapon"],
"offsetRegion" : [-0.5, 1.5, 0.5, 4.0],
"emissionRate" : 5,
"particles" : [
{ "particle" : "energyblade"},
{ "particle" : "energyblade2"}
]
}
},

"lights" : {
"glow" : {
"position" : [0, 2.0],
"color" : [90, 50, 120],
"transformationGroups" : ["weapon"]
}
},

"sounds" : {
"fire" : [],
"fire2" : [],
"fire3" : []
}
}

建议配合animatior的md文件或者wiki解释去理解,这里的很多东西都是为lua脚本服务的。

globalTagDefaults :脚本要用的东西,参照Wiki解释,
A global tag replaces any tag with the specified tagValue across all animation parts. 要是不懂没事,一会会看到脚本的用法。

stateTypes 状态的分类名称,其下定义了多个state,具体用法参照animator.setAnimationState这个函数。
可以看到,statetypes有: swoosh blade 两种

再来看下state里面的东西,
frame:即几帧图像,这个要配合相应的图片文件使用,虽然我还不知道在哪)
cycle :一次动画循环的时间
mode :wiki有解释, 配合后面的transition,指播放完毕后转入某个状态。
lightsOff [“glow”] glow在最下面被定义了,是个light,显而易见。
particleEmittersOff 同上,定义也在下面,不过这个是粒子发射器。
immediateSound persistentSound 顾名思义

stateTypes 看完了,接下来是 parts ,有四个parts,单个part里面各不相同,不过都有 properties 。
properties 内部有如下几种值:
zLevel z轴也就是深度的顺序。
centered 不懂,居中?
fullbright :无论白天夜晚都会亮
offset 应该是指位置
transformationGroups 移动的组,animator里一些函数是对一整个组进行操作的。
rotationCenter 旋转中心,顾名思义。
damageArea 可以造成伤害的区域,顾名思义。

然后blade下面有个 partStates ,可以看到里面定义了四个state, inactive extend active retract ,对应这个剑刃伸出收回的四个阶段。
不过每个states里面也就只定义了一个image,也就是说对于这个blade的part,不同状态只会修改image这个属性,其他属性则不变。
不过这个image,包括下面其他part的image,都是这种格式的: “:extend.??
尖括号,就是tag,代表其名称对应的值,partimage对应了activeitem里的part指定的文件及其frame文件,这里的extend.即blade.frames里的值,就是当前帧数。在播放动画的时候,frame会逐渐累加,直到到达frame最大值,这个最大值刚才在上面看到,也定义了。
至于问号和问号后面的内容,应该是一些其他tag,但是由于我也不知道问号的用法,所以暂时不能理解,不过这些tag我们之后应该可以在其他地方看到。

animation的解读到此为止,其他的下一篇继续。
有什么不懂的就去下面评论。