Skip to content

状态

角色的各项属性(生命、体力、理智、经验、称号等)通过状态(Status)来描述。你可以在 game.config.ts 中预先声明,然后在游戏中通过简单的 API 来读取或修改它们,这些值会实时反映在界面上方的状态栏与菜单页中。

状态支持两种值类型:number(数值型,如生命值、力量)和 string(字符串型,如称号、阵营)。两种类型可以在同一个组内混合使用。每个状态在定义时通过 value 字段的值自动确定其类型,之后不可更改——TypeScript 会在编译期检查类型错误,运行时也会进行校验。

注意:所有状态的 id 必须全局唯一。即使你按组将它们分开,不同 ADVUserStatusGroup 内部的属性 id 也不能重复,否则会造成运行时错误。

声明状态

你可以在 game.config.tsconfig 变量中新增 status 字段。该字段是一个对象,每一个顶层的 key 都是一个 状态组,用于将相关属性归类(例如“战斗属性”、“生存状态”等)。

typescript
export default Adv.defineConfig({
    // ... 其他配置
    status: {
        base: {
            name: '基础属性',
            content: {
                hp: {
                    name: '生命值',
                    max: 100,
                    value: 100,
                    color: '#d32f2f',
                    isDisplay: 'process',
                },
                sp: {
                    name: '体力',
                    max: 50,
                    value: 50,
                    color: '#388e3c',
                    isDisplay: 'process',
                },
            },
        },
        mental: {
            name: '精神状态',
            content: {
                sanity: {
                    name: '理智',
                    max: 100,
                    min: 0,
                    value: 80,
                    color: '#7b1fa2',
                    isDisplay: 'process',
                },
            },
        },
        info: {
            name: '个人信息',
            content: {
                title: {
                    name: '称号',
                    value: '新手冒险者', // 字符串类型 — 由 value 值自动推断
                    color: '#e3960c',
                    isDisplay: 'text',
                },
                faction: {
                    name: '阵营',
                    value: '中立',
                    isDisplay: 'hide', // 字符串类型也可以设为 hide
                },
            },
        },
    },
});
  • 外层的 basementalinfo 是组 ID,用于逻辑上的分组管理,不会暴露给玩家。
  • 每组都有一个可选的 name,它会在状态总览页面中作为小标题展示。
  • content 里存放的就是真正会被用到的一个个状态属性。number 和 string 类型可以在同一组内混合。
  • 状态的值类型由 value 字段自动推断:写数字就是 number 型,写字符串就是 string 型。一经确定,不可更改

状态属性的配置项

每个状态属性使用 ADVUserStatus 对象配置,它的各项说明如下:

参数名类型默认值描述
namestring可选。属性显示给玩家的名字,如 "生命值"。不填则为 id。
maxnumberInfinity属性的最大值。设置后,界面上会以进度条或数字的形式体现上限。仅对 number 型状态生效
minnumber0属性的最小值。作用于 base+bonus 总值,超出时修改 bonus。仅对 number 型状态生效
basenumber0技能基础值。所有 number 型状态内部均以 base+bonus 存储base > 0 时属性菜单展示为 基础值 + 加值
valuenumber | string必填游戏开始时该属性的初始总值(= base + 初始 bonus)。类型决定了该状态的永久类型
colorstring() => string'black'显示时的强调色,用于进度条填充和数字/文字颜色。可以传入固定颜色字符串(如 '#d32f2f'),或一个返回颜色字符串的函数,实现动态变色。
isDisplay'none''hide''text''process' 或返回它们的函数'hide'控制该属性如何在界面上展示。详见下表。

显示类型 (isDisplay) 详解

效果
'text'在顶部状态栏靠右显示。number 型会带数字动画和 / max 后缀;string 型直接显示文字。
'process'除数字外,还以进度条形式展示在状态栏靠左,视觉上更直观地体现当前值与最大值的比例。仅适用于 number 型
'hide'在顶部的状态栏中隐藏该属性,但在菜单中的状态总览页面里仍然可见,适合展示一些相对次要但偶尔需要查看的属性。
'none'完全不在任何界面显示,适合作为纯粹的幕后数值(如隐藏好感度、成就计数等)。

isDisplay 也可以是一个函数,返回上述四种字符串之一,从而使显示方式根据游戏状态动态切换。例如受伤后原本隐藏的“伤口感染度”突然显示为进度条。

技能基础值、加值与修饰器

所有 number 型状态内部均采用 { base, bonus } 结构。base 默认为 0Adv.status.xxx 返回 StatusValueAccessor 对象——可当 number 使用,同时也提供了一些修饰器。

typescript
skills: {
    name: '技能',
    content: {
        FastTalk: {
            name: '话术',
            max: 100,
            base: 5,       // 基础值 5%
            value: 30,   // 初始总值 = 5 + 25(初始加值 25)
            isDisplay: 'hide',
        },
        Accounting: {
            name: '会计',
            max: 100,
            base: 5,       // 基础值 5%
            value: 5,    // 初始总值 = 5 + 0(无初始加值)
            isDisplay: 'hide',
        },
    },
}
  • base:技能的固定基础值。
  • value:技能的初始总值(= base + 初始加值)。

在属性菜单中,base > 0 的技能会展示为 基础值 + 加值 的格式,例如:

话术:5 +25 / 100

通过 API 读写状态:

typescript
// number 型 — 返回 StatusValueAccessor(可当 number 使用)
Adv.status.FastTalk; // 读取总值
Adv.status.FastTalk = 40; // 设置总值(等同于修改 bonus)
Adv.status.FastTalk += 10; // +=/-= 修改 bonus
Adv.status.FastTalk.base; // 读取 base
Adv.status.FastTalk.bonus; // 读取 bonus
Adv.status.FastTalk.base = 10; // 单独设置 base
Adv.status.FastTalk.bonus = 20; // 单独设置 bonus
Adv.status.FastTalk.hard; // 困难成功模式:总值 / 2,向下取整(如 60 => 30)
Adv.status.FastTalk.extreme; // 极难成功模式:总值 / 5,向下取整(如 60 => 12)

// string 型 — 直接读取与赋值
const currentTitle: string = Adv.status.title;
Adv.status.title = '屠龙者';

所有的修饰器如下:

属性计算方式读写
.valuebase + bonus只读
.base技能基础值读写
.bonus技能加值读写
.hardMath.floor(总值 / 2)只读
.extremeMath.floor(总值 / 5)只读

你可以在 ACheck 中直接使用这些阈值作为目标值:

xml
<!-- 困难话术检定 -->
<ACheck :target="() => Adv.status.FastTalk.hard" target-desc="话术检定(困难)">
    <template #success>你巧妙地说服了对方。</template>
    <template #fail>对方不为所动。</template>
</ACheck>

注意.hard.extreme 是实时计算的,始终反映当前总值。Adv.status.FastTalk += 10 后,.hard.extreme 也会自动更新。

max / min 始终作用于 base + bonus,超出时将会自动调整 bonus。