4 Commits

Author SHA1 Message Date
Liushiqi1542
043308b44f Merge 6f63d63cff into 2eadb6fb23 2024-07-31 19:42:09 +08:00
Liushiqi1542
6f63d63cff add workbench config 2021-09-15 00:00:31 +08:00
Liushiqi1542
7c002c1896 add workbench config 2021-09-14 19:06:13 +08:00
Liushiqi1542
a57889e848 add workbench config 2021-09-14 19:06:12 +08:00
94 changed files with 189514 additions and 2219 deletions

View File

@@ -1,29 +0,0 @@
name: Build and Deploy
on:
push:
branches: [main]
permissions:
contents: write
jobs:
build-and-deploy:
concurrency: ci-${{ github.ref }} # Recommended if you intend to make multiple deployments in quick succession.
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
run: |
pnpm install
pnpm xlsx2json
pnpm build
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: template # The folder the action should deploy.

74
.github/workflows/fe.cdDaily.yaml vendored Normal file
View File

@@ -0,0 +1,74 @@
name: FE Project CI
on:
workflow_dispatch:
inputs:
version:
description: 'version'
required: false
default: '1.0.0'
oss_region:
description: 'oss region'
required: true
default: 'oss-cn-shanghai'
oss_bucket:
description: 'oss bucket'
required: true
default: ''
oss_path:
description: 'oss path'
required: false
default: ''
upload_path:
description: 'upload path'
required: true
default: './build'
pure_static_project:
description: 'project is a static project'
required: true
default: 'false'
compile_command:
description: 'code compile command'
required: true
default: 'true'
jobs:
pre-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: check package.json
run: ${{github.event.inputs.pure_static_project}} || ( test -f ./package.json && exit 0 || (echo 'package.json is not exist!' && exit 1))
build-and-deploy:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: install deps and build
run: ${{github.event.inputs.pure_static_project}} || ${{github.event.inputs.compile_command}}
- name: deploy to oss
id: upload_to_oss
uses: AliyunWorkbench/workbench-oss@1.0.0
with:
ACCESS_KEY: ${{ secrets.AK }}
ACCESS_SECRET: ${{ secrets.SK }}
OSS_REGION: ${{github.event.inputs.oss_region}}
OSS_BUCKET: ${{github.event.inputs.oss_bucket}}
OSS_PATH: ${{github.event.inputs.oss_path}}
UPLOAD_PATH: ${{github.event.inputs.upload_path}}

31
.github/workflows/node.js.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm install
- run: npm run build --if-present
- run: npm test

5
.gitignore vendored
View File

@@ -107,7 +107,4 @@ utils/xlsxTransform-*
/.idea
__localStorage.json
template/public
public/data
__localStorage.json

29
.vscode/launch.json vendored
View File

@@ -4,15 +4,40 @@
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Chrome",
"request": "launch",
"type": "pwa-chrome",
"url": "http://127.0.0.1:8000/public/index.html",
"webRoot": "${workspaceFolder}"
},
{
"type": "node",
"request": "launch",
"name": "test",
"program": "${workspaceFolder}/test",
"skipFiles": [
"<node_internals>/**",
"**/node_modumes/**"
"<node_internals>/**"
]
},
{
"type": "node",
"request": "launch",
"name": "xlsx2json",
"program": "${workspaceFolder}/node_modules/v-transform/src/index.js",
"args": ["transform", "jobs/xlsx2json/config.json"],
"skipFiles": [
"<node_internals>/**"
]
},
{
"name": "Attach by Process ID",
"processId": "${command:PickProcess}",
"request": "attach",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
]
}

5
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"cSpell.words": [
"Laya"
]
}

1
CNAME Normal file
View File

@@ -0,0 +1 @@
liferestart.syaro.io

View File

