From 6eea7d0d877bb9919a9fe35713ffff17f1ac0b5a Mon Sep 17 00:00:00 2001 From: Vick Scarlet Date: Wed, 12 Aug 2026 21:57:49 +0800 Subject: [PATCH] update: play property animation update: event format field fix: test --- README-zh_CN.md | 51 ++++------------------- README.md | 51 ++++------------------- apps/web/src/containers/Play.tsx | 57 ++++++++++++++++++-------- apps/web/src/containers/Summary.tsx | 20 ++++----- docs/remake.md | 17 -------- packages/condition/index.ts | 13 ------ packages/core/src/achievement.spec.ts | 1 + packages/core/src/event.spec.ts | 1 + packages/core/src/game.spec.ts | 1 + packages/core/src/state.spec.ts | 23 +++++++---- packages/core/src/talent.spec.ts | 4 +- packages/data/BUGS.md | 9 ++++ packages/data/src/event.types.ts | 2 + packages/data/src/event.xlsx | Bin 160530 -> 197502 bytes packages/vitex/index.ts | 15 +++++++ 15 files changed, 110 insertions(+), 155 deletions(-) delete mode 100644 docs/remake.md create mode 100644 packages/data/BUGS.md diff --git a/README-zh_CN.md b/README-zh_CN.md index e44f7f5..81aa6df 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -1,56 +1,19 @@ -# Life Restart +# 人生重开模拟器 [English](./README.md) | 简体中文 -## 简介 +## 开发环境 -- Game Life Restart +包管理: `pnpm` +运行时: `bun` ## 使用 -
-网页版 -
+### 开发 ```bash -# 1. 下载项目代码 -git clone https://github.com/VickScarlet/lifeRestart.git my-project - -# 2. 进入目录安装依赖 -cd my-project -pnpm install - -# 3. 转换XLSX表 -pnpm xlsx2json - -# 4. 启动本地开发服务器 +pnpm build:data pnpm dev -``` - -启动完成后打开浏览器访问 [http://localhost:5173](http://localhost:5173)。 - -
- -
-控制台版本 -
- -```bash -node repl -``` - -
- -## 其他版本 - -
-版本列表 -
- -- Cocos版:[gameall3d/LifeRestart_Cocos](https://github.com/gameall3d/LifeRestart_Cocos) - -
- -> 更多信息请参考 [官网文档](https://liferestart.syaro.io/)。 +``` \ No newline at end of file diff --git a/README.md b/README.md index 8494368..a34610d 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,19 @@ -# Life Restart +# Remake English | [简体中文](./README-zh_CN.md) -## Introduction +## Environment -- Game Life Restart +Package Manager: `pnpm` +Runtime: `bun` ## Usage -
-Web Version -
- +### Dev ```bash -# 1. Clone project code. -git clone git@github.com:VickScarlet/lifeRestart.git my-project -cd my-project - -# 2. Installation dependence. -pnpm install - -# 3. Transform XLSX -pnpm xlsx2json - -# 4. Start local dev server. +pnpm build:data pnpm dev -``` - -After the startup is complete, open a browser and visit [http://localhost:5173](http://localhost:5173). -
- -
-Command Line Version -
- -```bash -node repl -``` - -
- -## Other Version - -
-Versions -
- -- Cocos Ver: [gameall3d/LifeRestart_Cocos](https://github.com/gameall3d/LifeRestart_Cocos) - -
- -> More instructions at [documentation](https://liferestart.syaro.io/). +``` \ No newline at end of file diff --git a/apps/web/src/containers/Play.tsx b/apps/web/src/containers/Play.tsx index cf33a7f..0b77bf4 100644 --- a/apps/web/src/containers/Play.tsx +++ b/apps/web/src/containers/Play.tsx @@ -6,6 +6,7 @@ import type { Log } from '@remake/hooks' import { properties } from '@/display' import { achievements, events, talents } from '@remake/data' import { AutoInterval } from '@/config' +import { format } from '@remake/vitex' import './Play.css' function LogTalent({ id }: { id: number }) { @@ -25,12 +26,19 @@ function LogTalents({ items }: { items: number[] }) { return } +const year = new Date().getFullYear() interface LogEventProps { id: number post: boolean + index: number } -function LogEvent({ id, post }: LogEventProps) { - const { event, postEvent, grade } = events.get(id)! +function LogEvent({ id, post, index }: LogEventProps) { + let { event, postEvent, grade, format: f } = events.get(id)! + if (f) { + const g = (key: string) => ({ CurrentYear: year + index })[key] + event = format(event, g) + if (post && postEvent) postEvent = format(postEvent, g) + } return ( <>
  • {event}
  • @@ -41,10 +49,10 @@ function LogEvent({ id, post }: LogEventProps) { ) } -function LogEvents({ items }: { items: number[] }) { +function LogEvents({ items, index }: { items: number[]; index: number }) { const last = items.length - 1 const els = items.map((id, i) => ( - + )) return
      {els}
    } @@ -66,13 +74,13 @@ function LogAchievements({ items }: { items: number[] }) { return
      {els}
    } -function Log({ log }: { log: Log }) { +function Log({ log, index }: { log: Log; index: number }) { return (
  • {log.age}岁
    - +
  • @@ -88,25 +96,40 @@ interface PropProps { function Prop({ prop, value, grade }: PropProps) { const prevRef = useRef(value) const [trend, setTrend] = useState<'up' | 'down' | 'normal'>('normal') - const [animCount, setAnimCount] = useState(0) + const [flip, setFlip] = useState(0) + const [displayValue, setDisplayValue] = useState(value) useEffect(() => { const prev = prevRef.current if (value === prev) return prevRef.current = value setTrend(value > prev ? 'up' : 'down') - setAnimCount(c => c + 1) - const timer = setTimeout(() => { - setTrend('normal') - }, 2000) - return () => clearTimeout(timer) + setFlip(f => (f + 1) % 2) + let startTimestamp: number | null = null + const duration = 400 + const startValue = displayValue + let end = false + const step = (timestamp: number) => { + if (!startTimestamp) startTimestamp = timestamp + const progress = timestamp - startTimestamp + const progressRatio = Math.min(progress / duration, 1) + const easeOutQuad = progressRatio * (2 - progressRatio) + const currentDec = startValue + (value - startValue) * easeOutQuad + setDisplayValue(Math.round(currentDec)) + if (!end && progress < duration) requestAnimationFrame(step) + } + requestAnimationFrame(step) + const timer = setTimeout(() => setTrend('normal'), 2000) + return () => { + clearTimeout(timer) + setDisplayValue(value) + end = true + } }, [value]) return ( -
  • +
  • {properties[prop]} - {value} + {displayValue}
  • ) } @@ -160,7 +183,7 @@ export function Play() { ref={logRef} > {logs.map((log, index) => ( - + ))}
    diff --git a/apps/web/src/containers/Summary.tsx b/apps/web/src/containers/Summary.tsx index 9255579..f9c5bb3 100644 --- a/apps/web/src/containers/Summary.tsx +++ b/apps/web/src/containers/Summary.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState, useRef } from 'react' +import { useEffect, useState, useRef, useMemo } from 'react' import { usePicked, useEnd, useProfile } from '@remake/hooks' import { useEndJudge } from '@/hooks/judge' import { properties, judgeDisplay } from '@/display' @@ -27,26 +27,24 @@ interface TalentListProps { } function TalentList({ picked, picker }: TalentListProps) { const [profile] = useProfile() - const [talents, setTalents] = useState(usePicked()) + const items = usePicked() + const talents = useMemo(() => { + if (!isDev || !profile.locked) return items + return new Set([...items, ...profile.locked]) + }, []) const hasInitialized = useRef(false) - useEffect(() => { if (!profile.locked) return - let currentTalents = talents - if (isDev) { - currentTalents = new Set([...talents, ...profile.locked]) - setTalents(currentTalents) - } - if (!hasInitialized.current) { for (const id of profile.locked) { - if (currentTalents.has(id) && !picked.has(id)) { + if (talents.has(id) && !picked.has(id)) { picker(id) } } hasInitialized.current = true } - }, [profile, talents, picked, picker]) + }, [picked, picker]) + return (