专长需求框架

专长需求框架

一个用于为专长添加更多要求以及完全自定义要求的框架。

[size=4]一个用于为专长添加新需求的框架。你可以直接在 Feats.lsx 文件中使用预先制作好的需求选项,也可以用 lua 完全自定义。[/size]

[size=4]已知问题:
1. 升级时角色会轻微闪烁。这是因为我们需要“刷新”升级 UI 来锁定专长,而我们找到的最简单方法是选择一个兼职,所以代码会选择一个兼职然后尽快取消选择,通常在你还没来得及按空格跳过开场动画之前就完成了。希望将来我能找到更好的方法。[/size]
[size=4]
特别感谢:
Chatgpt 提供的编码帮助。
Mazzle 提供的超棒库以及在研究上的帮助。
Nzx 发现了可以动态编辑专长需求。
DIQscord 里的所有兄弟们[/size]


[size=6][b]使用方法:[/b][/size]
[b]在 Feats.lsx 中,像这样编写你的专长需求:[/b]
[code]<attribute id="Requirements" type="LSString" value="PlayerLevel>=10;HasPassive(Darkvision)"/>[/code]用分号分隔条件。每个条件都必须通过,使用内部名称或 ID,并注意大小写匹配。

[size=6][b]包含的需求:[/b][/size]
[b]玩家等级:[/b] [font=Courier New]PlayerLevel >= 10[/font]
[b]职业等级:[/b] [font=Courier New]ClassLevel(Rogue) >= 4[/font]
[b]属性值:[/b] [font=Courier New]Ability(Constitution) >= 16[/font]
[b]拥有被动:[/b] [font=Courier New]HasPassive(Darkvision)[/font]
[b]排除被动:[/b] [font=Courier New]NotPassive(Darkvision)[/font]
[b]种族:[/b] [font=Courier New]Race(HalfElf)[/font]
[b]亚种:[/b] [font=Courier New]Subrace(Elf_WoodElf)[/font]
[b]子职业:[/b] [font=Courier New]Subclass(Assassin)[/font]
[b]背景:[/b] [font=Courier New]Background(Sage)[/font]
[b]神祇:[/b] [font=Courier New]Deity(Selune)[/font]
[b]标签:[/b] [font=Courier New]HasTag(TIEFLING)[/font]
[b]起源:[/b] [font=Courier New]Origin(Astarion)[/font]
[b]拥有专长:[/b] [font=Courier New]HasFeat(Alert)[/font]
[b]排除专长:[/b] [font=Courier New]NotFeat(Alert)[/font]
[b]技能熟练:[/b] [font=Courier New]SkillProficiency(Acrobatics)[/font]
[b]技能专精:[/b] [font=Courier New]SkillExpertise(SleightOfHand)[/font]
[b]豁免检定熟练:[/b] [font=Courier New]SavingThrowProficiency(Strength)[/font]
[b]已知法术:[/b] [font=Courier New]HasSpell(Target_MistyStep)[/font]
[b]最高法术位等级:[/b] [font=Courier New]SpellSlotLevel >= 3[/font]
[b]职业数量:[/b] [font=Courier New]ClassCount >= 2[/font]

[b]运算符需求使用 Lua 比较:[/b]
[code]>  >=  <  <=  ==  ~=[/code]分别为:大于、大于或等于、小于、小于或等于、等于、不等于。按出现顺序排列。
玩家等级、职业等级和职业数量包含升级选择(例如从 10 级升到 11 级时,可以选择需要至少 11 级(>=11)的专长)。


[b]XML 要求将 < 写为 &lt;,如下所示:[/b]
[code]PlayerLevel&lt;10[/code]
[size=6][b]完全自定义的 lua 需求:[/b][/size]
从你模组的 BootstrapClient.lua(或它 require 的任何文件)中注册回调:
[code]---@param character EntityHandle
local function CheckFeats(character, LockFeat)
    ---@type ResourceRace
    local race = Ext.StaticData.Get(character.Race.Race, "Race")

    if not race.Name:match("^HalfElf") then
        LockFeat(
            "010f717e-c6e2-45cf-bbf9-298a72db4cad", --your feat UUID
            "You must be a half-elf to choose this feat." --message on hover
        )
    end
end

Ext.Events.SessionLoaded:Subscribe(function()
    Mods.FeatRequirementsFramework.RegisterCallback(CheckFeats)
end)[/code][font=Courier New]character[/font] 是当前正在升级的实体。对每个未满足的需求调用 [font=Courier New]LockFeat(featUUID, message)[/font],逻辑非常简单。当条件不满足时,锁定它;当条件满足时,什么都不做,让用户选择。不需要“解锁”。