@@ -24,7 +24,7 @@ cd my-project
2. 进入目录安装依赖。
```bash
pnpm install
yarn install
```
或者
@@ -36,7 +36,7 @@ npm install
3. 启动本地服务器。
```bash
pnpm dev
yarn dev
```
或者
@@ -45,7 +45,7 @@ pnpm dev
npm run dev
```
4. 启动完成后会自动打开浏览器访问 [http://localhost:5173](http://localhost:5173)。
4. 启动完成后会自动打开浏览器访问 [http://localhost:8081/view/index.html](http://localhost:8081/view/index.html)。
</details>

View File

@@ -24,7 +24,7 @@ cd my-project
2. Installation dependence.
```bash
pnpm install
yarn install
```
Or
@@ -36,7 +36,7 @@ npm install
3. Start local server.
```bash
pnpm dev
yarn dev
```
Or
@@ -45,7 +45,7 @@ Or
npm run dev
```
4. After the startup is complete, open a browser and visit [http://localhost:5173](http://localhost:5173).
4. After the startup is complete, will automatically open a browser and visit [http://localhost:8081/view/index.html](http://localhost:8081/view/index.html).
</details>
<details>

View File

@@ -2,7 +2,10 @@
<html lang="{{ site.lang | default: "en-US" }}">
<head>
<meta charset="UTF-8">
<script data-ad-client="ca-pub-9857163863537600" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
{% seo %}
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="preload" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700&display=swap" as="style" type="text/css" crossorigin>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#157878">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
@@ -15,7 +18,8 @@
<header class="page-header" role="banner">
<h1 class="project-name">{{ page.title | default: site.title | default: site.github.repository_name }}</h1>
<h2 class="project-tagline">{{ page.description | default: site.description | default: site.github.project_tagline }}</h2>
<a href="/public/" class="btn">RESTART</a>
<a href="/view/" class="btn">RESTART</a>
<a href="/view/test.html" class="btn">Source Version</a>
{% if site.github.is_project_page %}
<a href="{{ site.github.repository_url }}" class="btn">View on GitHub</a>
{% endif %}

4
build.sh Normal file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
# 前端应用存在NPM依赖时的默认编译脚本
npm install
npm run build

Binary file not shown.

Binary file not shown.

View File

@@ -1,8 +1,8 @@
{
"x":0,
"type":"View",
"selectedBox":93,
"selecteID":94,
"selectedBox":1,
"selecteID":12,
"props":{"y":1218,"x":562,"width":1125,"sceneColor":"#000000","sceneBg":"laya/views/view/CyberTheme/CyberMain.png","runtime":"Laya.runtime.ViewBase","height":2436,"anchorY":0.5,"anchorX":0.5},
"nodeParent":-1,
"label":"View",
@@ -548,13 +548,14 @@
"props":{"width":1,"left":0,"height":1,"bottom":0},
"nodeParent":1,
"label":"Box",
"isOpen":false,
"isOpen":true,
"isDirectory":true,
"isAniNode":true,
"hasChild":true,
"compId":85,
"child":[
{
"x":30,
"type":"Box",
"props":{"y":-175,"x":100,"width":160,"var":"btnGithub","runtime":"Laya.runtime.ScaleButton","name":"btnGithub","height":160,"anchorY":0.5,"anchorX":0.5},
"nodeParent":85,
@@ -579,6 +580,7 @@
}]
},
{
"x":30,
"type":"Box",
"props":{"y":-355,"x":100,"width":160,"var":"btnDiscord","runtime":"Laya.runtime.ScaleButton","name":"btnDiscord","height":160,"anchorY":0.5,"anchorX":0.5},
"nodeParent":85,
@@ -609,13 +611,14 @@
"props":{"right":0,"bottom":0},
"nodeParent":1,
"label":"Box",
"isOpen":false,
"isOpen":true,
"isDirectory":true,
"isAniNode":true,
"hasChild":true,
"compId":88,
"child":[
{
"x":30,
"type":"Box",
"props":{"y":-300,"x":-100,"width":110,"runtime":"Laya.runtime.ScaleButton","height":110,"anchorY":0.5,"anchorX":0.5},
"nodeParent":88,
@@ -627,6 +630,7 @@
"compId":90,
"child":[
{
"x":45,
"type":"Box",
"props":{"width":110,"var":"btnSaveLoad","runtime":"Laya.runtime.ColorfulBox","name":"btnSmall","height":110,"centerY":0,"centerX":0,"anchorY":0.5,"anchorX":0.5},
"nodeParent":90,
@@ -638,6 +642,7 @@
"compId":91,
"child":[
{
"x":60,
"type":"Image",
"props":{"width":80,"skin":"images/icons/icon_save.png","height":80,"centerY":0,"centerX":0},
"nodeParent":91,
@@ -652,6 +657,7 @@
}]
},
{
"x":30,
"type":"Box",
"props":{"y":-175,"x":-100,"width":110,"runtime":"Laya.runtime.ScaleButton","height":110,"anchorY":0.5,"anchorX":0.5},
"nodeParent":88,
@@ -663,6 +669,7 @@
"compId":89,
"child":[
{
"x":45,
"type":"Box",
"props":{"width":110,"var":"btnThemes","runtime":"Laya.runtime.ColorfulBox","name":"btnThemes","height":110,"centerY":0,"centerX":0,"anchorY":0.5,"anchorX":0.5},
"nodeParent":89,
@@ -687,32 +694,6 @@
}]
}]
}]
},
{
"x":15,
"type":"Box",
"props":{"x":572,"var":"banner","centerX":0,"bottom":100,"anchorY":1,"anchorX":0.5},
"nodeParent":1,
"label":"Box(banner)",
"isOpen":true,
"isDirectory":true,
"isAniNode":true,
"hasChild":true,
"compId":93,
"child":[
{
"x":30,
"type":"Label",
"props":{"text":"UI_Banner","fontSize":40,"font":"方正像素12","color":"#00fffd"},
"nodeParent":93,
"label":"Label",
"isDirectory":false,
"isAniNode":true,
"hasChild":false,
"compId":94,
"child":[
]
}]
}],
"animations":[
{

View File

@@ -1,8 +1,8 @@
{
"x":0,
"type":"View",
"selectedBox":101,
"selecteID":102,
"selectedBox":99,
"selecteID":100,
"props":{"y":1218,"x":562,"width":1125,"sceneColor":"#000000","runtime":"Laya.runtime.ViewBase","height":2436,"anchorY":0.5,"anchorX":0.5},
"nodeParent":-1,
"label":"View",
@@ -276,32 +276,6 @@
"child":[
]
}]
},
{
"x":15,
"type":"Box",
"props":{"x":562,"var":"banner","centerX":0,"bottom":100,"anchorY":1,"anchorX":0.5},
"nodeParent":1,
"label":"Box(banner)",
"isOpen":true,
"isDirectory":true,
"isAniNode":true,
"hasChild":true,
"compId":101,
"child":[
{
"x":30,
"type":"Label",
"props":{"text":"UI_Banner","name":"title","fontSize":40,"font":"SimHei","color":"#ffffff"},
"nodeParent":101,
"label":"Label(title)",
"isDirectory":false,
"isAniNode":true,
"hasChild":false,
"compId":102,
"child":[
]
}]
}],
"animations":[
{

View File

@@ -1,19 +1,24 @@
{
"name": "life_restart",
"type": "module",
"main": "repl/index.js",
"version": "2.1.0",
"author": "Vick Scarlet <vick@syaro.io>",
"bin": "repl/index.js",
"version": "2.0.0",
"scripts": {
"xlsx2json": "vt transform -d public \"data/**/*.xlsx\"",
"dev": "vite",
"build": "vite build",
"start": "vite preview",
"test": "vitest"
"test": "node test",
"xlsxTransform": "vt transform data",
"xlsx2json": "vt transform -s 4 -d public data/**/*.xlsx",
"dev": "webpack serve --open /view/index.html",
"build": "webpack --mode production"
},
"devDependencies": {
"v-transform": "^2.1.1",
"vite": "^6.2.5",
"vitest": "^3.1.1"
"@babel/core": "^7.15.4",
"@babel/preset-env": "^7.15.4",
"babel-loader": "^8.2.2",
"core-js": "^3.17.2",
"html-webpack-plugin": "^5.5.0",
"v-transform": "^2.0.1",
"webpack": "^5.64.4",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.1.0"
}
}

1059
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
public/chunk/33.007ad.js Normal file

File diff suppressed because one or more lines are too long

1
public/chunk/33.6a18b.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
public/chunk/51.b32bb.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
public/chunk/85.5dbe1.js Normal file

File diff suppressed because one or more lines are too long

1
public/chunk/85.ffdbc.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

71820
public/data/en-us/age.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

13168
public/data/en-us/events.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

71820
public/data/zh-cn/age.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

13168
public/data/zh-cn/events.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,8 @@
<meta http-equiv="Cache-Control" content="no-siteapp"/>
<font-face font-family="方正像素12" src="fonts/方正像素12.ttf"/>
<title>Life Restart</title>
</head>
<body style="background:black">
<!--以下引用了常用类库,如果不使用,可以删除-->
<!--核心包,封装了显示对象渲染,事件,时间管理,时间轴动画,缓动,消息交互,socket本地存储鼠标触摸声音加载颜色滤镜位图字体等-->
@@ -65,8 +67,8 @@
<!-- 物理引擎matter.js -->
<!--自定义的js(src文件夹下)文件自动添加到下面jsfile模块标签里面里js的顺序可以手动修改修改后保留修改的顺序新增加的js会默认依次追加到标签里-->
<!--删除标签ide不会自动添加js文件请谨慎操作-->
<script type="module" src="src/index.js"></script>
</head>
<body style="background:black"></body>
<!--jsfile--startTag-->
<script type="module" src="../src/index.js"></script>
<!--jsfile--endTag-->
</body>
</html>

1
public/index.html Normal file
View File

@@ -0,0 +1 @@
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"><meta name="description" content="やり直すんだ。そして、次はうまくやる。"/><meta name="keywords" content="人生重开模拟器 liferestart life restart remake 人生重来"/><meta name="renderer" content="webkit"/><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="full-screen" content="true"/><meta name="x5-fullscreen" content="true"/><meta name="360-fullscreen" content="true"/><meta name="theme-color" content="#157878"/><meta name="laya" screenorientation="landscape"/><meta http-equiv="expires" content="0"/><meta http-equiv="Cache-Control" content="no-siteapp"/><title>Life Restart</title><script src="libs/laya/min/laya.core.min.js"></script><script src="libs/laya/min/laya.webgl.min.js"></script><script src="libs/laya/min/laya.filter.min.js"></script><script src="libs/laya/min/laya.particle.min.js"></script><script src="libs/laya/min/laya.ui.min.js"></script><script defer="defer" src="chunk/main.76985.js"></script></head><body style="background:black"></body></html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,44 +1,32 @@
import { fileURLToPath } from 'url'
import { dirname } from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
import App from './app.js'
import { readFile, writeFile } from 'fs/promises'
import App from './app.js';
import { readFile, writeFile } from 'fs/promises';
async function main() {
try {
globalThis.localStorage = JSON.parse(
await readFile(__dirname + '/__localStorage.json')
)
globalThis.localStorage = JSON.parse(await readFile('__localStorage.json'));
} catch (e) {
globalThis.localStorage = {}
globalThis.localStorage = {};
}
localStorage.getItem = key =>
localStorage[key] === void 0 ? null : localStorage[key]
localStorage.setItem = (key, value) => (localStorage[key] = value)
localStorage.getItem = key => localStorage[key]===void 0? null: localStorage[key];
localStorage.setItem = (key, value) => (localStorage[key] = value);
globalThis.dumpLocalStorage = async () =>
await writeFile(
__dirname + '/__localStorage.json',
JSON.stringify(global.localStorage)
)
globalThis.dumpLocalStorage = async ()=>await writeFile('__localStorage.json', JSON.stringify( global.localStorage))
const app = new App()
const app = new App();
app.io(
repl => process.stdin.on('data', data => repl(data.toString().trim())),
(data, isRepl) => process.stdout.write(`${data}${isRepl ? '\n>' : ''}`),
code => process.exit(code)
repl => process.stdin.on('data', data=>repl(data.toString().trim())),
(data, isRepl) => process.stdout.write(`${data}${isRepl?'\n>':''}`),
code=>process.exit(code)
)
await app.initial()
await app.initial();
}
main()
main();
// process.stdin.setRawMode(true);
// process.openStdin().on('keypress', function (chunk, key) {
// process.stdout.write('Get Chunk: ' + chunk + '\n');
// if (key && key.ctrl && key.name == 'c') process.exit();
// });
// });

View File

@@ -7,21 +7,21 @@ import UIManager from './ui/uiManager.js';
import * as utils from './functions/util.js';
globalThis.UIManager =
globalThis.UI =
UIManager;
globalThis.UI =
UIManager;
globalThis.$_ = utils;
globalThis.goto = async tag => {
let url;
switch (tag) {
switch(tag) {
case 'github': url = 'https://github.com/VickScarlet/lifeRestart'; break;
case 'discord': url = 'https://discord.gg/U3qrf49NMQ'; break;
case 'sponsor_afd': url = 'https://afdian.com/a/LifeRestart'; break;
case 'sponsor_afd': url = 'https://afdian.net/@LifeRestart'; break;
case 'sponsor_ddf': url = 'https://dun.mianbaoduo.com/@vickscarlet'; break;
}
try {
if (Laya.Browser.onIOS) {
if(Laya.Browser.onIOS) {
window.location.href = url;
} else {
window.open(url, '_blank');
@@ -30,8 +30,8 @@ globalThis.goto = async tag => {
console.error(error);
}
}
class App {
constructor() {
class App{
constructor(){
this.name = 'lifeRestart';
this.version = '2.0.0';
console.log(`${this.name} ${this.version}`);
@@ -50,10 +50,10 @@ class App {
//class laya.webgl.text.CharSegment
class CharSegment {
constructor() {
this._sourceStr = null;
this._sourceStr=null;
}
textToSpit(str) {
this._sourceStr = str;
this._sourceStr=str;
var texLen = str.length;
var idx = -1;
this._words = [];
@@ -67,18 +67,18 @@ class App {
}
}
}
getChar(i) {
getChar(i){
return this._words;
}
getCharCode(i) {
getCharCode(i){
return this._words[i].codePointAt(0);
}
length() {
length(){
return this._words.length;
}
}
Laya.class(CharSegment, 'laya.webgl.text.CharSegment');
Laya.imps(CharSegment.prototype, { "laya.webgl.text.ICharSegment": true })
Laya.class(CharSegment,'laya.webgl.text.CharSegment');
Laya.imps(CharSegment.prototype,{"laya.webgl.text.ICharSegment":true})
// Laya.init(1125, 2436, Laya.WebGL);
@@ -103,15 +103,15 @@ class App {
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
const screenRatio = screenWidth / screenHeight;
if (screenRatio > designRatio) {
if(screenRatio > designRatio) {
return [
Math.min(screenWidth * designHeight / screenHeight, maxWidth),
Math.min(screenWidth*designHeight/screenHeight, maxWidth),
designHeight
]
} else {
return [
designWidth,
Math.min(screenHeight * designWidth / screenWidth, maxHeight)
Math.min(screenHeight*designWidth/screenWidth, maxHeight)
]
}
}
@@ -121,7 +121,7 @@ class App {
}
async #setLanguage(language) {
switch (language) {
switch(language) {
case App.languages['en-us']:
case App.languages['zh-cn']:
this.#language = language;
@@ -131,23 +131,23 @@ class App {
break;
}
globalThis.$lang =
Laya.Text.langPacks =
Laya.Text.langPacks =
(await import(`./i18n/${this.#language}.js`)).default;
}
resigterEvent() {
$$on('achievement', achievement => {
$ui.popup(UI.popups.ACHIEVEMENT, { achievement });
$ui.popup(UI.popups.ACHIEVEMENT, {achievement});
})
$$on('message', ([message, ...args]) => {
if (Array.isArray(message)) {
message = message.map(([m, ...a]) => $_.format($lang[m], ...a)).join('\n');
if(Array.isArray(message)) {
message = message.map(([m, ...a]) => $_.format($lang[m], ...a)) .join('\n');
} else {
message = $_.format(
$lang[message], ...args
);
}
$ui.popup(UI.popups.MESSAGE, { message });
$ui.popup(UI.popups.MESSAGE, {message});
})
}
@@ -159,7 +159,7 @@ class App {
this.#initLaya();
globalThis.$ui = UIManager.getInstance();
if (theme == 'default') {
if(theme=='default') {
theme = localStorage.getItem('theme') || 'default';
}
@@ -168,8 +168,8 @@ class App {
await $ui.setLoading(UI.pages.LOADING);
await $ui.switchView(UI.pages.LOADING);
await core.initial(
dataSet => Laya.promises.loader.load(`data/${this.#language}/${dataSet}.json`, null, Laya.Loader.JSON),
dataSet => Laya.promises.loader.load(`data/${dataSet}.json`, null, Laya.Loader.JSON),
dataSet=>Laya.promises.loader.load(`data/${this.#language}/${dataSet}.json`, null, Laya.Loader.JSON),
dataSet=>Laya.promises.loader.load(`data/${dataSet}.json`, null, Laya.Loader.JSON),
);
await $ui.switchView(UI.pages.MAIN);

View File

@@ -43,7 +43,7 @@ function parseCondition(condition) {
return conditions;
}
export function checkCondition(property, condition) {
function checkCondition(property, condition) {
const conditions = parseCondition(condition);
return checkParsedConditions(property, conditions);
}
@@ -113,7 +113,7 @@ function checkProp(property, condition) {
}
}
export function extractMaxTriggers(condition) {
function extractMaxTriggers(condition) {
// Assuming only age related talents can be triggered multiple times.
const RE_AGE_CONDITION = /AGE\?\[([0-9\,]+)\]/;
const match_object = RE_AGE_CONDITION.exec(condition);
@@ -124,4 +124,6 @@ export function extractMaxTriggers(condition) {
const age_list = match_object[1].split(",");
return age_list.length;
}
}
export { checkCondition, extractMaxTriggers };

View File

@@ -1,103 +0,0 @@
import { expect, test, describe } from 'vitest'
import { checkCondition } from './condition'
function withProp(prop) {
const p = {
get(key) {
return prop[key]
},
}
return condition => checkCondition(p, condition)
}
describe('condition', () => {
const check = withProp({
n1: 0,
n2: -10,
n3: 10,
nl1: [1, 2, 3],
nl2: [0],
nl3: [],
})
test('gt(>)', () => {
expect(check('n3>11')).toBe(false)
expect(check('n3>10')).toBe(false)
expect(check('n3>9')).toBe(true)
})
test('gte(>=)', () => {
expect(check('n3>=11')).toBe(false)
expect(check('n3>=10')).toBe(true)
expect(check('n3>=9')).toBe(true)
})
test('lt(<)', () => {
expect(check('n3<9')).toBe(false)
expect(check('n3<10')).toBe(false)
expect(check('n3<11')).toBe(true)
})
test('lte(<=)', () => {
expect(check('n3<=9')).toBe(false)
expect(check('n3<=10')).toBe(true)
expect(check('n3<=11')).toBe(true)
})
test('eq(=)', () => {
expect(check('n3=9')).toBe(false)
expect(check('n3=10')).toBe(true)
expect(check('n3=11')).toBe(false)
expect(check('nl1=0')).toBe(false)
expect(check('nl1=1')).toBe(true)
expect(check('nl1=2')).toBe(true)
expect(check('nl1=3')).toBe(true)
})
test('ne(!=)', () => {
expect(check('n3!=9')).toBe(true)
expect(check('n3!=10')).toBe(false)
expect(check('n3!=11')).toBe(true)
expect(check('nl1!=0')).toBe(true)
expect(check('nl1!=1')).toBe(false)
expect(check('nl1!=2')).toBe(false)
expect(check('nl1!=3')).toBe(false)
})
test('in(?)', () => {
expect(check('n3?[1,2,3]')).toBe(false)
expect(check('n3?[10,11,12]')).toBe(true)
expect(check('nl1?[0,1]')).toBe(true)
expect(check('nl2?[1,2,3]')).toBe(false)
expect(check('nl3?[1,2,3]')).toBe(false)
expect(check('nl2?[]')).toBe(false)
expect(check('nl3?[]')).toBe(false)
})
test('notin(!)', () => {
expect(check('n3![1,2,3]')).toBe(true)
expect(check('n3![10,11,12]')).toBe(false)
expect(check('nl1![0,1]')).toBe(false)
expect(check('nl2![1,2,3]')).toBe(true)
expect(check('nl3![1,2,3]')).toBe(true)
expect(check('nl2![]')).toBe(true)
expect(check('nl3![]')).toBe(true)
})
test('and(&)', () => {
expect(check('n1>=0&n2<0')).toBe(true)
expect(check('n2>0&n3>0')).toBe(false)
expect(check('n2<0&n3<0')).toBe(false)
expect(check('n2<0&n3>0')).toBe(true)
expect(check('n1=0&n2<0&n3>0')).toBe(true)
expect(check('n1=0&n2>0&n3>0')).toBe(false)
})
test('or(|)', () => {
expect(check('n1>=0|n2<0')).toBe(true)
expect(check('n2>0|n3>0')).toBe(true)
expect(check('n2<0|n3<0')).toBe(true)
expect(check('n2<0|n3>0')).toBe(true)
expect(check('n2>0|n3<0')).toBe(false)
expect(check('n1=0|n2<0|n3>0')).toBe(true)
expect(check('n1=0|n2>0|n3>0')).toBe(true)
expect(check('n1!=0|n2>0|n3<0')).toBe(false)
})
test('mix', () => {
expect(check('(n1=0|n2<0|n3>0)&(n1=0|n2>0|n3>0)')).toBe(true)
expect(check('(n1=0|n2<0|n3>0)&(n1!=0|n2>0|n3<0)')).toBe(false)
expect(check('n1=0|n2<0|n3>0&n1!=0|n2>0|n3<0')).toBe(true)
expect(check('(n1>0|n1?[-10,0])&(n2>0|n3![0,1])')).toBe(true)
expect(check('(n1>0&n1?[-10,0])|(n2<0&n3![0,1])')).toBe(true)
})
})

0
src/functions/unique.js Normal file
View File

View File

@@ -31,7 +31,6 @@ export default ({
UI_Thanks: 'Thx',
UI_Achievement: 'Achv',
UI_Cyber_Theme_Art_Design: 'UI Design by 晰晰',
UI_Banner: '作者的新作《纸上谈亲》已上线小程序\n微信/抖音搜索“纸上谈亲”即可游玩~',
UI_Title_Talent: 'Talent Draw',
UI_Talent_Draw: '!10 Pulls!',

View File

@@ -33,7 +33,6 @@ export default ({
UI_Thanks: '感谢',
UI_Achievement: '成就',
UI_Cyber_Theme_Art_Design: 'UI 设计 by 晰晰',
UI_Banner: '作者的新作《纸上谈亲》已上线小程序\n微信/抖音搜索“纸上谈亲”即可游玩~',
UI_Title_Talent: '天赋抽卡',
UI_Talent_Draw: '10连抽',

View File

@@ -54,7 +54,7 @@ class Life {
this.#specialThanks = specialThanks;
const total = {
[this.PropertyTypes.TACHV]: this.#achievement.initial({achievements}),
[this.PropertyTypes.TACEV]: this.#achievement.initial({achievements}),
[this.PropertyTypes.TEVT]: this.#event.initial({events}),
[this.PropertyTypes.TTLT]: this.#talent.initial({talents}),
};

File diff suppressed because one or more lines are too long

View File

@@ -30,7 +30,6 @@ export default class CyberMain extends ui.view.CyberTheme.CyberMainUI {
}
init() {
this.banner.visible =
this.btnDiscord.visible =
this.btnAchievement.visible =
this.btnThanks.visible = !!core.times;

View File

@@ -17,7 +17,6 @@ export default class Main extends ui.view.DefaultTheme.MainUI {
}
init() {
this.banner.visible =
this.btnDiscord.visible =
this.btnAchievement.visible =
this.btnThanks.visible = !!core.times;

View File

@@ -10,32 +10,32 @@ const pages = {
THEMES: 'THEMES',
SAVELOAD: 'SAVELOAD',
MODE: 'MODE',
CELEBRITY: 'CELEBRITY',
}
CELEBRITY: 'CELEBRITY'
};
const popups = {
ACHIEVEMENT: 'POPUP_ACHIEVEMENT',
MESSAGE: 'POPUP_MESSAGE',
}
};
const cyber = {
pages: {
[pages.LOADING]: 'loading',
[pages.MAIN]: 'cyber/main',
[pages.TALENT]: 'cyber/talent',
[pages.PROPERTY]: 'cyber/property',
[pages.TRAJECTORY]: 'cyber/trajectory',
[pages.SUMMARY]: 'cyber/summary',
[pages.ACHIEVEMENT]: 'cyber/achievement',
[pages.THANKS]: 'default/thanks',
[pages.LOADING]: "loading",
[pages.MAIN]: "cyber/main",
[pages.TALENT]: "cyber/talent",
[pages.PROPERTY]: "cyber/property",
[pages.TRAJECTORY]: "cyber/trajectory",
[pages.SUMMARY]: "cyber/summary",
[pages.ACHIEVEMENT]: "cyber/achievement",
[pages.THANKS]: "default/thanks",
[pages.THEMES]: 'themes',
[pages.SAVELOAD]: 'saveload',
[pages.MODE]: 'cyber/mode',
[pages.CELEBRITY]: 'cyber/celebrity',
},
popups: {
[popups.ACHIEVEMENT]: 'cyber/popup/achievementPopup',
[popups.MESSAGE]: 'message',
[popups.ACHIEVEMENT]: "cyber/popup/achievementPopup",
[popups.MESSAGE]: "message",
},
configs: {
bgColor: '#04131f',
@@ -47,8 +47,18 @@ const cyber = {
hoverStroke: '#ffa500',
},
defaultFontColor: '#cccccc',
grade: ['#cccccc', '#55fffe', '#b17cff', '#ffce45'],
filter: ['#ccccccff', '#55fffeff', '#b17cffff', '#ffce45ff'],
grade: [
'#cccccc',
'#55fffe',
'#b17cff',
'#ffce45',
],
filter: [
'#ccccccff',
'#55fffeff',
'#b17cffff',
'#ffce45ff',
],
gradeBlk: [
{
visible: false,
@@ -68,7 +78,7 @@ const cyber = {
hoverColor: '#ffce45',
visible: true,
},
],
]
},
pages: {
[pages.MAIN]: {
@@ -87,7 +97,7 @@ const cyber = {
lineWidth: 0,
radius: 100,
},
},
}
},
[pages.THANKS]: {
vars: {
@@ -137,7 +147,7 @@ const cyber = {
hoverLabel: '#ffffff',
radius: 80,
},
},
}
},
[pages.SAVELOAD]: {
vars: {
@@ -174,31 +184,31 @@ const cyber = {
radius: 80,
defaultLabel: '#ffffff',
hoverLabel: '#ffffff',
},
},
}
}
},
},
},
}
}
}
const dark = {
pages: {
[pages.LOADING]: 'loading',
[pages.MAIN]: 'default/main',
[pages.TALENT]: 'default/talent',
[pages.PROPERTY]: 'default/property',
[pages.TRAJECTORY]: 'default/trajectory',
[pages.SUMMARY]: 'default/summary',
[pages.ACHIEVEMENT]: 'default/achievement',
[pages.THANKS]: 'default/thanks',
[pages.LOADING]: "loading",
[pages.MAIN]: "default/main",
[pages.TALENT]: "default/talent",
[pages.PROPERTY]: "default/property",
[pages.TRAJECTORY]: "default/trajectory",
[pages.SUMMARY]: "default/summary",
[pages.ACHIEVEMENT]: "default/achievement",
[pages.THANKS]: "default/thanks",
[pages.THEMES]: 'themes',
[pages.SAVELOAD]: 'saveload',
[pages.MODE]: 'default/mode',
[pages.CELEBRITY]: 'default/celebrity',
},
popups: {
[popups.ACHIEVEMENT]: 'default/popup/achievementPopup',
[popups.MESSAGE]: 'message',
[popups.ACHIEVEMENT]: "default/popup/achievementPopup",
[popups.MESSAGE]: "message",
},
configs: {
bgColor: '#222831',
@@ -238,8 +248,18 @@ const dark = {
hoverColor: '#ffc500',
hoverStroke: '#ffa500',
},
grade: ['#cccccc', '#55fffe', '#b17cff', '#ffce45'],
filter: ['#ccccccff', '#55fffeff', '#b17cffff', '#ffce45ff'],
grade: [
'#cccccc',
'#55fffe',
'#b17cff',
'#ffce45',
],
filter: [
'#ccccccff',
'#55fffeff',
'#b17cffff',
'#ffce45ff',
],
card: [
{
normal: {
@@ -261,7 +281,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 4,
},
}
},
{
normal: {
@@ -283,7 +303,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 4,
},
}
},
{
normal: {
@@ -305,7 +325,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 4,
},
}
},
{
normal: {
@@ -327,8 +347,8 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 4,
},
},
}
}
],
summary: [
{
@@ -340,8 +360,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 2,
radius: 0,
},
{
},{
defaultColor: '#6495ed',
defaultStroke: '#f8f8f8',
defaultLabel: '#eeeeee',
@@ -350,8 +369,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 2,
radius: 0,
},
{
},{
defaultColor: '#e2a7ff',
defaultStroke: '#f8f8f8',
defaultLabel: '#eeeeee',
@@ -370,7 +388,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 2,
radius: 0,
},
}
],
achievement: [
{
@@ -382,8 +400,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
},
{
},{
defaultColor: '#6495ed',
defaultStroke: '#f8f8f8',
defaultLabel: '#eeeeee',
@@ -392,8 +409,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
},
{
},{
defaultColor: '#e2a7ff',
defaultStroke: '#f8f8f8',
defaultLabel: '#eeeeee',
@@ -412,7 +428,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
},
}
],
characterItem: {
name: {
@@ -472,7 +488,7 @@ const dark = {
},
font_default: {
color: '#eeeeee',
},
}
},
pages: {
[pages.MAIN]: {
@@ -496,14 +512,14 @@ const dark = {
names: {
title: 'title',
btnSmall: 'btn_small',
},
}
},
[pages.TALENT]: {
vars: {
btnDrawCard: 'btn_main',
btnNext: 'btn_main',
title: 'title',
},
}
},
[pages.PROPERTY]: {
vars: {
@@ -514,9 +530,9 @@ const dark = {
names: {
font_default: 'font_default',
property: {
colorFilter: '#eeeeeeff',
},
},
colorFilter: '#eeeeeeff'
}
}
},
[pages.TRAJECTORY]: {
vars: {
@@ -532,8 +548,8 @@ const dark = {
radius: 4,
},
boxSpeed: {
colorFilter: '#ffffffff',
},
colorFilter: '#ffffffff'
}
},
names: {
propertyBox: {
@@ -555,8 +571,8 @@ const dark = {
hoverLabel: '#222831',
lineWidth: 0,
radius: 4,
},
},
}
}
},
[pages.SUMMARY]: {
vars: {
@@ -565,7 +581,7 @@ const dark = {
},
names: {
font_default: 'font_default',
},
}
},
[pages.ACHIEVEMENT]: {
vars: {
@@ -575,7 +591,7 @@ const dark = {
names: {
font_default: 'font_default',
title: 'title',
},
}
},
[pages.THANKS]: {
vars: {
@@ -616,7 +632,7 @@ const dark = {
hoverLabel: '#ffffff',
radius: 80,
},
},
}
},
[pages.SAVELOAD]: {
vars: {
@@ -653,20 +669,20 @@ const dark = {
radius: 80,
defaultLabel: '#ffffff',
hoverLabel: '#ffffff',
},
},
}
}
},
[pages.MODE]: {
names: {
font_default: 'font_default',
btn: 'btn_main',
},
}
},
[pages.CELEBRITY]: {
vars: {
btnRetry: 'btn_main',
btnNext: 'btn_main2',
},
}
},
},
popups: {
@@ -677,31 +693,31 @@ const dark = {
defaultStroke: '#84ff55',
hoverColor: '#292a28',
hoverStroke: '#84ff55',
},
},
},
},
},
}
}
}
}
}
}
const light = {
pages: {
[pages.LOADING]: 'loading',
[pages.MAIN]: 'default/main',
[pages.TALENT]: 'default/talent',
[pages.PROPERTY]: 'default/property',
[pages.TRAJECTORY]: 'default/trajectory',
[pages.SUMMARY]: 'default/summary',
[pages.ACHIEVEMENT]: 'default/achievement',
[pages.THANKS]: 'default/thanks',
[pages.LOADING]: "loading",
[pages.MAIN]: "default/main",
[pages.TALENT]: "default/talent",
[pages.PROPERTY]: "default/property",
[pages.TRAJECTORY]: "default/trajectory",
[pages.SUMMARY]: "default/summary",
[pages.ACHIEVEMENT]: "default/achievement",
[pages.THANKS]: "default/thanks",
[pages.THEMES]: 'themes',
[pages.SAVELOAD]: 'saveload',
[pages.MODE]: 'default/mode',
[pages.CELEBRITY]: 'default/celebrity',
},
popups: {
[popups.ACHIEVEMENT]: 'default/popup/achievementPopup',
[popups.MESSAGE]: 'message',
[popups.ACHIEVEMENT]: "default/popup/achievementPopup",
[popups.MESSAGE]: "message",
},
configs: {
bgColor: '#ffffff',
@@ -741,8 +757,18 @@ const light = {
hoverColor: '#ffc500',
hoverStroke: '#ffa500',
},
grade: ['#000000', '#55fffe', '#b17cff', '#ffce45'],
filter: ['#000000ff', '#55fffeff', '#b17cffff', '#ffce45ff'],
grade: [
'#000000',
'#55fffe',
'#b17cff',
'#ffce45',
],
filter: [
'#000000ff',
'#55fffeff',
'#b17cffff',
'#ffce45ff',
],
card: [
{
normal: {
@@ -764,7 +790,7 @@ const light = {
hoverLabel: '#ffffff',
lineWidth: 4,
radius: 4,
},
}
},
{
normal: {
@@ -786,7 +812,7 @@ const light = {
hoverLabel: '#ffffff',
lineWidth: 4,
radius: 4,
},
}
},
{
normal: {
@@ -808,7 +834,7 @@ const light = {
hoverLabel: '#ffffff',
lineWidth: 4,
radius: 4,
},
}
},
{
normal: {
@@ -830,8 +856,8 @@ const light = {
hoverLabel: '#ffffff',
lineWidth: 4,
radius: 4,
},
},
}
}
],
summary: [
{
@@ -843,8 +869,7 @@ const light = {
hoverLabel: '#ffffff',
lineWidth: 4,
radius: 4,
},
{
},{
defaultColor: '#6495ed',
defaultStroke: '#f8f8f8',
defaultLabel: '#ffffff',
@@ -853,8 +878,7 @@ const light = {
hoverLabel: '#666666',
lineWidth: 4,
radius: 4,
},
{
},{
defaultColor: '#e2a7ff',
defaultStroke: '#f8f8f8',
defaultLabel: '#ffffff',
@@ -863,8 +887,7 @@ const light = {
hoverLabel: '#666666',
lineWidth: 4,
radius: 4,
},
{
},{
defaultColor: '#ffa07a',
defaultStroke: '#f8f8f8',
defaultLabel: '#ffffff',
@@ -885,8 +908,7 @@ const light = {
hoverLabel: '#efefef',
lineWidth: 4,
radius: 0,
},
{
},{
defaultColor: '#6495ed',
defaultStroke: '#cccccc',
defaultLabel: '#eeeeee',
@@ -895,8 +917,7 @@ const light = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
},
{
},{
defaultColor: '#e2a7ff',
defaultStroke: '#cccccc',
defaultLabel: '#eeeeee',
@@ -905,8 +926,7 @@ const light = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
},
{
},{
defaultColor: '#ffa07a',
defaultStroke: '#cccccc',
defaultLabel: '#eeeeee',
@@ -915,7 +935,7 @@ const light = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
},
}
],
characterItem: {
name: {
@@ -975,7 +995,7 @@ const light = {
},
font_default: {
color: '#000000',
},
}
},
pages: {
[pages.MAIN]: {
@@ -999,14 +1019,14 @@ const light = {
names: {
title: 'title',
btnSmall: 'btn_small',
},
}
},
[pages.TALENT]: {
vars: {
btnDrawCard: 'btn_main',
btnNext: 'btn_main',
title: 'title',
},
}
},
[pages.PROPERTY]: {
vars: {
@@ -1017,9 +1037,9 @@ const light = {
names: {
font_default: 'font_default',
property: {
colorFilter: '#000000ff',
},
},
colorFilter: '#000000ff'
}
}
},
[pages.TRAJECTORY]: {
vars: {
@@ -1035,8 +1055,8 @@ const light = {
radius: 4,
},
boxSpeed: {
colorFilter: '#666666ff',
},
colorFilter: '#666666ff'
}
},
names: {
propertyBox: {
@@ -1058,8 +1078,8 @@ const light = {
hoverLabel: '#222831',
lineWidth: 0,
radius: 4,
},
},
}
}
},
[pages.SUMMARY]: {
vars: {
@@ -1068,7 +1088,7 @@ const light = {
},
names: {
font_default: 'font_default',
},
}
},
[pages.ACHIEVEMENT]: {
vars: {
@@ -1078,7 +1098,7 @@ const light = {
names: {
font_default: 'font_default',
title: 'title',
},
}
},
[pages.THANKS]: {
vars: {
@@ -1100,7 +1120,7 @@ const light = {
hoverStroke: '#dc76a9',
hoverLabel: '#ffffff',
radius: 4,
},
}
},
},
[pages.THEMES]: {
@@ -1119,7 +1139,7 @@ const light = {
hoverLabel: '#ffffff',
radius: 80,
},
},
}
},
[pages.SAVELOAD]: {
vars: {
@@ -1156,20 +1176,20 @@ const light = {
radius: 80,
defaultLabel: '#ffffff',
hoverLabel: '#ffffff',
},
},
}
}
},
[pages.MODE]: {
names: {
font_default: 'font_default',
btn: 'btn_main',
},
}
},
[pages.CELEBRITY]: {
vars: {
btnRetry: 'btn_main',
btnNext: 'btn_main2',
},
}
},
},
popups: {
@@ -1181,13 +1201,14 @@ const light = {
hoverColor: '#ffffff',
hoverStroke: '#84ff55',
lineWidth: 1,
},
},
},
},
},
}
}
}
}
}
}
const themes = { default: dark, cyber, dark, light }
const themes = { default: dark, cyber, dark, light };
export default { themes, pages, popups }
export default { themes, pages, popups };

