本讲分析的是在原版(core+all dlc)环境下,一个Pawn可以用的Tools的所有来源。
重点要分析的是RimWorld.Pawn_MeleeVerbs下的方法GetUpdatedAvailableVerbsList,我把它贴在下面:
public List<VerbEntry> GetUpdatedAvailableVerbsList(bool terrainTools)
{
meleeVerbs.Clear();
verbsToAdd.Clear();
if (!terrainTools)
{
List<Verb> allVerbs = pawn.verbTracker.AllVerbs;
for (int i = 0; i < allVerbs.Count; i++)
{
if (IsUsableMeleeVerb(allVerbs[i]))
{
verbsToAdd.Add(allVerbs[i]);
}
}
if (pawn.equipment != null)
{
List<ThingWithComps> allEquipmentListForReading = pawn.equipment.AllEquipmentListForReading;
for (int j = 0; j < allEquipmentListForReading.Count; j++)
{
List<Verb> list = allEquipmentListForReading[j].GetComp<CompEquippable>()?.AllVerbs;
if (list == null)
{
continue;
}
for (int k = 0; k < list.Count; k++)
{
if (IsUsableMeleeVerb(list[k]))
{
verbsToAdd.Add(list[k]);
}
}
}
}
if (pawn.apparel != null)
{
List<Apparel> wornApparel = pawn.apparel.WornApparel;
for (int l = 0; l < wornApparel.Count; l++)
{
List<Verb> list2 = wornApparel[l].GetComp<CompEquippable>()?.AllVerbs;
if (list2 == null)
{
continue;
}
for (int m = 0; m < list2.Count; m++)
{
if (IsUsableMeleeVerb(list2[m]))
{
verbsToAdd.Add(list2[m]);
}
}
}
}
foreach (Verb hediffsVerb in pawn.health.hediffSet.GetHediffsVerbs())
{
if (IsUsableMeleeVerb(hediffsVerb))
{
verbsToAdd.Add(hediffsVerb);
}
}
if (ModsConfig.AnomalyActive && pawn.IsMutant)
{
foreach (Verb allVerb in pawn.mutant.AllVerbs)
{
if (IsUsableMeleeVerb(allVerb))
{
verbsToAdd.Add(allVerb);
}
}
}
}
else if (pawn.Spawned && !pawn.IsMutant)
{
TerrainDef terrain = pawn.Position.GetTerrain(pawn.Map);
if (terrainVerbs == null || terrainVerbs.def != terrain)
{
terrainVerbs = Pawn_MeleeVerbs_TerrainSource.Create(this, terrain);
}
List<Verb> allVerbs2 = terrainVerbs.tracker.AllVerbs;
for (int n = 0; n < allVerbs2.Count; n++)
{
Verb verb = allVerbs2[n];
if (IsUsableMeleeVerb(verb))
{
verbsToAdd.Add(verb);
}
}
}
float num = 0f;
foreach (Verb item in verbsToAdd)
{
float num2 = VerbUtility.InitialVerbWeight(item, pawn);
if (num2 > num)
{
num = num2;
}
}
foreach (Verb item2 in verbsToAdd)
{
meleeVerbs.Add(new VerbEntry(item2, pawn, verbsToAdd, num));
}
return meleeVerbs;
bool IsUsableMeleeVerb(Verb v)
{
if (v.IsMeleeAttack)
{
return v.IsStillUsableBy(pawn);
}
return false;
}
}
具有一定C#基础的同学一看就懂了,好的,本期教程到此为止,谢谢大家【
咳咳,然而该教程依然是面向XML的教程,所以我将把上述天书翻译为正常的教程内容。
首先,一个Pawn本身会自带一定的Tools,比如人类的左拳右拳牙齿头槌:
Core\ThingDefs_Races\Races_Humanlike.xml,line16开始
<tools>
<li>
<label>left fist</label>
<labelNoLocation>fist</labelNoLocation>
<capacities>
<li>Blunt</li>
</capacities>
<power>8.2</power>
<cooldownTime>2</cooldownTime>
<linkedBodyPartsGroup>LeftHand</linkedBodyPartsGroup>
<surpriseAttack>
<extraMeleeDamages>
<li>
<def>Stun</def>
<amount>14</amount>
</li>
</extraMeleeDamages>
</surpriseAttack>
</li>
<li>
<label>right fist</label>
<labelNoLocation>fist</labelNoLocation>
<capacities>
<li>Blunt</li>
</capacities>
<power>8.2</power>
<cooldownTime>2</cooldownTime>
<linkedBodyPartsGroup>RightHand</linkedBodyPartsGroup>
<surpriseAttack>
<extraMeleeDamages>
<li>
<def>Stun</def>
<amount>14</amount>
</li>
</extraMeleeDamages>
</surpriseAttack>
</li>
<li>
<label>teeth</label>
<capacities>
<li>Bite</li>
</capacities>
<power>8.2</power>
<cooldownTime>2</cooldownTime>
<linkedBodyPartsGroup>Teeth</linkedBodyPartsGroup>
<chanceFactor>0.07</chanceFactor>
<soundMeleeHit>Pawn_Melee_HumanBite_Hit</soundMeleeHit>
<soundMeleeMiss>Pawn_Melee_HumanBite_Miss</soundMeleeMiss>
</li>
<li>
<label>head</label>
<capacities>
<li>Blunt</li>
</capacities>
<power>5</power>
<cooldownTime>2</cooldownTime>
<linkedBodyPartsGroup>HeadAttackTool</linkedBodyPartsGroup>
<ensureLinkedBodyPartsGroupAlwaysUsable>true</ensureLinkedBodyPartsGroupAlwaysUsable>
<chanceFactor>0.2</chanceFactor>
</li>
</tools>
Pawn自带的tools会多出一个常用的字段,为linkedBodyPartsGroup,即该Tool与身体部件绑定。具体来说,与其绑定的BodyPartsGroup内的身体部件的效率会以倍率的形式影响该Tool的伤害;而如果Group内的身体部件均已缺失,则该Tool的伤害为0,也就不会被使用。
与之相关的另一个字段是ensureLinkedBodyPartsGroupAlwaysUsable,如果填的是true,那么伤害倍率至少为0.4倍,那么即使绑定的所有部件均已缺失,也能正常使用。
除此之外,这里还有一个surpriseAttack的词条,这并非“暴击”的意思,而是突然袭击。
具体来说,这个机制只有一个触发条件:当野生的食肉动物触发狩猎工作(JobDriver_PredatorHunt)时,若该次攻击是对目标造成的第一次尝试攻击,且目标并非殖民者,那么会造成额外的效果。在原版,这个额外效果均为14*30tick(7秒)的晕眩。
还有一个出现的chanceFactor,它会影响随机选用tools时被选中的概率。(具体的选择逻辑后续讲吧)
第二个来源是手持的武器,这个就不再细讲了。
第三个来源是身上的装备,装备依然需要带有CompEquippable,与武器类似。
第四个来源是hediff,比如皇权里面的肘刀:
Royalty\HediffDefs\Hediffs_BodyParts_Prosthetic_Empire.xml
<HediffDef ParentName="ImplantHediffBase">
<defName>ElbowBlade</defName>
<label>elbow blade</label>
<labelNoun>an elbow blade</labelNoun>
<description>An installed elbow blade. Extends at will from a hidden opening at the end of the ulna. Appearing without warning, it can be used for devastating slice attacks.</description>
<descriptionHyperlinks><ThingDef>ElbowBlade</ThingDef></descriptionHyperlinks>
<addedPartProps>
<solid>true</solid>
</addedPartProps>
<comps>
<li Class="HediffCompProperties_VerbGiver">
<tools>
<li>
<label>blade</label>
<capacities>
<li>Cut</li>
</capacities>
<power>18</power>
<cooldownTime>2</cooldownTime>
<alwaysTreatAsWeapon>true</alwaysTreatAsWeapon>
<soundMeleeHit>MeleeHit_BionicSlash</soundMeleeHit>
<soundMeleeMiss>MeleeMiss_BionicSlash</soundMeleeMiss>
</li>
</tools>
</li>
</comps>
<spawnThingOnRemoved>ElbowBlade</spawnThingOnRemoved>
</HediffDef>
就是这里的comp里面的内容。当带有该comp的hediff出现在小人身上的时候,小人就能直接使用它作为近战来源。
第五个来源是异象DLC下的机制,变异的生物会获得来自变异提供的更多tools,在MutantDef.tools进行编辑。原版比较典型的是蹒跚怪获得的新tools:
Anomaly\Misc\Mutants.xml line87
<tools>
<li>
<label>teeth</label>
<capacities>
<li>Bite</li>
</capacities>
<power>8.2</power>
<cooldownTime>2</cooldownTime>
<linkedBodyPartsGroup>Teeth</linkedBodyPartsGroup>
<chanceFactor>1</chanceFactor>
<soundMeleeHit>Pawn_Melee_HumanBite_Hit</soundMeleeHit>
<soundMeleeMiss>Pawn_Melee_HumanBite_Miss</soundMeleeMiss>
</li>
<li>
<label>left hand</label>
<labelNoLocation>hand</labelNoLocation>
<capacities>
<li>Scratch</li>
</capacities>
<power>7.0</power>
<cooldownTime>2</cooldownTime>
<linkedBodyPartsGroup>LeftHand</linkedBodyPartsGroup>
<chanceFactor>1.5</chanceFactor>
<alwaysTreatAsWeapon>true</alwaysTreatAsWeapon>
</li>
<li>
<label>right hand</label>
<labelNoLocation>hand</labelNoLocation>
<capacities>
<li>Scratch</li>
</capacities>
<power>7.0</power>
<cooldownTime>2</cooldownTime>
<linkedBodyPartsGroup>RightHand</linkedBodyPartsGroup>
<chanceFactor>1.5</chanceFactor>
<alwaysTreatAsWeapon>true</alwaysTreatAsWeapon>
</li>
</tools>
新增了一个牙齿,两个伤害类型为刮伤的左右手。这三个tools类似Pawn自带的tools,也是与身体部件绑定的。但可以发现它们的chanceFactor都被设置的很高,表达了泰南将其作为更高攻击性身体武器的想法。
第六个来源是地板。Core\TerrainDefs\Terrain_Natural.xml line41
<tools>
<li>
<label>dirt</label>
<capacities>
<li>KickMaterialInEyes</li>
</capacities>
<hediff>DirtInEyes</hediff>
<cooldownTime>1.5</cooldownTime>
</li>
</tools>
就是站在这种地形上可以使用这种tool,这里是把土踢进人眼睛里,是一个特殊的近战。
没了。下次再会。