定位法术数据

通过菜单栏右上角的条形图标打开Stats Editor

在左侧列中,会有一个项目列表。打开与您的模组名称相对应的项目——它应该与您项目的名称相同。在本指南中,我们的模组名为 SimpleNewSpell。展开该项目以查看其子文件夹。

在这里,您会看到多个可供打开和修改的部分。要创建法术,请前往 SpellData 并点击“+”符号。

这将打开一个下拉菜单,显示游戏中可用的各种法术类型。

对于我们正在制作的目标法术,您需要添加TargetProjectile法术数据。您可能需要展开SpellData文件夹才能看到新添加的内容

制作目标法术 Target Spell

我们将制作一个触摸法术(施法者需要接触目标才能施放的法术),该法术会在目标上爆炸。爆炸将对区域内的所有人造成火焰伤害,并为施法者提供治疗

打开您新创建的Target法术数据。

对于目标法术,有一些必填字段,必须填写才能确保法术在游戏中正确执行。我们将介绍这些必填字段,以及上述示例中所需的一些额外字段

Name (Technical Name)

您需要填写法术的Name字段。这是法术的技术名称,也称为TechName。系统会使用该名称将特定法术分配给玩家。

该字段:

  • 不接受空格
  • 接受下划线 _(通常用来替代空格)
  • 接受数字和大写、小写字母

在我们的示例中,我们将使用技术名称 FireTouch


Level 和 SpellSchool

如果您希望您的法术显示为特定等级(如戏法1级等)或特定法术学派(如塑能预言死灵等)的一部分,请填写LevelSpellSchool 字段。

  • Level 字段接受数字。

    • 0 = 戏法(Cantrip)
    • 1 = 1级法术
    • 2 = 2级法术,依此类推。
  • SpellSchool 字段是一个法术学派的下拉菜单。

我们希望将这个法术设定为3级塑能法术,类似于火球术。因此,我们将在Level字段中填写3,并从SpellSchool下拉菜单中选择Evocation(塑能)。

这些信息将会自动显示在游戏内的提示框中


TargetRadius

TargetRadius 决定了施法者与目标之间需要保持的最小距离,以便成功施放该法术。

我们希望将这个法术设定为触摸法术。这意味着玩家必须在近战范围内才能施放该法术。

  • 该字段接受数字小数
  • 数值的单位是(metres)。

对于我们新制作的法术 FireTouch,我们将在 TargetRadius 字段中填写 1.5。这是《博德之门3》中近战范围所使用的标准数值。


AreaRadius

AreaRadius 决定了法术的效果范围

我们希望该法术能够影响施法者周围的所有人,因此我们也需要填写 AreaRadius 字段。

  • 该字段接受数字小数
  • 数值的单位是(meters)。

对于我们的新法术 FireTouch,我们将在 AreaRadius 字段中填写 3。这意味着法术将影响目标周围3米范围内的所有人


SpellRoll

所有法术必须定义 SpellRollSpellProperties 其中之一。在我们的例子中,我们将使用 SpellRoll。 SpellRoll 描述了这是什么类型的法术。在博德之门3中通常使用两种选项:SavingThrow()Attack()

在我们的示例中,我们将制作一个 SavingThrow 类型的法术,这类法术要求目标进行豁免检定。为此,我们将在 SpellRoll 字段中粘贴以下内容:

not SavingThrow(Ability.Dexterity, SourceSpellDC())

你可以将 Ability.Dexterity 部分更改为游戏中的任何属性类型(例如 Ability.CharismaAbility.Strength)。

因为我们正在制作一个 SavingThrow 类型的法术,我们需要填写 SpellSuccessSpellFail 字段。我们将在接下来的部分详细介绍如何填写这两个字段。

  • SpellSuccess 是用于定义施法者成功时会发生什么,也就是说敌人豁免检定失败的情况。

  • SpellFail

    是用于定义

    施法者失败时

    会发生什么,也就是说敌人豁免检定成功的情况。

    • SpellFail 字段是可选的,可以留空。

SpellSuccess

填写 SpellSuccess 字段来定义施法者成功时会发生什么。对于我们的新法术,我们想要实现两件事:治疗施法者,以及对目标和范围内的其他目标造成伤害。

  • 使用 IF() 语句来定义对每个角色产生的效果。
  • 使用 Self() 来指代施法者。
  • 使用 not Self() 来指代除施法者以外的所有人。

要治疗施法者,我们将使用 IF(Self()):RegainHitPoints(3d10)

  • RegainHitPoints() 可以接受骰子掷点(例如 3d10)或具体数值(例如 9)。

要对目标造成伤害,由于我们想对除施法者以外的所有人造成伤害,我们将使用 IF(not Self()):DealDamage(3d10,Fire,Magical)

  • DealDamage() 可以接受骰子掷点或具体数值。
  • Fire 表示伤害类型。
  • Magical表示它造成魔法伤害,用于计算抗性。
    • 因为这是一个法术,所以伤害是魔法性质的。

; 分隔每个动作。组合在一起是这样的:


SpellFail