View File

@@ -1,397 +1,360 @@
import Views from './views.js'
import Views from './themes/views.js';
export default class UIManager {
constructor(stage) {
UIManager.#views = Views
UIManager.#views = Views;
if (!stage) {
stage = Laya.stage
if(!stage) {
stage = Laya.stage;
}
this.#stage = stage
this.#stage = stage;
stage.addChild(this.#viewLayer)
this.#viewLayer.zOrder = 1
stage.addChild(this.#dialogLayer)
this.#dialogLayer.zOrder = 2
stage.addChild(this.#popupLayer)
this.#popupLayer.zOrder = 3
stage.addChild(this.#viewLayer);
this.#viewLayer.zOrder = 1;
stage.addChild(this.#dialogLayer);
this.#dialogLayer.zOrder = 2;
stage.addChild(this.#popupLayer);
this.#popupLayer.zOrder = 3;
this.#viewLayer.top =
this.#viewLayer.bottom =
this.#viewLayer.left =
this.#viewLayer.right =
this.#dialogLayer.top =
this.#dialogLayer.bottom =
this.#dialogLayer.left =
this.#dialogLayer.right =
this.#popupLayer.top =
this.#popupLayer.bottom =
this.#popupLayer.left =
this.#popupLayer.right =
this.#dialogMask.top =
this.#dialogMask.bottom =
this.#dialogMask.left =
this.#dialogMask.right =
0
this.#dialogMask.graphics.drawRect(0, 0, 5000, 5000, '#000000')
this.#dialogMask.alpha = 0.4
this.#dialogMask.on(Laya.Event.CLICK, this, () => {
this.#dialogStack[this.#dialogStack.length - 1]?.close?.()
this.#viewLayer.bottom =
this.#viewLayer.left =
this.#viewLayer.right =
this.#dialogLayer.top =
this.#dialogLayer.bottom =
this.#dialogLayer.left =
this.#dialogLayer.right =
this.#popupLayer.top =
this.#popupLayer.bottom =
this.#popupLayer.left =
this.#popupLayer.right =
this.#dialogMask.top =
this.#dialogMask.bottom =
this.#dialogMask.left =
this.#dialogMask.right = 0;
this.#dialogMask.graphics.drawRect(0, 0, 5000, 5000, '#000000');
this.#dialogMask.alpha = 0.4;
this.#dialogMask.on(Laya.Event.CLICK, this, ()=>{
this.#dialogStack[this.#dialogStack.length - 1]?.close?.();
})
}
static #instance = {}
static #views
#stage
#loading
#currentView
#viewLayer = new Laya.Panel()
#dialogLayer = new Laya.Panel()
#popupLayer = new Laya.Panel()
#dialogMask = new Laya.Sprite()
#viewMap = new Map()
#class = new Map()
#dialogStack = []
static #instance = {};
static #views;
#stage;
#loading;
#currentView;
#viewLayer = new Laya.Panel();
#dialogLayer = new Laya.Panel();
#popupLayer = new Laya.Panel();
#dialogMask = new Laya.Sprite();
#viewMap = new Map();
#class = new Map();
#dialogStack = [];
static get inst() {
return this.getInstance()
return this.getInstance();
}
static getInstance(name = 'default') {
return this.#instance[name] || (this.#instance[name] = new UIManager())
static getInstance(name="default") {
return this.#instance[name] || (this.#instance[name] = new UIManager());
}
static get pages() {
return this.#views.pages
return this.#views.pages;
}
static get popups() {
return this.#views.popups
return this.#views.popups;
}
static theme(theme, prop) {
return this.#views.themes[theme][prop]
return this.#views.themes[theme][prop];
}
async setLoading(loading) {
const className = this.#pages[loading]
const view = await this.getView(className, null, null, loading)
view.top = view.bottom = view.left = view.right = 0
view.zOrder = 4
this.#loading = view
const className = this.#pages[loading];
const view = await this.getView(className, null, null, loading);
view.top = view.bottom = view.left = view.right = 0;
view.zOrder = 4;
this.#loading = view;
}
async switchView(viewName, args, actions) {
const className = this.#pages[viewName]
const className = this.#pages[viewName];
// get view instance
const view = await this.getView(
className,
args,
actions?.load,
viewName,
'pages'
)
const view = await this.getView(className, args, actions?.load, viewName, 'pages');
view.top = view.bottom = view.left = view.right = 0
view.top = view.bottom = view.left = view.right = 0;
// close current view
this.clearAllDialog()
await this.#currentView?.__close?.(view)
await this.#currentView?.close?.(view)
this.#viewLayer.removeChildren()
this.clearAllDialog();
await this.#currentView?.__close?.(view);
await this.#currentView?.close?.(view);
this.#viewLayer.removeChildren();
// open new view
await view.init?.(args)
await view.init?.(args);
this.#currentView = view
this.#viewLayer.addChild(view)
this.#currentView = view;
this.#viewLayer.addChild(view);
view.__close = actions?.close
await actions?.open?.(view)
await view.show?.()
view.__close = actions?.close;
await actions?.open?.(view);
await view.show?.();
}
async getView(className, args, preload, viewName, type) {
// check if view is already loaded
let view = await this.#viewMap.get(className)
let view = await this.#viewMap.get(className);
let timeout
if (this.#loading) {
let timeout;
if(this.#loading) {
timeout = setTimeout(
() => this.#stage.addChild(this.#loading),
()=>this.#stage.addChild(this.#loading),
3000
)
);
}
const onProgress = this.#loading?.onProgress
const onProgress = this.#loading?.onProgress;
if (!view) {
if(!view) {
// load view
const ViewClass = await this.loadView(className)
const resourceList = await ViewClass.load?.(args)
const scanedResourceList = this.#loading
? this.scanResource(ViewClass.uiView)
: []
if (preload) {
preload = [].concat(preload).concat(scanedResourceList)
const ViewClass = await this.loadView(className);
const resourceList = await ViewClass.load?.(args);
const scanedResourceList = this.#loading? this.scanResource(ViewClass.uiView): [];
if(preload) {
preload = [].concat(preload).concat(scanedResourceList);
} else {
preload = scanedResourceList
preload = scanedResourceList;
}
await this.loadRes(resourceList, preload, onProgress)
await this.loadRes(resourceList, preload, onProgress);
// create view
view = new ViewClass()
view = new ViewClass();
// add view to map
this.#viewMap.set(className, view)
this.#viewMap.set(className, view);
} else {
// load resource
const resourceList = await view.constructor.load?.(args)
await this.loadRes(resourceList, preload, onProgress)
const resourceList = await view.constructor.load?.(args);
await this.loadRes(resourceList, preload, onProgress);
}
if (timeout) clearTimeout(timeout)
this.#loading?.removeSelf()
if(timeout) clearTimeout(timeout);
this.#loading?.removeSelf();
this.#config(view, viewName, type)
this.#config(view, viewName, type);
// return view
return view
return view;
}
async loadView(className) {
// load view
if (this.#class.has(className)) return this.#class.get(className)
const views = import.meta.glob('./themes/**/*.js')
const view = (await views[`./themes/${className}.js`]()).default
this.#class.set(className, view)
return view
if(this.#class.has(className)) return this.#class.get(className);
const c = (await import(`./themes/${className}.js`)).default;
this.#class.set(className, c);
return c;
}
async loadRes(resourceList, preload, onProgress) {
const cnt = (resourceList?.length || 0) + (preload?.length || 0)
if (resourceList && resourceList.length) {
const s = resourceList.length / cnt
await Laya.promises.loader.load(
resourceList,
Laya.Handler.create(null, prg => onProgress?.(prg * s))
)
const cnt = (resourceList?.length || 0)
+(preload?.length || 0);
if(resourceList && resourceList.length) {
const s = resourceList.length / cnt;
await Laya.promises.loader.load(resourceList, Laya.Handler.create(null, prg=>onProgress?.(prg*s)));
}
if (preload && preload.length) {
const s = 1 - preload.length / cnt
const l = preload.length / cnt
await Laya.promises.loader.load(
preload,
Laya.Handler.create(null, prg => onProgress?.(prg * l + s))
)
if(preload && preload.length) {
const s = 1 - preload.length / cnt;
const l = preload.length / cnt;
await Laya.promises.loader.load(preload, Laya.Handler.create(null, prg=>onProgress?.(prg*l+s)));
}
}
#showDialogStack() {
if (this.#dialogStack.length == 0) {
this.#dialogLayer.visible = false
return
if(this.#dialogStack.length == 0) {
this.#dialogLayer.visible = false;
return;
}
this.#dialogLayer.visible = true
this.#dialogStack.forEach((dialog, i) => {
this.#dialogLayer.addChild(dialog)
dialog.zOrder = i
this.#dialogLayer.visible = true;
this.#dialogStack.forEach((dialog, i)=>{
this.#dialogLayer.addChild(dialog);
dialog.zOrder = i;
})
this.#dialogLayer.addChild(this.#dialogMask)
const l = this.#dialogStack.length
this.#dialogMask.zOrder = l - 1
this.#dialogStack[l - 1].zOrder = l
this.#dialogLayer.addChild(this.#dialogMask);
const l = this.#dialogStack.length;
this.#dialogMask.zOrder = l -1;
this.#dialogStack[l -1].zOrder = l;
}
async showDialog(dialogName, args, actions) {
const className = this.#pages[dialogName]
const dialog = await this.getView(
className,
args,
actions?.load,
dialogName,
'pages'
)
const className = this.#pages[dialogName];
const dialog = await this.getView(className, args, actions?.load, dialogName, 'pages');
const index = this.#dialogStack.indexOf(dialog)
if (index != -1) {
this.#dialogStack.splice(index, 1)
const index = this.#dialogStack.indexOf(dialog);
if(index != -1) {
this.#dialogStack.splice(index, 1);
}
this.#dialogStack.push(dialog)
dialog.init?.(args)
dialog.centerX = dialog.centerY = 0
this.#showDialogStack()
this.#dialogStack.push(dialog);
dialog.init?.(args);
dialog.centerX = dialog.centerY = 0;
this.#showDialogStack();
const open =
actions?.open ||
(async () => {
dialog.scaleX = 0
dialog.scaleY = 0
await Laya.promises.Tween.to(
dialog,
{ scaleX: 1, scaleY: 1 },
300,
Laya.Ease.backOut
)
})
await open(dialog)
dialog.mouseThrough = true
dialog.mouseEnabled = true
dialog.close = async () => {
if (actions?.close) {
await actions.close()
const open = actions?.open || (async () => {
dialog.scaleX = 0;
dialog.scaleY = 0;
await Laya.promises.Tween.to(dialog, { scaleX: 1, scaleY: 1 }, 300, Laya.Ease.backOut);
});
await open(dialog);
dialog.mouseThrough = true;
dialog.mouseEnabled = true;
dialog.close = async ()=>{
if(actions?.close) {
await actions.close();
} else {
await Laya.promises.Tween.to(
dialog,
{ scaleX: 0, scaleY: 0 },
300,
Laya.Ease.strongIn
)
await Laya.promises.Tween.to(dialog, { scaleX: 0, scaleY: 0 }, 300, Laya.Ease.strongIn);
}
const index = this.#dialogStack.indexOf(dialog)
if (index != -1) {
this.#dialogStack.splice(index, 1)
const index = this.#dialogStack.indexOf(dialog);
if(index != -1) {
this.#dialogStack.splice(index, 1);
}
this.#showDialogStack()
this.#showDialogStack();
}
this.#dialogLayer.addChild(dialog)
this.#dialogLayer.addChild(dialog);
}
async popup(type, args) {
const className = this.#popups[type]
const popup = await this.getView(className, args, null, type, 'popups')
this.#popupLayer.addChild(popup)
await popup.popup(args, this.#popupLayer)
this.#popupLayer.removeChild(popup)
const className = this.#popups[type];
const popup = await this.getView(className, args, null, type, 'popups');
this.#popupLayer.addChild(popup);
await popup.popup(args, this.#popupLayer);
this.#popupLayer.removeChild(popup);
}
clearAllDialog() {
this.#dialogStack = []
this.#showDialogStack()
this.#dialogStack = [];
this.#showDialogStack();
}
#config(view, key, type) {
const config = this.#configs?.[type]?.[key]
if (!config) return
if (view.config && view.config(config)) return
const config = this.#configs?.[type]?.[key];
if(!config) return;
if(view.config && view.config(config)) return;
const applyConfig = (target, config) => {
if (!target) return
if (typeof config == 'string') {
config = this.#configs?.class?.[config]
if(!target) return;
if(typeof config == 'string') {
config = this.#configs?.class?.[config];
}
$_.deepMapSet(target, config)
}
$_.deepMapSet(target, config);
};
if (config.names)
for (const name in config.names)
this.#deepGetChildsByName(view, name).forEach(child =>
applyConfig(child, config.names[name])
)
if(config.names)
for(const name in config.names)
this.#deepGetChildsByName(view, name)
.forEach(child => applyConfig(child, config.names[name]));
if(config.vars)
for(const key in config.vars)
applyConfig(view[key], config.vars[key]);
if (config.vars)
for (const key in config.vars)
applyConfig(view[key], config.vars[key])
}
#deepGetChildsByName(parent, name) {
const list = []
if (!parent || !parent._childs) return list
const list = [];
if(!parent || !parent._childs) return list;
for (const child of parent._childs) {
if (child.name == name) list.push(child)
if (child._childs)
list.push(...this.#deepGetChildsByName(child, name))
for(const child of parent._childs) {
if(child.name == name) list.push(child);
if(child._childs) list.push(...this.#deepGetChildsByName(child, name));
}
return list
return list;
}
#cutPath(path) {
path = '' + path
let index = path.length
path = ''+path;
let index = path.length;
do {
index--
if (path[index] == '.') {
break
index --;
if(path[index] == '.') {
break;
}
} while (index > 0)
return [path.substring(0, index), path.substring(index, path.length)]
} while (index>0)
return [
path.substring(0, index),
path.substring(index, path.length)
];
}
#subSkin(skin, type) {
if (!skin || !skin.replace(/\s/g, '')) return []
if(!skin || !skin.replace(/\s/g, '')) return [];
switch (type) {
case 'ProgressBar':
return [skin, ...this.#progressBarSkin(skin)]
return [ skin, ...this.#progressBarSkin(skin) ];
case 'ScrollBar':
return [skin, ...this.#scrollBarSkin(skin)]
return [ skin, ...this.#scrollBarSkin(skin) ];
default:
return [skin]
}
}
#progressBarSkin(skin) {
if (!skin.replace(/\s/g, '')) return []
let p = this.#cutPath(skin)
return [`${p[0]}$bar${p[1]}`]
if(!skin.replace(/\s/g, '')) return [];
let p = this.#cutPath(skin);
return [`${p[0]}$bar${p[1]}`];
}
#scrollBarSkin(skin) {
if (!skin.replace(/\s/g, '')) return []
let p = this.#cutPath(skin)
if(!skin.replace(/\s/g, '')) return [];
let p = this.#cutPath(skin);
return [
`${p[0]}$bar${p[1]}`,
`${p[0]}$up${p[1]}`,
`${p[0]}$down${p[1]}`,
]
`${p[0]}$down${p[1]}`
];
}
scanResource(uiView) {
if (!uiView) return []
const resourceList = []
if(!uiView) return [];
const resourceList = [];
resourceList.push(...this.#subSkin(uiView.props?.skin, uiView.type))
resourceList.push(
...this.#subSkin(uiView.props?.hScrollBarSkin, 'ScrollBar')
)
resourceList.push(
...this.#subSkin(uiView.props?.vScrollBarSkin, 'ScrollBar')
)
resourceList.push(...this.#subSkin(uiView.props?.skin, uiView.type));
resourceList.push(...this.#subSkin(uiView.props?.hScrollBarSkin, 'ScrollBar'));
resourceList.push(...this.#subSkin(uiView.props?.vScrollBarSkin, 'ScrollBar'));
uiView.child?.forEach(child => {
resourceList.push(...this.scanResource(child))
})
resourceList.push(...this.scanResource(child));
});
return resourceList
return resourceList;
}
get currentView() {
return this.#currentView
return this.#currentView;
}
get currentDialog() {
return this.#dialogStack[this.#dialogStack.length - 1]
return this.#dialogStack[this.#dialogStack.length -1];
}
get theme() {
return localStorage.getItem('theme')
return localStorage.getItem('theme');
}
set theme(value) {
localStorage.setItem('theme', value)
this.#stage.bgColor = this.#configs.bgColor
document
?.querySelector?.('meta[name="theme-color"]')
?.setAttribute?.('content', this.#configs.bgColor)
localStorage.setItem('theme', value);
this.#stage.bgColor = this.#configs.bgColor;
document?.querySelector?.('meta[name="theme-color"]')?.setAttribute?.('content', this.#configs.bgColor);
}
get #pages() {
return UIManager.theme(this.theme, 'pages')
return UIManager.theme(this.theme, 'pages');
}
get #popups() {
return UIManager.theme(this.theme, 'popups')
return UIManager.theme(this.theme, 'popups');
}
get #configs() {
return UIManager.theme(this.theme, 'configs')
return UIManager.theme(this.theme, 'configs');
}
get common() {
return this.#configs.common
return this.#configs.common;
}
gradeColor(grade) {
return this.common.grade[grade]
return this.common.grade[grade];
}
gradeFilter(grade) {
return this.common.filter[grade]
return this.common.filter[grade];
}
}
}

26
template/index.html Normal file
View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta name="description" content="やり直すんだ。そして、次はうまくやる。"/>
<meta name="keywords" content="人生重开模拟器 liferestart life restart remake 人生重来"/>
<meta name="renderer" content="webkit"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="full-screen" content="true"/>
<meta name="x5-fullscreen" content="true"/>
<meta name="360-fullscreen" content="true"/>
<meta name="theme-color" content="#157878"/>
<meta name="laya" screenorientation ="landscape"/>
<meta http-equiv="expires" content="0"/>
<meta http-equiv="Cache-Control" content="no-siteapp"/>
<title>Life Restart</title>
<script type="text/javascript" src="libs/laya/min/laya.core.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.webgl.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.filter.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.particle.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.ui.min.js"></script>
</head>
<body style="background:black"></body>
</html>

253
test/index.js Normal file
View File

@@ -0,0 +1,253 @@
import { readFile } from 'fs/promises';
import Life from '../src/modules/life.js'
globalThis.localStorage = {};
localStorage.getItem = key => localStorage[key]===void 0? null: localStorage[key];
localStorage.setItem = (key, value) => (localStorage[key] = value);
globalThis.$$eventMap = new Map();
globalThis.$$event = (tag, data) => {
const listener = $$eventMap.get(tag);
if(listener) listener.forEach(fn=>fn(data));
}
globalThis.$$on = (tag, fn) => {
let listener = $$eventMap.get(tag);
if(!listener) {
listener = new Set();
$$eventMap.set(tag, listener);
}
listener.add(fn);
}
globalThis.$$off = (tag, fn) => {
const listener = $$eventMap.get(tag);
if(listener) listener.delete(fn);
}
async function debug(config) {
const core = new Life();
core.config(config);
await core.initial(
async fileName => JSON.parse(await readFile(`public/data/zh-cn/${fileName}.json`)),
async fileName => JSON.parse(await readFile(`public/data/${fileName}.json`)),
);
core.remake(
core.talentRandom()
.splice(0,3)
.map(({id})=>id)
);
let pts = core.getPropertyPoints();
const limit = core.propertyAllocateLimit;
const arr = new Array(4).fill(limit[1]);
while (pts > 0) {
const sub = Math.round(Math.random() * (Math.min(pts, limit[1]) - 1)) + 1;
while(true) {
const select = Math.floor(Math.random() * 4) % 4;
if(arr[select] - sub <0) continue;
arr[select] -= sub;
pts -= sub;
break;
}
}
core.start({
CHR: limit[1] - arr[0], // 颜值 charm CHR
INT: limit[1] - arr[1], // 智力 intelligence INT
STR: limit[1] - arr[2], // 体质 strength STR
MNY: limit[1] - arr[3], // 家境 money MNY
});
const lifeTrajectory = [];
let trajectory;
do{
try{
trajectory = core.next();
} catch(e) {
console.error(e);
// debugger
throw e;
}
lifeTrajectory.push(trajectory);
const { age, content } = trajectory;
console.debug(
`---------------------------------`,
`\n-- ${age}\n `,
content.map(
({type, description, rate, name, postEvent}) => {
switch(type) {
case 'TLT':
return `天赋【${name}】发动:${description}`;
case 'EVT':
return description + (postEvent?`\n ${postEvent}`:'');
}
}
).join('\n ')
);
// if(age == 60) debugger
} while(!trajectory.isEnd)
// debugger;
}
debug({
defaultPropertyPoints: 20, // default number of points for a property
talentSelectLimit: 3, // max number of talents that can be selected
propertyAllocateLimit: [0, 10], // scoop of properties that can be allocated,
defaultPropertys: { SPR: 5 }, // default properties
talentConfig: { // config for talent
talentPullCount: 10, // number of talents to pull from the talent pool
talentRate: { 1:100, 2:10, 3:1, total: 1000 }, // rate of talent pull
additions: {
TMS: [
[ 10, { 2: 1 }],
[ 30, { 2: 2 }],
[ 50, { 2: 3 }],
[ 70, { 2: 4 }],
[100, { 2: 5 }],
],
CACHV: [
[ 10, { 2: 1 }],
[ 30, { 2: 2 }],
[ 50, { 2: 3 }],
[ 70, { 2: 4 }],
[100, { 2: 5 }],
]
},
},
propertyConfig: { // config for property
judge: {
// type: [min, grade, judge]
RTLT: [
[ 0, 0],
[ 0.3, 1],
[ 0.6, 2],
[ 0.9, 3],
],
REVT: [
[ 0, 0],
[ 0.2, 1],
[ 0.4, 2],
[ 0.6, 3],
],
TMS: [
[ 0, 0, 'UI_Remake_Times_Judge_Level_0'],
[ 10, 1, 'UI_Remake_Times_Judge_Level_1'],
[ 30, 1, 'UI_Remake_Times_Judge_Level_2'],
[ 50, 2, 'UI_Remake_Times_Judge_Level_3'],
[ 70, 2, 'UI_Remake_Times_Judge_Level_4'],
[ 100, 3, 'UI_Remake_Times_Judge_Level_5'],
],
CACHV: [
[ 0, 0, 'UI_Achievement_Count_Judge_Level_0'],
[ 10, 1, 'UI_Achievement_Count_Judge_Level_1'],
[ 30, 1, 'UI_Achievement_Count_Judge_Level_2'],
[ 50, 2, 'UI_Achievement_Count_Judge_Level_3'],
[ 70, 2, 'UI_Achievement_Count_Judge_Level_4'],
[ 100, 3, 'UI_Achievement_Count_Judge_Level_5'],
],
HCHR: [
[ 0, 0, 'UI_Judge_Level_0'],
[ 1, 0, 'UI_Judge_Level_1'],
[ 2, 0, 'UI_Judge_Level_2'],
[ 4, 0, 'UI_Judge_Level_3'],
[ 7, 1, 'UI_Judge_Level_4'],
[ 9, 2, 'UI_Judge_Level_5'],
[ 11, 3, 'UI_Judge_Level_6'],
],
HMNY: [
[ 0, 0, 'UI_Judge_Level_0'],
[ 1, 0, 'UI_Judge_Level_1'],
[ 2, 0, 'UI_Judge_Level_2'],
[ 4, 0, 'UI_Judge_Level_3'],
[ 7, 1, 'UI_Judge_Level_4'],
[ 9, 2, 'UI_Judge_Level_5'],
[ 11, 3, 'UI_Judge_Level_6'],
],
HSPR: [
[ 0, 0, 'UI_Spirit_Judge_Level_0'],
[ 1, 0, 'UI_Spirit_Judge_Level_1'],
[ 2, 0, 'UI_Spirit_Judge_Level_2'],
[ 4, 0, 'UI_Spirit_Judge_Level_3'],
[ 7, 1, 'UI_Spirit_Judge_Level_4'],
[ 9, 2, 'UI_Spirit_Judge_Level_5'],
[ 11, 3, 'UI_Spirit_Judge_Level_6'],
],
HINT: [
[ 0, 0, 'UI_Judge_Level_0'],
[ 1, 0, 'UI_Judge_Level_1'],
[ 2, 0, 'UI_Judge_Level_2'],
[ 4, 0, 'UI_Judge_Level_3'],
[ 7, 1, 'UI_Judge_Level_4'],
[ 9, 2, 'UI_Judge_Level_5'],
[ 11, 3, 'UI_Judge_Level_6'],
[ 21, 3, 'UI_Intelligence_Judge_Level_7'],
[ 131, 3, 'UI_Intelligence_Judge_Level_8'],
[ 501, 3, 'UI_Intelligence_Judge_Level_9'],
],
HSTR: [
[ 0, 0, 'UI_Judge_Level_0'],
[ 1, 0, 'UI_Judge_Level_1'],
[ 2, 0, 'UI_Judge_Level_2'],
[ 4, 0, 'UI_Judge_Level_3'],
[ 7, 1, 'UI_Judge_Level_4'],
[ 9, 2, 'UI_Judge_Level_5'],
[ 11, 3, 'UI_Judge_Level_6'],
[ 21, 3, 'UI_Strength_Judge_Level_7'],
[ 101, 3, 'UI_Strength_Judge_Level_8'],
[ 401, 3, 'UI_Strength_Judge_Level_9'],
[1001, 3, 'UI_Strength_Judge_Level_10'],
[2001, 3, 'UI_Strength_Judge_Level_11'],
],
HAGE: [
[ 0, 0, 'UI_AGE_Judge_Level_0'],
[ 1, 0, 'UI_AGE_Judge_Level_1'],
[ 10, 0, 'UI_AGE_Judge_Level_2'],
[ 18, 0, 'UI_AGE_Judge_Level_3'],
[ 40, 0, 'UI_AGE_Judge_Level_4'],
[ 60, 1, 'UI_AGE_Judge_Level_5'],
[ 70, 1, 'UI_AGE_Judge_Level_6'],
[ 80, 2, 'UI_AGE_Judge_Level_7'],
[ 90, 2, 'UI_AGE_Judge_Level_8'],
[ 95, 3, 'UI_AGE_Judge_Level_9'],
[ 100, 3, 'UI_AGE_Judge_Level_10'],
[ 500, 3, 'UI_AGE_Judge_Level_11'],
],
SUM: [
[ 0, 0, 'UI_Judge_Level_0'],
[ 41, 0, 'UI_Judge_Level_1'],
[ 50, 0, 'UI_Judge_Level_2'],
[ 60, 0, 'UI_Judge_Level_3'],
[ 80, 1, 'UI_Judge_Level_4'],
[ 100, 2, 'UI_Judge_Level_5'],
[ 110, 3, 'UI_Judge_Level_6'],
[ 120, 3, 'UI_Judge_Level_7'],
],
},
},
characterConfig: { // config for character
characterPullCount: 3,
rateableKnife: 10,
propertyWeight: [
[ 0, 1],
[ 1, 2],
[ 2, 3],
[ 3, 4],
[ 4, 5],
[ 5, 6],
[ 6, 5],
[ 7, 4],
[ 8, 3],
[ 9, 2],
[10, 1],
],
talentWeight: [
[ 1, 1],
[ 2, 2],
[ 3, 3],
[ 4, 2],
[ 5, 1],
],
},
});

View File

@@ -7,8 +7,10 @@
<meta name="description" content="やり直すんだ。そして、次はうまくやる。"/>
<meta name="keywords" content="人生重开模拟器 liferestart life restart remake 人生重来"/>
<title>Life Restart</title>
</head>
<body>
<script language="javascript" type="text/javascript">
window.location.href="/public/index.html";
</script>
</head>
</body>
</html>

View File

@@ -1,7 +0,0 @@
/** @type {import('vite').UserConfig} */
export default {
base: './',
build: {
outDir: 'template/public',
},
}

57
webpack.config.cjs Normal file
View File

@@ -0,0 +1,57 @@
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'production',
entry: './src/index.js',
devtool: 'eval-cheap-module-source-map',
devServer: {
static: [
{
directory: path.join(__dirname, 'public'),
publicPath: '/public',
},
{
directory: path.join(__dirname, 'view'),
publicPath: '/view',
},
{
directory: path.join(__dirname, 'src'),
publicPath: '/src',
},
],
allowedHosts: "all",
},
output: {
path: path.resolve(__dirname, 'public/chunk'),
filename: '[name].[chunkhash:5].js',
clean: true,
},
plugins: [
new HtmlWebpackPlugin({
template: 'template/index.html',
filename: '../index.html',
}),
],
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
"targets": "> 0.25%, not dead",
"useBuiltIns": "usage",
"corejs": "3.8.3",
}
]
]
}
}
}]
}
};

3782
yarn.lock Normal file

File diff suppressed because it is too large Load Diff