欢迎回来,这里是几百年更新不到一次的旋风
本讲我们以栓动步枪、电荷步枪为例,讲述基础的远程武器如何创作。
栓动步枪的defName为Gun_BoltActionRifle,文件位于Core\ThingDefs_Misc\Weapons\RangedIndustrial.xml,line527开始。
<ThingDef ParentName="BaseHumanMakeableGun">
<defName>Gun_BoltActionRifle</defName>
<label>bolt-action rifle</label>
<description>An ancient pattern bolt-action rifle. With its long range, and low fire rate, it is unlikely to drive animals to revenge, which makes it a favorite weapon for hunting.</description>
<graphicData>
<texPath>Things/Item/Equipment/WeaponRanged/BoltActionRifle</texPath>
<graphicClass>Graphic_Single</graphicClass>
</graphicData>
<soundInteract>Interact_Rifle</soundInteract>
<weaponClasses>
<li>LongShots</li>
</weaponClasses>
<statBases>
<WorkToMake>12000</WorkToMake>
<Mass>3.5</Mass>
<AccuracyTouch>0.65</AccuracyTouch>
<AccuracyShort>0.80</AccuracyShort>
<AccuracyMedium>0.90</AccuracyMedium>
<AccuracyLong>0.80</AccuracyLong>
<RangedWeapon_Cooldown>1.5</RangedWeapon_Cooldown>
</statBases>
<costList>
<Steel>60</Steel>
<ComponentIndustrial>3</ComponentIndustrial>
</costList>
<recipeMaker>
<skillRequirements>
<Crafting>5</Crafting>
</skillRequirements>
<displayPriority>415</displayPriority>
</recipeMaker>
<verbs>
<li>
<verbClass>Verb_Shoot</verbClass>
<hasStandardCommand>true</hasStandardCommand>
<defaultProjectile>Bullet_BoltActionRifle</defaultProjectile>
<warmupTime>1.7</warmupTime>
<range>36.9</range>
<soundCast>Shot_BoltActionRifle</soundCast>
<soundCastTail>GunTail_Heavy</soundCastTail>
<muzzleFlashScale>9</muzzleFlashScale>
</li>
</verbs>
<tools>
<li>
<label>stock</label>
<capacities>
<li>Blunt</li>
</capacities>
<power>9</power>
<cooldownTime>2</cooldownTime>
</li>
<li>
<label>barrel</label>
<capacities>
<li>Blunt</li>
<li>Poke</li>
</capacities>
<power>9</power>
<cooldownTime>2</cooldownTime>
</li>
</tools>
</ThingDef>
我只讲其中比较关键的几个部分
>weaponClass:武器种类,原版预设了几种武器种类,可以在Core\WeaponClassDefs\WeaponClassDefs.xml处查看。一个武器可以同时属于多种种类。武器种类会与文化的戒律、生科的基因产生联动,除此之外似乎不影响其他机制。
>statBases:这里出现了5个比较重要的stat
>>AccuracyTouch:精度贴近
>>AccuracyShort:精度近
>>AccuracyMedium:精度中
>>AccuracyLong:精度远
>>RangedWeapon_Cooldown:远程冷却时间,武器开火后进入冷却时间,此时小人不能动,也就是开火的后摇。单位是秒,可以填小数
对应的就是游戏中的,具体你们进游戏看就是了【
值得注意的是这里填写的是基础值,实际的值还会受武器品质等七七八八的因素影响。
>verbs:这是一个填verbProperties的list。一般来说武器会读取其中的第一个作为主verb,我们不建议一个武器在verbs里填多个verbProperties。
>>verbClass:一个verb的class,决定了这种verb的工作方式。对于远程武器来说,原版的verbClass有以下选择:
【Verb_LaunchProjectile】:最基础的发射子弹。仅会发射一发。
【Verb_Shoot】:继承自Verb_LaunchProjectile,可以连续发射多发子弹。当然只发射一发也可以。
【Verb_ShootOneUse】:继承自Verb_Shoot,不仅可以连续发射多发子弹,而且武器会在发射后摧毁自己,也就是一次性武器的效果。
>>hasStandardCommand:这决定了小人在持有你的武器时,是否显示下方的武器按钮,一般填true即可。
>>defaultProjectile:填子弹的thingDef的defName,我们稍后再跳转到该处进行分析。
>>warmupTime:预热时间,就是武器的前摇,单位是秒,可以填小数。
>>range:武器射程,单位是格,可以填小数。值得一提的是根据格点对齐的范围计算方式,填整数会显得很难看,所以我们一般末尾是xx.9。当武器范围大于√(10000/π)(约为56.41896)时,游戏无法渲染该射程范围。这是由于游戏中渲染圆形格子使用的是缓存,缓存大小为10000个格子。
>>soundCast:开火的音效。音效播放位置是小人的位置。
>>soundCastTail:开火的音效。音效播放位置是摄像机,也就是不管玩家在看哪里都有。
>>muzzleFlashScale:开火的闪光特效的大小。
剩下的那个tools与近战篇讲的是一致的。不难发现,一把远程武器本身也具备近战武器的属性,只是一般来说这些属性较弱。当然,各位作者可以通过调整这些tools的伤害类型和数值,轻易的做出一把“带刺刀的步枪”。
在栓动步枪的def下方紧邻着的,就是栓动步枪子弹的ThingDef,从line590开始:
<ThingDef ParentName="BaseBullet">
<defName>Bullet_BoltActionRifle</defName>
<label>bolt-action rifle bullet</label>
<projectile>
<damageDef>Bullet</damageDef>
<damageAmountBase>18</damageAmountBase>
<stoppingPower>1.5</stoppingPower>
<speed>70</speed>
</projectile>
<graphicData>
<texPath>Things/Projectile/Bullet_big</texPath>
<graphicClass>Graphic_Single</graphicClass>
</graphicData>
</ThingDef>
为了教学,我们先分析一下其父定义BaseBullet(Core\ThingDefs_Misc\Weapons\BaseWeapons.xml,line97)
<ThingDef Name="BaseBullet" Abstract="True">
<category>Projectile</category>
<tickerType>Normal</tickerType>
<altitudeLayer>Projectile</altitudeLayer>
<thingClass>Bullet</thingClass>
<label>bullet</label>
<useHitPoints>False</useHitPoints>
<neverMultiSelect>True</neverMultiSelect>
<graphicData>
<shaderType>Transparent</shaderType>
</graphicData>
</ThingDef>
很重要的一点就是,thingClass为Bullet,继承自Projectile。
Projectile类的Thing会有自己的运动轨迹,通常是线性的。起点和终点由verb决定,在到达终点后会触发某事件(Impact)并自毁。
Bullet类的Impact事件即是对命中的Thing造成一定的伤害。
回到栓动步枪的子弹,除了defName和图像数据以外,最重要的就是projectile这个字段,它的class名为ProjectileProperties。
>damageDef:该子弹伤害的damageDef。
>damageAmountBase:子弹伤害的基础值。实际的值还会受武器品质等七七八八的因素影响。
>stoppingPower:抑止能力。体型小于等于“该值+0.001”的生物被子弹命中时,会造成95ticks(约1.583秒)的减速效果(速度x0.17)。这个减速时长与幅度可能会受生物的种类影响。(但原版还不存在修改bulletStaggerDelayTicks,bulletStaggerSpeedFactor的生物)
>speed:武器的弹道速度。具体的换算关系是,每tick运动的格数为(speed / 100)。也就是实际的速度是speed*0.6 格/s。过高的弹速可能会影响子弹的碰撞,请谨慎调整。原版弹速最高的武器为电荷标枪弹和铀弹加农炮塔的铀弹,为120。其次为狙击步枪的100。≥100的仅此三者。
接下来是电荷步枪Gun_ChargeRifle的分析,Core\ThingDefs_Misc\Weapons\RangedSpacer.xml,第一个def就是了。我们仅取要讲的部分来分析。
<verbs>
<li>
<verbClass>Verb_Shoot</verbClass>
<hasStandardCommand>true</hasStandardCommand>
<defaultProjectile>Bullet_ChargeRifle</defaultProjectile>
<warmupTime>1.0</warmupTime>
<range>25.9</range>
<ticksBetweenBurstShots>12</ticksBetweenBurstShots>
<burstShotCount>3</burstShotCount>
<soundCast>Shot_ChargeRifle</soundCast>
<soundCastTail>GunTail_Medium</soundCastTail>
<muzzleFlashScale>9</muzzleFlashScale>
</li>
</verbs>
这里多了2个字段:
>burstShotCount:每一次开火时的连发次数。此处即为一梭子有3发子弹
>ticksBetweenBurstShots:同一次开火内,每两次连发之间的间隔,单位为tick,填整数。
需要注意的是,在同1tick内最多发出一发子弹,即一秒60发。要想实现1tick内发出多发子弹的效果,需要修改verb,而那就是C#的范畴了。
此外,要记住这两个属性是与Verb_Shoot及其子类verbClass配套使用的。与Verb_LaunchProjectile一起用并不能实现连发。
该def后方紧挨着的就是电荷步枪弹的def,也有部分不同
<projectile>
<damageDef>Bullet</damageDef>
<damageAmountBase>15</damageAmountBase>
<armorPenetrationBase>0.35</armorPenetrationBase>
<speed>70</speed>
</projectile>
armorPenetrationBase:基础穿甲值。游戏里显示的是百分比,要注意区分一下。这个值是基础值,实际依然会受品质等因素影响。如果作者不把这个值写出来,那么默认的穿甲值是伤害的0.015倍。
这里再多补充一些常用的属性,首先是verbs的:
minRange:最小开火范围
soundAiming:瞄准时播放的音效
warmupEffecter:瞄准时播放的特效
子弹projectile的:
extraDamages:一个list,每个元素代表一种额外伤害的属性,有以下属性
>>>def:填一个DamageDef
>>>amount:伤害量
>>>armorPenetration:穿甲,不填的话也是自动生成
>>>chance:默认值是1,如果填了的话就是填0~1.00,表示该额外伤害的触发概率
landedEffecter:落地触发的特效
shadowSize:影子大小,默认为0也就是不渲染影子。
alwaysFreeIntercept:填false的话,子弹在发射时,有50%的概率被标记为FreeIntercept,此子弹在飞行过程中接触到“非初始目标”的单位也会触发命中。如果该值填true,则必定为FreeIntercept。
没有提到的可能用不上 也可能在后面几讲出现。
下次再会。