填写 SpellFail 字段来定义施法者失败时会发生什么。我们要做的事情和 SpellSuccess 几乎一样,但对于我们的新法术,我们希望失败时只产生一半的治疗和一半的伤害。我们可以在 SpellSuccess 的基础上稍作修改,用 /2 将数值除以2。

  • 治疗部分:IF(Self()):RegainHitPoints(3d10/2)IF(Self()):RegainHitPoints((3d10)/2)
  • 伤害部分:IF(not Self()):DealDamage(3d10/2,Fire,Magical)IF(not Self()):DealDamage((3d10)/2,Fire,Magical)

再次用 ; 分隔每个动作。组合在一起是这样的:


TargetConditions

TargetConditions 筛选出施法者可以对谁施放法术。例如,如果我们输入 Self(),玩家将只能对自己施放该法术。 因为我们希望玩家能以任何存活的角色作为目标,所以我们将使用:Character() and not Dead()


AoEConditions

如果我们想让这个法术的区域效果(AoE)影响特定类型的角色,我们可以在 AoEConditions 字段中定义条件。例如,如果我们只想让 AoE 爆炸影响施法者的敌人,我们可以在这里写入 Enemy()。这个字段的另一个有效选项是 Ally()

在我们的新法术 FireTouch 中,我们想要让所有人都受到伤害,所以我们将使用与 TargetConditions 相同的设置。

玩家可见信息

接下来这部分属性列是关于填写玩家可见信息和工具提示信息的,这样玩家就能理解这个法术的作用

Icon

在这里你可以定义一个图标。就本指南而言,让我们重复使用火球术的现有法术图标:Spell_Evocation_Fireball


DisplayName

这将是在工具提示中显示的法术名称。让我们把这个新法术叫做 Touch of Fire

下面你可以看到这个名称将如何显示在工具提示中


Description

这将是玩家查看工具提示时看到的信息。这段文本只能包含字母。通常,你需要让玩家了解这个法术的作用。

对于我们的法术,我们将这样写: Touch an enemy with the force of a fireball. Everyone in the area will take [1] and the caster will be [2].


DescriptionParams

你可能注意到在上面的描述中我们使用了 [1][2]。这些是描述参数(DescriptionParms)的占位符。

在我们的法术工具提示描述中,我们想要表明敌人受到伤害而玩家得到治疗,所以我们将使用与添加到 SpellSuccess 中相同的 DealDamage()RegainHitPoints()。 我们将按照想要工具提示显示的顺序把它们插入到描述参数中。

  • [1] 应该是 DealDamage(3d10,Fire)
  • [2] 应该是 RegainHitPoints(3d10)

所以在 DescriptionParms 中,我们将输入 DealDamage(3d10,Fire);RegainHitPoints(3d10)

注意在这个用于工具提示的 DealDamage() 版本中,不使用 Magical

如果设置正确,你的法术工具提示现在应该显示该法术造成的伤害和治疗效果:


TooltipDamageList 和 TooltipAttackSave

TooltipDamageList给玩家提供了一种直观简洁的方式来查看法术的伤害和治疗效果。这将使用与我们描述参数完全相同的函数。 DealDamage(3d10,Fire);RegainHitPoints(3d10)

TooltipAttackSave用于豁免投掷法术,以指示是什么类型的豁免。我们的法术是基于敏捷的豁免,所以我们将在这个部分填写 Dexterity。

填写完这些字段后,你的法术工具提示现在会显示骰子的可视化效果,以及底部的敏捷(DEX)豁免。


CastTextEvent

所有法术都需要填写它们的CastTextEvent。这与施法者使用的动画有关 - 动画会寻找这个施法事件来执行法术的各个部分。

对于我们的法术,我们只想执行一个施法事件,所以我们只需在这一列中写入Cast

如果你忘记填写这个,你的动画可能会出现延迟,而不是平滑施法。


UseCost

这用于确定施法需要什么资源。目前,我们的法术还没有关联任何使用成本。

假设我们希望 FireTouch 消耗一个动作点和一个3级法术位。

  • ActionPoint:1
    • 这意味着它将消耗一个动作点。
  • SpellSlotsGroup:1:1:3
    • 这意味着施放这个法术需要消耗一个3级法术位。

如果你已经正确完成了这些设置,你的工具提示现在会如下显示法术的消耗:


Spell Animation

所有法术都需要一个法术动画才能使用。没有法术动画,法术就无法施放。

让我们获取一个现有的动画来使用。在状态编辑器中,展开左侧的Shared部分,然后展开其中的SpellData。

双击其中的Target文件来打开它。

我们正在寻找一个Touch(触摸)动画法术,所以我们将按Ctrl+F打开底部的搜索栏并输入’Touch’。按回车键进行搜索。

你应该看到搜索栏下方的区域更新了搜索结果,显示了Shared Target文件中所有名字包含Touch的法术。

让我们使用Vampiric Touch(吸血触摸)的动画。

如果你双击Vampiric Touch(任何一个VampiricTouch的结果都可以),它会带你到Target文件中的那一行。应该是第179行。

向右滚动直到找到SpellAnimation(法术动画)列(BL列)。

