mirror of
https://github.com/VickScarlet/lifeRestart.git
synced 2026-08-28 17:26:47 +08:00
update: play property animation
update: event format field fix: test
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ describe('Achievement', () => {
|
||||
intelligence: 5,
|
||||
strength: 5,
|
||||
money: 5,
|
||||
spirit: 5,
|
||||
}
|
||||
|
||||
test('trigger [times:500]', () => {
|
||||
|
||||
@@ -16,6 +16,7 @@ describe('Event', () => {
|
||||
intelligence: 10,
|
||||
strength: 0,
|
||||
money: 0,
|
||||
spirit: 5,
|
||||
}
|
||||
|
||||
test('branch 10003:0 [玉佩]', () => {
|
||||
|
||||
@@ -17,6 +17,7 @@ describe('Achievement', () => {
|
||||
intelligence: 5,
|
||||
strength: 5,
|
||||
money: 5,
|
||||
spirit: 5,
|
||||
}
|
||||
|
||||
test('talentsPicked', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
## Bugs
|
||||
|
||||
### 复活Bug
|
||||
age 400
|
||||
-> 寿元终
|
||||
-> 天赋复活
|
||||
age 401
|
||||
-> 无可随机事件
|
||||
-> 报错
|
||||
@@ -47,6 +47,8 @@ export type Event = {
|
||||
readonly exclude?: string
|
||||
/** 分支路线 */
|
||||
readonly branch?: EventBranch[]
|
||||
/** 是否需要格式化 */
|
||||
readonly format?: boolean
|
||||
}
|
||||
// @vt-types-end
|
||||
|
||||
|
||||
Binary file not shown.
@@ -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)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user