update: play property animation

update: event format field
fix: test
This commit is contained in:
Vick Scarlet
2026-08-16 20:06:16 +08:00
committed by 神戸小鳥
parent cd82d175c2
commit 6eea7d0d87
15 changed files with 110 additions and 155 deletions
-13
View File
@@ -188,16 +188,3 @@ function checkProp(property: PropertyContainer, condition: string): boolean {
return false
}
}
export function extractMaxTriggers(condition: string): number {
// Assuming only age related talents can be triggered multiple times.
const RE_AGE_CONDITION = /AGE\?\[([0-9,]+)\]/
const matchObject = RE_AGE_CONDITION.exec(condition)
if (matchObject === null) {
// Not age related, single trigger.
return 1
}
return matchObject[1]?.split(',')?.length ?? 1
}
+1
View File
@@ -17,6 +17,7 @@ describe('Achievement', () => {
intelligence: 5,
strength: 5,
money: 5,
spirit: 5,
}
test('trigger [times:500]', () => {
+1
View File
@@ -16,6 +16,7 @@ describe('Event', () => {
intelligence: 10,
strength: 0,
money: 0,
spirit: 5,
}
test('branch 10003:0 [玉佩]', () => {
+1
View File
@@ -17,6 +17,7 @@ describe('Achievement', () => {
intelligence: 5,
strength: 5,
money: 5,
spirit: 5,
}
test('talentsPicked', () => {
+16 -7
View File
@@ -2,7 +2,7 @@ import { expect, test, describe } from 'bun:test'
import { parse, type ConditionNode } from '@remake/condition'
import { achievements, events, talents } from '@remake/data'
import type { GameState, ProfileState, Properties } from './state'
import type { FlatState, GameState, ProfileState, Properties } from './state'
import { createFlatState, createHLProperties, propsEffect } from './state'
import { SupportedFlatStateKeys } from './state'
import { enableMapSet } from 'immer'
@@ -11,7 +11,10 @@ enableMapSet()
/**
* 核心递归辅助函数:从多维语法树节点中提取所有属性名
*/
function extractKeysFromNode(node: ConditionNode, properties: Set<string>) {
function extractKeysFromNode(
node: ConditionNode,
properties: Set<keyof FlatState>,
) {
if (Array.isArray(node)) {
for (const subNode of node) {
extractKeysFromNode(subNode, properties)
@@ -22,7 +25,7 @@ function extractKeysFromNode(node: ConditionNode, properties: Set<string>) {
// 匹配操作符(><!?=)前面的属性名部分
const match = node.match(/^([^><!?=]+)/)
if (match && match) {
properties.add(match[1]!.trim())
properties.add(match[1]!.trim() as keyof FlatState)
}
}
}
@@ -30,9 +33,9 @@ function extractKeysFromNode(node: ConditionNode, properties: Set<string>) {
/**
* 从条件字符串中提取所有使用到的属性键名
*/
function getPropertiesFromCondition(condition: string): Set<string> {
function getPropertiesFromCondition(condition: string): Set<keyof FlatState> {
const parsedConditions = parse(condition)
const properties = new Set<string>()
const properties = new Set<keyof FlatState>()
extractKeysFromNode(parsedConditions, properties)
return properties
}
@@ -205,7 +208,13 @@ describe('State', () => {
)
})
const allocation = { charm: 5, intelligence: 5, strength: 5, money: 5 }
const allocation = {
charm: 5,
intelligence: 5,
strength: 5,
money: 5,
spirit: 5,
}
test('createHLProperties', () => {
const props = createHLProperties(allocation)
expect(props.current.charm).toBe(allocation.charm)
@@ -213,7 +222,7 @@ describe('State', () => {
expect(props.current.strength).toBe(allocation.strength)
expect(props.current.money).toBe(allocation.money)
expect(props.current.age).toBe(-1)
expect(props.current.spirit).toBe(0)
expect(props.current.spirit).toBe(5)
})
test('propsEffect', () => {
+2 -2
View File
@@ -30,11 +30,11 @@ describe('Talent', () => {
test('pull external', () => {
const p = produce(profile, draft => {
draft.lockedTalent = 1001
draft.locked = [1001]
})
const result = pull(options, p)
expect(result.length).toBe(options.count)
expect(result).toContain(p.lockedTalent!)
expect(result).toContain(p.locked![0]!)
})
test('pull rate', () => {
+9
View File
@@ -0,0 +1,9 @@
## Bugs
### 复活Bug
age 400
-> 寿元终
-> 天赋复活
age 401
-> 无可随机事件
-> 报错
+2
View File
@@ -47,6 +47,8 @@ export type Event = {
readonly exclude?: string
/** 分支路线 */
readonly branch?: EventBranch[]
/** 是否需要格式化 */
readonly format?: boolean
}
// @vt-types-end
Binary file not shown.
+15
View File
@@ -43,3 +43,18 @@ export function keys<T extends object, K extends keyof T = never>(
const filterSet = new Set<keyof T>(filter)
return allKeys.filter(key => !filterSet.has(key)) as Exclude<keyof T, K>[]
}
// 定义获取字段值的方法签名
export type GetValueFn = (
fieldName: string,
) => string | number | boolean | null | undefined
export function format(str: string, getValueFn: GetValueFn): string {
if (!str) return ''
return str.replace(
/\{([^}]+)\}/g,
(match: string, fieldName: string): string => {
const value = getValueFn(fieldName)
if (value === undefined || value === null) return match
return String(value)
},
)
}