点击包含VampiricTouch法术动画数据的单元格,然后按Ctrl+C复制所有法术动画信息。

返回到你的mod的Target文件,并按Ctrl+V将复制的法术动画粘贴到FireTouch的Spell Animation列中。你的Spell Animation列现在应该是这个样子。


PrepareEffect, CastEffect, HitEffect

这些效果是我们如何将视觉效果应用到法术上。所有这些列都是下拉菜单,显示游戏中所有现有的效果。

如果你想制作自己的效果,请参考VFX指南**[[即将推出]]** - 但现在我们先使用一些现有的视觉效果。

PrepareEffect是法术的预施法阶段。这是在你选择了法术但还没有选择目标的期间。对于FireTouch,我们想要一些基于火焰的效果,所以让我们在下拉菜单中输入’fire’来筛选结果。

PrepareEffect需要一个带有_PrepareEffect后缀的效果,所以让我们使用Fireball_PrepareEffect

CastEffect是法术执行时施法者身上的视觉效果。你可能之前注意到Fireball也有一个cast effect(施法效果),所以让我们在这里使用它。和PrepareEffect一样,CastEffect应该有_CastEffect后缀。

HitEffect是当法术击中目标时在目标身上播放的视觉效果。同样,这个效果也应该以_HitEffect结尾,我们再次重用Fireball的效果:Fireball_HitEffect


PrepareSound, PrepareLoopSound, CastSound

这些字段是我们如何为法术添加音效。目前不支持创建新的音效,因此最好的方法是寻找一个类似的法术并把它的音效值复制到我们的法术中,就像我们对VFX所做的那样。对于我们的FireTouch法术,我们将从Shared → Projectile中复制Firebolt的音效:


SpellFlag

法术标志用于提供关于法术预期行为的额外信息。这些可能因具体情况而异。这个字段的下拉菜单允许选择多个选项。

对于FireTouch,让我们选择以下选项:

  • HasVerbalComponent(包含言语成分)
  • HasSomaticComponent(包含姿势成分)
  • IsMelee(近战)
  • IsSpell(是法术)
  • IsHarmful(有害)

HasVerbalComponent(包含言语成分): 带有此标志的法术在施法者被沉默时将无法使用。

HasSomaticComponent(包含姿势成分): 用于需要姿势动作才能施放的法术。

IsMelee(近战): 用于近战范围内的攻击和/或法术。

IsSpell(是法术): 建议用于任何在DnD中被视为法术的法术。使用此标志使法术能够与其他系统(如沉默、反制法术和护甲熟练度要求)配合使用。如果没有此标志,当法术等级为0时,工具提示会将其显示为”职业动作”。

IsHarmful(有害): 如果启用,此标志让AI知道是否要将NPC引入战斗。如果法术造成伤害,这自然会发生,但如果目标有可能通过豁免来抵消伤害,我们也需要这个标志。

一些其他在本例中未使用但可能有趣的常见标志:

  • IsConcentration(需要专注): 用于将法术变成专注法术。

  • IsAttack(是攻击): 用于不应该是魔法的攻击。

  • Temporary(临时): 用于为玩家只短暂拥有的法术打开快捷栏的临时部分。

测试我们的法术

现在,在填写了所有这些字段后,我们可以测试这个法术了。要测试这个法术,我们需要将它添加到某个职业的法术列表中,这样我们就可以在角色创建或升级时选择它。

打开UUID编辑器,在Lists部分创建一个新的SpellLists表:

在UUID编辑器中,转到 Shared → Lists → SpellLists。查看现有的SpellList,找到你想要修改的列表。请记住我们将FireTouch设置为3级法术,所以你应该选择3级法术列表。在本指南的测试中,我们将使用牧师的3级法术列表:

注意:我保持了FireTouch不变,因为它是高亮显示的专有名词。

将Shared SpellLists表格中的UUID字段复制并粘贴到你的mod的SpellLists中:

重复复制和粘贴到Spells字段中。这样做是为了保持原有的牧师列表完整。在末尾添加我们新法术的技术名称,用分号;分隔。

这里提到的”技术名称”指的是SpellType_SpellName格式。 在这个例子中,类型是Target,法术名称是FireTouch,所以完整的技术名称就是Target_FireTouch

Comment字段可以留空。这个字段在游戏中没有任何作用,仅作为开发者的注释使用。

保存你目前所做的所有更改。

要进行测试,如果你还没有加载关卡的话,需要先加载一个关卡。Basic_Level_A就完全够用了。一旦关卡加载完成,进入游戏模式。

将光标放在角色头像上,按下Ctrl+Shift+L来升级角色。点击Level Up按钮进入升级界面。

如果你的测试角色还不是牧师职业,使用多重职业菜单来添加牧师职业。

你需要再升几次级,直到你成为5级牧师,这样才能获得3环法术列表。到达这个等级后,进入法术标签页 - 在可用法术列表中,你应该能看到新添加的法术: Touch of Fire。一旦我们选择了这个法术,就可以在游戏中使用它并检查所有功能是否都按预期工作。

……略