mirror of
https://github.com/VickScarlet/lifeRestart.git
synced 2026-08-29 10:04:43 +08:00
add: bili-toy-sdk cloud save support
This commit is contained in:
@@ -0,0 +1,50 @@
|
|||||||
|
async function loadSDK(sdk) {
|
||||||
|
const script = document.createElement('script')
|
||||||
|
script.src = sdk
|
||||||
|
script.async = true
|
||||||
|
document.body.appendChild(script)
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
script.onload = () => {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
script.onerror = () => {
|
||||||
|
reject(new Error('Failed to load SDK'))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function init(options) {
|
||||||
|
try {
|
||||||
|
await loadSDK(options.sdk)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to load Bili Toy SDK:', error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!(await toy.isSupport('getCloudStorage'))) return
|
||||||
|
if (!(await toy.isSupport('setCloudStorage'))) return
|
||||||
|
if (!(await toy.isSupport('removeCloudStorage'))) return
|
||||||
|
syncUnique()
|
||||||
|
syncProps()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function syncUnique() {
|
||||||
|
if (core.sync('unique')) return
|
||||||
|
const data = await toy.getCloudStorage(['unique'])
|
||||||
|
if (data?.unique) {
|
||||||
|
core.sync('unique', data?.unique)
|
||||||
|
} else {
|
||||||
|
$$on('syncUnique', unique => toy.setCloudStorage({ unique }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function syncProps() {
|
||||||
|
const sync = async () => {
|
||||||
|
const changed = core.sync('props')
|
||||||
|
if (!changed) return
|
||||||
|
const cloudData = await toy.getCloudStorage(['props'])
|
||||||
|
const props = core.sync('props', cloudData?.props ?? '{}')
|
||||||
|
await toy.setCloudStorage({ props })
|
||||||
|
}
|
||||||
|
await sync()
|
||||||
|
setInterval(sync, 10000)
|
||||||
|
}
|
||||||
+70
-69
@@ -1,28 +1,28 @@
|
|||||||
class Character {
|
class Character {
|
||||||
constructor(system) {
|
constructor(system) {
|
||||||
this.#system = system;
|
this.#system = system
|
||||||
}
|
}
|
||||||
|
|
||||||
#system;
|
#system
|
||||||
#characters;
|
#characters
|
||||||
#characterPullCount;
|
#characterPullCount
|
||||||
#rateableKnife;
|
#rateableKnife
|
||||||
#rate;
|
#rate
|
||||||
#pipe = [];
|
#pipe = []
|
||||||
#uniqueWaTaShi;
|
#uniqueWaTaShi
|
||||||
#propertyWeight;
|
#propertyWeight
|
||||||
#talentWeight
|
#talentWeight
|
||||||
|
|
||||||
initial({characters}) {
|
initial({ characters }) {
|
||||||
this.#characters = characters;
|
this.#characters = characters
|
||||||
const uniqueWaTaShi = localStorage.getItem('uniqueWaTaShi');
|
const uniqueWaTaShi = localStorage.getItem('uniqueWaTaShi')
|
||||||
if(uniqueWaTaShi != null || uniqueWaTaShi != 'undefined')
|
if (uniqueWaTaShi != null || uniqueWaTaShi != 'undefined')
|
||||||
this.#uniqueWaTaShi = JSON.parse(uniqueWaTaShi);
|
this.#uniqueWaTaShi = JSON.parse(uniqueWaTaShi)
|
||||||
return this.count;
|
return this.count
|
||||||
}
|
}
|
||||||
|
|
||||||
get count() {
|
get count() {
|
||||||
return Object.keys(this.#characters).length;
|
return Object.keys(this.#characters).length
|
||||||
}
|
}
|
||||||
|
|
||||||
config({
|
config({
|
||||||
@@ -31,43 +31,47 @@ class Character {
|
|||||||
propertyWeight,
|
propertyWeight,
|
||||||
talentWeight,
|
talentWeight,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.#characterPullCount = characterPullCount;
|
this.#characterPullCount = characterPullCount
|
||||||
this.#rateableKnife = rateableKnife;
|
this.#rateableKnife = rateableKnife
|
||||||
this.#propertyWeight = propertyWeight;
|
this.#propertyWeight = propertyWeight
|
||||||
this.#talentWeight = talentWeight;
|
this.#talentWeight = talentWeight
|
||||||
|
}
|
||||||
|
|
||||||
|
sync(data) {
|
||||||
|
if (!data) return JSON.stringify(this.#uniqueWaTaShi)
|
||||||
|
localStorage.setItem('uniqueWaTaShi', data)
|
||||||
|
this.#uniqueWaTaShi = JSON.parse(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
get #unique() {
|
get #unique() {
|
||||||
if(this.#uniqueWaTaShi) {
|
if (this.#uniqueWaTaShi) {
|
||||||
return this.#system.clone(this.#uniqueWaTaShi);
|
return this.#system.clone(this.#uniqueWaTaShi)
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = Date.now();
|
const now = Date.now()
|
||||||
this.#pipe.push(now);
|
this.#pipe.push(now)
|
||||||
if(this.#pipe.length < 10) return null;
|
if (this.#pipe.length < 10) return null
|
||||||
const time = this.#pipe.shift();
|
const time = this.#pipe.shift()
|
||||||
if(now - time > 10000) return null;
|
if (now - time > 10000) return null
|
||||||
return {unique: true, generate: false};
|
return { unique: true, generate: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
set #unique(data) {
|
set #unique(data) {
|
||||||
this.#uniqueWaTaShi = this.#system.clone(data);
|
this.#uniqueWaTaShi = this.#system.clone(data)
|
||||||
this.#uniqueWaTaShi.unique = true;
|
this.#uniqueWaTaShi.unique = true
|
||||||
this.#uniqueWaTaShi.generate = true;
|
this.#uniqueWaTaShi.generate = true
|
||||||
localStorage.setItem(
|
const json = JSON.stringify(this.#uniqueWaTaShi)
|
||||||
'uniqueWaTaShi',
|
localStorage.setItem('uniqueWaTaShi', json)
|
||||||
JSON.stringify(this.#uniqueWaTaShi)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get #weightRandom() {
|
get #weightRandom() {
|
||||||
return this.#system.function(this.#system.Function.UTIL).weightRandom;
|
return this.#system.function(this.#system.Function.UTIL).weightRandom
|
||||||
}
|
}
|
||||||
|
|
||||||
generateUnique() {
|
generateUnique() {
|
||||||
if(this.#uniqueWaTaShi) return this.#unique;
|
if (this.#uniqueWaTaShi) return this.#unique
|
||||||
const weightRandom = this.#weightRandom;
|
const weightRandom = this.#weightRandom
|
||||||
const {CHR, INT, STR, MNY} = this.#system.PropertyTypes;
|
const { CHR, INT, STR, MNY } = this.#system.PropertyTypes
|
||||||
|
|
||||||
this.#unique = {
|
this.#unique = {
|
||||||
property: {
|
property: {
|
||||||
@@ -81,7 +85,7 @@ class Character {
|
|||||||
.random(weightRandom(this.#talentWeight)),
|
.random(weightRandom(this.#talentWeight)),
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.#unique;
|
return this.#unique
|
||||||
}
|
}
|
||||||
|
|
||||||
random() {
|
random() {
|
||||||
@@ -92,43 +96,40 @@ class Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#rateable() {
|
#rateable() {
|
||||||
if(!this.#rate) {
|
if (!this.#rate) {
|
||||||
this.#rate = {};
|
this.#rate = {}
|
||||||
for(const id in this.#characters) {
|
for (const id in this.#characters) {
|
||||||
this.#rate[id] = 1;
|
this.#rate[id] = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const r = [];
|
const r = []
|
||||||
const weightRandom = this.#weightRandom;
|
const weightRandom = this.#weightRandom
|
||||||
new Array(this.#characterPullCount)
|
new Array(this.#characterPullCount).fill(0).forEach(() => {
|
||||||
.fill(0)
|
r.push(
|
||||||
.forEach(()=>{
|
weightRandom(
|
||||||
r.push(
|
Object.keys(this.#rate)
|
||||||
weightRandom(Object
|
.filter(id => !r.includes(id))
|
||||||
.keys(this.#rate)
|
.map(id => [id, this.#rate[id]]),
|
||||||
.filter(id=>!r.includes(id))
|
),
|
||||||
.map(id=>([id,this.#rate[id]]))
|
)
|
||||||
)
|
})
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
let min = Infinity;
|
let min = Infinity
|
||||||
for(const id in this.#rate) {
|
for (const id in this.#rate) {
|
||||||
if(r.includes(id)) {
|
if (r.includes(id)) {
|
||||||
min = Math.min(min, this.#rate[id]);
|
min = Math.min(min, this.#rate[id])
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
min = Math.min(min, ++ this.#rate[id]);
|
min = Math.min(min, ++this.#rate[id])
|
||||||
}
|
}
|
||||||
if(min > this.#rateableKnife) {
|
if (min > this.#rateableKnife) {
|
||||||
for(const id in this.#rate) {
|
for (const id in this.#rate) {
|
||||||
this.#rate[id] -= this.#rateableKnife;
|
this.#rate[id] -= this.#rateableKnife
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r.map(id=>this.#system.clone(this.#characters[id]));
|
return r.map(id => this.#system.clone(this.#characters[id]))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Character;
|
export default Character
|
||||||
|
|||||||
+199
-162
@@ -1,19 +1,19 @@
|
|||||||
import * as util from '../functions/util.js';
|
import * as util from '../functions/util.js'
|
||||||
import * as fCondition from '../functions/condition.js';
|
import * as fCondition from '../functions/condition.js'
|
||||||
|
|
||||||
import Property from './property.js';
|
import Property from './property.js'
|
||||||
import Event from './event.js';
|
import Event from './event.js'
|
||||||
import Talent from './talent.js';
|
import Talent from './talent.js'
|
||||||
import Achievement from './achievement.js';
|
import Achievement from './achievement.js'
|
||||||
import Character from './character.js';
|
import Character from './character.js'
|
||||||
|
|
||||||
class Life {
|
class Life {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.#property = new Property(this);
|
this.#property = new Property(this)
|
||||||
this.#event = new Event(this);
|
this.#event = new Event(this)
|
||||||
this.#talent = new Talent(this);
|
this.#talent = new Talent(this)
|
||||||
this.#achievement = new Achievement(this);
|
this.#achievement = new Achievement(this)
|
||||||
this.#character = new Character(this);
|
this.#character = new Character(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
Module = {
|
Module = {
|
||||||
@@ -29,18 +29,18 @@ class Life {
|
|||||||
UTIL: 'UTIL',
|
UTIL: 'UTIL',
|
||||||
}
|
}
|
||||||
|
|
||||||
#property;
|
#property
|
||||||
#event;
|
#event
|
||||||
#talent;
|
#talent
|
||||||
#achievement;
|
#achievement
|
||||||
#character;
|
#character
|
||||||
#triggerTalents;
|
#triggerTalents
|
||||||
#defaultPropertyPoints;
|
#defaultPropertyPoints
|
||||||
#talentSelectLimit;
|
#talentSelectLimit
|
||||||
#propertyAllocateLimit;
|
#propertyAllocateLimit
|
||||||
#defaultPropertys;
|
#defaultPropertys
|
||||||
#specialThanks;
|
#specialThanks
|
||||||
#initialData;
|
#initialData
|
||||||
|
|
||||||
async initial(i18nLoad, commonLoad) {
|
async initial(i18nLoad, commonLoad) {
|
||||||
const [age, talents, events, achievements, characters, specialThanks] = await Promise.all([
|
const [age, talents, events, achievements, characters, specialThanks] = await Promise.all([
|
||||||
@@ -50,16 +50,16 @@ class Life {
|
|||||||
i18nLoad('achievement'),
|
i18nLoad('achievement'),
|
||||||
i18nLoad('character'),
|
i18nLoad('character'),
|
||||||
commonLoad('specialthanks'),
|
commonLoad('specialthanks'),
|
||||||
]);
|
])
|
||||||
this.#specialThanks = specialThanks;
|
this.#specialThanks = specialThanks
|
||||||
|
|
||||||
const total = {
|
const total = {
|
||||||
[this.PropertyTypes.TACHV]: this.#achievement.initial({achievements}),
|
[this.PropertyTypes.TACHV]: this.#achievement.initial({ achievements }),
|
||||||
[this.PropertyTypes.TEVT]: this.#event.initial({events}),
|
[this.PropertyTypes.TEVT]: this.#event.initial({ events }),
|
||||||
[this.PropertyTypes.TTLT]: this.#talent.initial({talents}),
|
[this.PropertyTypes.TTLT]: this.#talent.initial({ talents }),
|
||||||
};
|
}
|
||||||
this.#property.initial({age, total});
|
this.#property.initial({ age, total })
|
||||||
this.#character.initial({characters});
|
this.#character.initial({ characters })
|
||||||
}
|
}
|
||||||
|
|
||||||
config({
|
config({
|
||||||
@@ -71,137 +71,146 @@ class Life {
|
|||||||
propertyConfig, // config for property
|
propertyConfig, // config for property
|
||||||
characterConfig, // config for character
|
characterConfig, // config for character
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.#defaultPropertyPoints = defaultPropertyPoints;
|
this.#defaultPropertyPoints = defaultPropertyPoints
|
||||||
this.#talentSelectLimit = talentSelectLimit;
|
this.#talentSelectLimit = talentSelectLimit
|
||||||
this.#propertyAllocateLimit = propertyAllocateLimit;
|
this.#propertyAllocateLimit = propertyAllocateLimit
|
||||||
this.#defaultPropertys = defaultPropertys;
|
this.#defaultPropertys = defaultPropertys
|
||||||
this.#talent.config(talentConfig);
|
this.#talent.config(talentConfig)
|
||||||
this.#property.config(propertyConfig);
|
this.#property.config(propertyConfig)
|
||||||
this.#character.config(characterConfig);
|
this.#character.config(characterConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
request(module) {
|
request(module) {
|
||||||
switch (module) {
|
switch (module) {
|
||||||
case this.Module.ACHIEVEMENT: return this.#achievement;
|
case this.Module.ACHIEVEMENT: return this.#achievement
|
||||||
case this.Module.CHARACTER: return this.#character;
|
case this.Module.CHARACTER: return this.#character
|
||||||
case this.Module.EVENT: return this.#event;
|
case this.Module.EVENT: return this.#event
|
||||||
case this.Module.PROPERTY: return this.#property;
|
case this.Module.PROPERTY: return this.#property
|
||||||
case this.Module.TALENT: return this.#talent;
|
case this.Module.TALENT: return this.#talent
|
||||||
default: return null;
|
default: return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function(type) {
|
function(type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case this.Function.CONDITION: return fCondition;
|
case this.Function.CONDITION: return fCondition
|
||||||
case this.Function.UTIL: return util;
|
case this.Function.UTIL: return util
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
check(condition) {
|
check(condition) {
|
||||||
return fCondition.checkCondition(this.#property,condition);
|
return fCondition.checkCondition(this.#property, condition)
|
||||||
}
|
}
|
||||||
|
|
||||||
clone(...args) {
|
clone(...args) {
|
||||||
return util.clone(...args);
|
return util.clone(...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
remake(talents) {
|
remake(talents) {
|
||||||
this.#initialData = util.clone(this.#defaultPropertys);
|
this.#initialData = util.clone(this.#defaultPropertys)
|
||||||
this.#initialData.TLT = util.clone(talents);
|
this.#initialData.TLT = util.clone(talents)
|
||||||
this.#triggerTalents = {};
|
this.#triggerTalents = {}
|
||||||
return this.talentReplace(this.#initialData.TLT);
|
return this.talentReplace(this.#initialData.TLT)
|
||||||
}
|
}
|
||||||
|
|
||||||
start(allocation) {
|
start(allocation) {
|
||||||
for(const key in allocation) {
|
for (const key in allocation) {
|
||||||
this.#initialData[key] = util.clone(allocation[key]);
|
this.#initialData[key] = util.clone(allocation[key])
|
||||||
}
|
}
|
||||||
this.#property.restart(this.#initialData);
|
this.#property.restart(this.#initialData)
|
||||||
this.doTalent()
|
this.doTalent()
|
||||||
this.#property.restartLastStep();
|
this.#property.restartLastStep()
|
||||||
this.#achievement.achieve(this.AchievementOpportunity.START);
|
this.#achievement.achieve(this.AchievementOpportunity.START)
|
||||||
}
|
}
|
||||||
|
|
||||||
getPropertyPoints() {
|
getPropertyPoints() {
|
||||||
return this.#defaultPropertyPoints + this.#talent.allocationAddition(this.#initialData.TLT);
|
return (
|
||||||
|
this.#defaultPropertyPoints +
|
||||||
|
this.#talent.allocationAddition(this.#initialData.TLT)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
getTalentCurrentTriggerCount(talentId) {
|
getTalentCurrentTriggerCount(talentId) {
|
||||||
return this.#triggerTalents[talentId] || 0;
|
return this.#triggerTalents[talentId] || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
next() {
|
next() {
|
||||||
const {age, event, talent} = this.#property.ageNext();
|
const { age, event, talent } = this.#property.ageNext()
|
||||||
|
|
||||||
const talentContent = this.doTalent(talent);
|
const talentContent = this.doTalent(talent)
|
||||||
const eventContent = this.doEvent(this.random(event));
|
const eventContent = this.doEvent(this.random(event))
|
||||||
|
|
||||||
const isEnd = this.#property.isEnd();
|
const isEnd = this.#property.isEnd()
|
||||||
|
|
||||||
const content = [talentContent, eventContent].flat();
|
const content = [talentContent, eventContent].flat()
|
||||||
this.#achievement.achieve(this.AchievementOpportunity.TRAJECTORY);
|
this.#achievement.achieve(this.AchievementOpportunity.TRAJECTORY)
|
||||||
return { age, content, isEnd };
|
return { age, content, isEnd }
|
||||||
}
|
}
|
||||||
|
|
||||||
talentReplace(talents) {
|
talentReplace(talents) {
|
||||||
const result = this.#talent.replace(talents);
|
const result = this.#talent.replace(talents)
|
||||||
const contents = [];
|
const contents = []
|
||||||
for(const id in result) {
|
for (const id in result) {
|
||||||
talents.push(result[id]);
|
talents.push(result[id])
|
||||||
const source = this.#talent.get(id);
|
const source = this.#talent.get(id)
|
||||||
const target = this.#talent.get(result[id]);
|
const target = this.#talent.get(result[id])
|
||||||
contents.push({
|
contents.push({
|
||||||
type: 'talentReplace',
|
type: 'talentReplace',
|
||||||
source, target
|
source,
|
||||||
});
|
target,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return contents;
|
return contents
|
||||||
}
|
}
|
||||||
|
|
||||||
doTalent(talents) {
|
doTalent(talents) {
|
||||||
if(talents) this.#property.change(this.PropertyTypes.TLT, talents);
|
if (talents) this.#property.change(this.PropertyTypes.TLT, talents)
|
||||||
talents = this.#property.get(this.PropertyTypes.TLT)
|
talents = this.#property
|
||||||
.filter(talentId => this.getTalentCurrentTriggerCount(talentId) < this.#talent.get(talentId).max_triggers);
|
.get(this.PropertyTypes.TLT)
|
||||||
|
.filter(
|
||||||
|
talentId =>
|
||||||
|
this.getTalentCurrentTriggerCount(talentId) <
|
||||||
|
this.#talent.get(talentId).max_triggers,
|
||||||
|
)
|
||||||
|
|
||||||
const contents = [];
|
const contents = []
|
||||||
for(const talentId of talents) {
|
for (const talentId of talents) {
|
||||||
const result = this.#talent.do(talentId);
|
const result = this.#talent.do(talentId)
|
||||||
if(!result) continue;
|
if (!result) continue
|
||||||
this.#triggerTalents[talentId] = this.getTalentCurrentTriggerCount(talentId) + 1;
|
this.#triggerTalents[talentId] = this.getTalentCurrentTriggerCount(talentId) + 1
|
||||||
const { effect, name, description, grade } = result;
|
const { effect, name, description, grade } = result
|
||||||
contents.push({
|
contents.push({
|
||||||
type: this.PropertyTypes.TLT,
|
type: this.PropertyTypes.TLT,
|
||||||
name,
|
name,
|
||||||
grade,
|
grade,
|
||||||
description: this.format(description),
|
description: this.format(description),
|
||||||
})
|
})
|
||||||
if(!effect) continue;
|
if (!effect) continue
|
||||||
this.#property.effect(effect);
|
this.#property.effect(effect)
|
||||||
}
|
}
|
||||||
return contents;
|
return contents
|
||||||
}
|
}
|
||||||
|
|
||||||
doEvent(eventId) {
|
doEvent(eventId) {
|
||||||
const { effect, next, description, postEvent, grade } = this.#event.do(eventId);
|
const { effect, next, description, postEvent, grade } = this.#event.do(eventId)
|
||||||
this.#property.change(this.PropertyTypes.EVT, eventId);
|
this.#property.change(this.PropertyTypes.EVT, eventId)
|
||||||
this.#property.effect(effect);
|
this.#property.effect(effect)
|
||||||
const content = {
|
const content = {
|
||||||
type: this.PropertyTypes.EVT,
|
type: this.PropertyTypes.EVT,
|
||||||
description: this.format(description),
|
description: this.format(description),
|
||||||
postEvent: postEvent && this.format(postEvent),
|
postEvent: postEvent && this.format(postEvent),
|
||||||
grade,
|
grade,
|
||||||
}
|
}
|
||||||
if(next) return [content, this.doEvent(next)].flat();
|
if (next) return [content, this.doEvent(next)].flat()
|
||||||
return [content];
|
return [content]
|
||||||
}
|
}
|
||||||
|
|
||||||
random(events) {
|
random(events) {
|
||||||
return util.weightRandom(
|
return util.weightRandom(
|
||||||
events.filter(
|
events.filter(([eventId]) =>
|
||||||
([eventId])=>this.#event.check(eventId, this.#property)
|
this.#event.check(eventId, this.#property),
|
||||||
)
|
),
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
talentRandom() {
|
talentRandom() {
|
||||||
@@ -210,118 +219,146 @@ class Life {
|
|||||||
this.#getPropertys(
|
this.#getPropertys(
|
||||||
this.PropertyTypes.TMS,
|
this.PropertyTypes.TMS,
|
||||||
this.PropertyTypes.CACHV,
|
this.PropertyTypes.CACHV,
|
||||||
)
|
),
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
characterRandom() {
|
characterRandom() {
|
||||||
const characters = this.#character.random();
|
const characters = this.#character.random()
|
||||||
const replaceTalent = v=>v.talent=v.talent.map(
|
const replaceTalent = v =>
|
||||||
id=>this.#talent.get(id)
|
(v.talent = v.talent.map(id => this.#talent.get(id)))
|
||||||
);
|
characters.normal.forEach(replaceTalent)
|
||||||
characters.normal.forEach(replaceTalent);
|
if (characters.unique && characters.unique.talent)
|
||||||
if(characters.unique && characters.unique.talent)
|
replaceTalent(characters.unique)
|
||||||
replaceTalent(characters.unique);
|
return characters
|
||||||
return characters;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
talentExtend(talentId) {
|
talentExtend(talentId) {
|
||||||
this.#property.set(this.PropertyTypes.EXT, talentId);
|
this.#property.set(this.PropertyTypes.EXT, talentId)
|
||||||
}
|
}
|
||||||
|
|
||||||
exclude(talents, exclusive) {
|
exclude(talents, exclusive) {
|
||||||
return this.#talent.exclude(talents, exclusive);
|
return this.#talent.exclude(talents, exclusive)
|
||||||
}
|
}
|
||||||
|
|
||||||
generateUnique() {
|
generateUnique() {
|
||||||
this.#character.generateUnique();
|
const unique = this.#character.generateUnique()
|
||||||
|
$$event('syncUnique', unique)
|
||||||
}
|
}
|
||||||
|
|
||||||
#getJudges(...types) {
|
#getJudges(...types) {
|
||||||
return util.getListValuesMap(types.flat(), key => this.#property.judge(key));
|
return util.getListValuesMap(types.flat(), key =>
|
||||||
|
this.#property.judge(key),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#getPropertys(...types) {
|
#getPropertys(...types) {
|
||||||
return util.getListValuesMap(types.flat(), key => this.#property.get(key));
|
return util.getListValuesMap(types.flat(), key =>
|
||||||
|
this.#property.get(key),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
format(discription) {
|
format(discription) {
|
||||||
return `${discription}`.replaceAll(/\{\s*[0-9a-zA-Z_-]+\s*?\}/g, (match) => this.#format(match));
|
return `${discription}`.replaceAll(
|
||||||
|
/\{\s*[0-9a-zA-Z_-]+\s*?\}/g,
|
||||||
|
match => this.#format(match),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#format(key) {
|
#format(key) {
|
||||||
switch (key.slice(1, -1).trim().toLowerCase()) {
|
switch (key.slice(1, -1).trim().toLowerCase()) {
|
||||||
case 'currentyear': return new Date().getFullYear()
|
case 'currentyear':
|
||||||
case 'age': return this.#property.get(this.PropertyTypes.AGE)
|
return new Date().getFullYear()
|
||||||
case 'charm': return this.#property.get(this.PropertyTypes.CHR)
|
case 'age':
|
||||||
case 'intelligence': return this.#property.get(this.PropertyTypes.INT)
|
return this.#property.get(this.PropertyTypes.AGE)
|
||||||
case 'strength': return this.#property.get(this.PropertyTypes.STR)
|
case 'charm':
|
||||||
case 'money': return this.#property.get(this.PropertyTypes.MNY)
|
return this.#property.get(this.PropertyTypes.CHR)
|
||||||
case 'spirit': return this.#property.get(this.PropertyTypes.SPR)
|
case 'intelligence':
|
||||||
default: return key
|
return this.#property.get(this.PropertyTypes.INT)
|
||||||
|
case 'strength':
|
||||||
|
return this.#property.get(this.PropertyTypes.STR)
|
||||||
|
case 'money':
|
||||||
|
return this.#property.get(this.PropertyTypes.MNY)
|
||||||
|
case 'spirit':
|
||||||
|
return this.#property.get(this.PropertyTypes.SPR)
|
||||||
|
default:
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sync(tag, data) {
|
||||||
|
switch (tag) {
|
||||||
|
case 'unique':
|
||||||
|
return this.#character.sync(data)
|
||||||
|
case 'props':
|
||||||
|
return this.#property.sync(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get lastExtendTalent() {
|
get lastExtendTalent() {
|
||||||
return this.#property.get(this.PropertyTypes.EXT);
|
return this.#property.get(this.PropertyTypes.EXT)
|
||||||
}
|
}
|
||||||
|
|
||||||
get summary() {
|
get summary() {
|
||||||
this.#achievement.achieve(this.AchievementOpportunity.SUMMARY);
|
this.#achievement.achieve(this.AchievementOpportunity.SUMMARY)
|
||||||
|
|
||||||
const pt = this.PropertyTypes;
|
const pt = this.PropertyTypes
|
||||||
|
|
||||||
return this.#getJudges(pt.SUM,
|
return this.#getJudges(
|
||||||
pt.HAGE, pt.HCHR, pt.HINT,
|
pt.SUM,
|
||||||
pt.HSTR, pt.HMNY, pt.HSPR,
|
pt.HAGE,
|
||||||
);
|
pt.HCHR,
|
||||||
|
pt.HINT,
|
||||||
|
pt.HSTR,
|
||||||
|
pt.HMNY,
|
||||||
|
pt.HSPR,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
get statistics() {
|
get statistics() {
|
||||||
const pt = this.PropertyTypes;
|
const pt = this.PropertyTypes
|
||||||
|
|
||||||
return this.#getJudges( pt.TMS,
|
return this.#getJudges(pt.TMS, pt.CACHV, pt.RTLT, pt.REVT)
|
||||||
pt.CACHV, pt.RTLT, pt.REVT,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
get achievements() {
|
get achievements() {
|
||||||
const ticks = {};
|
const ticks = {}
|
||||||
this.#property
|
this.#property
|
||||||
.get(this.PropertyTypes.ACHV)
|
.get(this.PropertyTypes.ACHV)
|
||||||
.forEach(([id, tick]) => ticks[id] = tick);
|
.forEach(([id, tick]) => (ticks[id] = tick))
|
||||||
return this
|
return this.#achievement
|
||||||
.#achievement
|
|
||||||
.list(this.#property)
|
.list(this.#property)
|
||||||
.sort((
|
.sort(
|
||||||
{id: a, grade: ag, hide: ah},
|
(
|
||||||
{id: b, grade: bg, hide: bh}
|
{ id: a, grade: ag, hide: ah },
|
||||||
)=>{
|
{ id: b, grade: bg, hide: bh },
|
||||||
a = ticks[a];
|
) => {
|
||||||
b = ticks[b];
|
a = ticks[a]
|
||||||
if(a&&b) return b - a;
|
b = ticks[b]
|
||||||
if(!a&&!b) {
|
if (a && b) return b - a
|
||||||
if(ah&&bh) return bg - ag;
|
if (!a && !b) {
|
||||||
if(ah) return 1;
|
if (ah && bh) return bg - ag
|
||||||
if(bh) return -1;
|
if (ah) return 1
|
||||||
return bg - ag;
|
if (bh) return -1
|
||||||
}
|
return bg - ag
|
||||||
if(!a) return 1;
|
}
|
||||||
if(!b) return -1;
|
if (!a) return 1
|
||||||
});
|
if (!b) return -1
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
get PropertyTypes() { return this.#property.TYPES; }
|
get PropertyTypes() { return this.#property.TYPES }
|
||||||
get AchievementOpportunity() { return this.#achievement.Opportunity; }
|
get AchievementOpportunity() { return this.#achievement.Opportunity }
|
||||||
get talentSelectLimit() { return this.#talentSelectLimit; }
|
get talentSelectLimit() { return this.#talentSelectLimit }
|
||||||
get propertyAllocateLimit() { return util.clone(this.#propertyAllocateLimit); }
|
get propertyAllocateLimit() { return util.clone(this.#propertyAllocateLimit) }
|
||||||
|
|
||||||
get propertys() { return this.#property.getPropertys(); }
|
get propertys() { return this.#property.getPropertys() }
|
||||||
get times() { return this.#property.get(this.PropertyTypes.TMS) || 0; }
|
get times() { return this.#property.get(this.PropertyTypes.TMS) || 0}
|
||||||
set times(v) {
|
set times(v) {
|
||||||
this.#property.set(this.PropertyTypes.TMS, v);
|
this.#property.set(this.PropertyTypes.TMS, v)
|
||||||
this.#achievement.achieve(this.AchievementOpportunity.END);
|
this.#achievement.achieve(this.AchievementOpportunity.END)
|
||||||
}
|
}
|
||||||
get specialThanks() { return this.#specialThanks; }
|
get specialThanks() { return this.#specialThanks }
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Life;
|
export default Life
|
||||||
|
|||||||
+230
-222
@@ -1,110 +1,107 @@
|
|||||||
class Property {
|
class Property {
|
||||||
constructor(system) {
|
constructor(system) {
|
||||||
this.#system = system;
|
this.#system = system
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPES = {
|
TYPES = {
|
||||||
// 本局
|
// 本局
|
||||||
AGE: "AGE", // 年龄 age AGE
|
AGE: 'AGE', // 年龄 age AGE
|
||||||
CHR: "CHR", // 颜值 charm CHR
|
CHR: 'CHR', // 颜值 charm CHR
|
||||||
INT: "INT", // 智力 intelligence INT
|
INT: 'INT', // 智力 intelligence INT
|
||||||
STR: "STR", // 体质 strength STR
|
STR: 'STR', // 体质 strength STR
|
||||||
MNY: "MNY", // 家境 money MNY
|
MNY: 'MNY', // 家境 money MNY
|
||||||
SPR: "SPR", // 快乐 spirit SPR
|
SPR: 'SPR', // 快乐 spirit SPR
|
||||||
LIF: "LIF", // 生命 life LIFE
|
LIF: 'LIF', // 生命 life LIFE
|
||||||
TLT: "TLT", // 天赋 talent TLT
|
TLT: 'TLT', // 天赋 talent TLT
|
||||||
EVT: "EVT", // 事件 event EVT
|
EVT: 'EVT', // 事件 event EVT
|
||||||
TMS: "TMS", // 次数 times TMS
|
TMS: 'TMS', // 次数 times TMS
|
||||||
|
|
||||||
// Auto calc
|
// Auto calc
|
||||||
LAGE: "LAGE", // 最低年龄 Low Age
|
LAGE: 'LAGE', // 最低年龄 Low Age
|
||||||
HAGE: "HAGE", // 最高年龄 High Age
|
HAGE: 'HAGE', // 最高年龄 High Age
|
||||||
LCHR: "LCHR", // 最低颜值 Low Charm
|
LCHR: 'LCHR', // 最低颜值 Low Charm
|
||||||
HCHR: "HCHR", // 最高颜值 High Charm
|
HCHR: 'HCHR', // 最高颜值 High Charm
|
||||||
LINT: "LINT", // 最低智力 Low Intelligence
|
LINT: 'LINT', // 最低智力 Low Intelligence
|
||||||
HINT: "HINT", // 最高智力 High Intelligence
|
HINT: 'HINT', // 最高智力 High Intelligence
|
||||||
LSTR: "LSTR", // 最低体质 Low Strength
|
LSTR: 'LSTR', // 最低体质 Low Strength
|
||||||
HSTR: "HSTR", // 最高体质 High Strength
|
HSTR: 'HSTR', // 最高体质 High Strength
|
||||||
LMNY: "LMNY", // 最低家境 Low Money
|
LMNY: 'LMNY', // 最低家境 Low Money
|
||||||
HMNY: "HMNY", // 最高家境 High Money
|
HMNY: 'HMNY', // 最高家境 High Money
|
||||||
LSPR: "LSPR", // 最低快乐 Low Spirit
|
LSPR: 'LSPR', // 最低快乐 Low Spirit
|
||||||
HSPR: "HSPR", // 最高快乐 High Spirit
|
HSPR: 'HSPR', // 最高快乐 High Spirit
|
||||||
|
|
||||||
SUM: "SUM", // 总评 summary SUM
|
SUM: 'SUM', // 总评 summary SUM
|
||||||
|
|
||||||
EXT: "EXT", // 继承天赋
|
EXT: 'EXT', // 继承天赋
|
||||||
|
|
||||||
// 总计
|
// 总计
|
||||||
// Achievement Total
|
// Achievement Total
|
||||||
ATLT: "ATLT", // 拥有过的天赋 Achieve Talent
|
ATLT: 'ATLT', // 拥有过的天赋 Achieve Talent
|
||||||
AEVT: "AEVT", // 触发过的事件 Achieve Event
|
AEVT: 'AEVT', // 触发过的事件 Achieve Event
|
||||||
ACHV: "ACHV", // 达成的成就 Achievement
|
ACHV: 'ACHV', // 达成的成就 Achievement
|
||||||
|
|
||||||
CTLT: "CTLT", // 天赋选择数 Count Talent
|
CTLT: 'CTLT', // 天赋选择数 Count Talent
|
||||||
CEVT: "CEVT", // 事件收集数 Count Event
|
CEVT: 'CEVT', // 事件收集数 Count Event
|
||||||
CACHV: "CACHV", // 成就达成数 Count Achievement
|
CACHV: 'CACHV', // 成就达成数 Count Achievement
|
||||||
|
|
||||||
// 总数
|
// 总数
|
||||||
TTLT: "TTLT", // 总天赋数 Total Talent
|
TTLT: 'TTLT', // 总天赋数 Total Talent
|
||||||
TEVT: "TEVT", // 总事件数 Total Event
|
TEVT: 'TEVT', // 总事件数 Total Event
|
||||||
TACHV: "TACHV", // 总成就数 Total Achievement
|
TACHV: 'TACHV', // 总成就数 Total Achievement
|
||||||
|
|
||||||
// 比率
|
// 比率
|
||||||
REVT: "REVT", // 事件收集率 Rate Event
|
REVT: 'REVT', // 事件收集率 Rate Event
|
||||||
RTLT: "RTLT", // 天赋选择率 Rate Talent
|
RTLT: 'RTLT', // 天赋选择率 Rate Talent
|
||||||
RACHV: "RACHV", // 成就达成率 Rate Achievement
|
RACHV: 'RACHV', // 成就达成率 Rate Achievement
|
||||||
|
|
||||||
// SPECIAL
|
// SPECIAL
|
||||||
RDM: 'RDM', // 随机属性 random RDM
|
RDM: 'RDM', // 随机属性 random RDM
|
||||||
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// 特殊类型
|
// 特殊类型
|
||||||
SPECIAL = {
|
SPECIAL = {
|
||||||
RDM: [ // 随机属性 random RDM
|
RDM: [
|
||||||
|
// 随机属性 random RDM
|
||||||
this.TYPES.CHR,
|
this.TYPES.CHR,
|
||||||
this.TYPES.INT,
|
this.TYPES.INT,
|
||||||
this.TYPES.STR,
|
this.TYPES.STR,
|
||||||
this.TYPES.MNY,
|
this.TYPES.MNY,
|
||||||
this.TYPES.SPR,
|
this.TYPES.SPR,
|
||||||
]
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
#system;
|
#system
|
||||||
#ageData;
|
#ageData
|
||||||
#data = {};
|
#data = {}
|
||||||
#total;
|
#total
|
||||||
#judge;
|
#judge
|
||||||
|
#sync = new Set()
|
||||||
|
|
||||||
get #util() {
|
get #util() {
|
||||||
return this.#system.function(this.#system.Function.UTIL);
|
return this.#system.function(this.#system.Function.UTIL)
|
||||||
}
|
}
|
||||||
|
|
||||||
initial({age, total}) {
|
initial({ age, total }) {
|
||||||
this.#ageData = age;
|
this.#ageData = age
|
||||||
for(const a in age) {
|
for (const a in age) {
|
||||||
let { event, talent } = age[a];
|
let { event, talent } = age[a]
|
||||||
if(!Array.isArray(event))
|
if (!Array.isArray(event)) event = event?.split(',') || []
|
||||||
event = event?.split(',') || [];
|
|
||||||
|
|
||||||
event = event.map(v=>{
|
event = event.map(v => {
|
||||||
const value = `${v}`.split('*').map(n=>Number(n));
|
const value = `${v}`.split('*').map(Number)
|
||||||
if(value.length==1) value.push(1);
|
if (value.length == 1) value.push(1)
|
||||||
return value;
|
return value
|
||||||
});
|
})
|
||||||
|
|
||||||
if(!Array.isArray(talent))
|
if (!Array.isArray(talent)) talent = talent?.split(',') || []
|
||||||
talent = talent?.split(',') || [];
|
talent = talent.map(Number)
|
||||||
|
age[a] = { event, talent }
|
||||||
talent = talent.map(v=>Number(v));
|
|
||||||
|
|
||||||
age[a] = { event, talent };
|
|
||||||
}
|
}
|
||||||
this.#total = total;
|
this.#total = total
|
||||||
}
|
}
|
||||||
|
|
||||||
config({judge = {}}) {
|
config({ judge = {} }) {
|
||||||
this.#judge = judge;
|
this.#judge = judge
|
||||||
}
|
}
|
||||||
|
|
||||||
restart(data) {
|
restart(data) {
|
||||||
@@ -135,29 +132,28 @@ class Property {
|
|||||||
[this.TYPES.HSTR]: -Infinity,
|
[this.TYPES.HSTR]: -Infinity,
|
||||||
[this.TYPES.HMNY]: -Infinity,
|
[this.TYPES.HMNY]: -Infinity,
|
||||||
[this.TYPES.HSPR]: -Infinity,
|
[this.TYPES.HSPR]: -Infinity,
|
||||||
};
|
}
|
||||||
for(const key in data)
|
for (const key in data) this.change(key, data[key])
|
||||||
this.change(key, data[key]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
restartLastStep() {
|
restartLastStep() {
|
||||||
this.#data[this.TYPES.LAGE] = this.get(this.TYPES.AGE);
|
this.#data[this.TYPES.LAGE] = this.get(this.TYPES.AGE)
|
||||||
this.#data[this.TYPES.LCHR] = this.get(this.TYPES.CHR);
|
this.#data[this.TYPES.LCHR] = this.get(this.TYPES.CHR)
|
||||||
this.#data[this.TYPES.LINT] = this.get(this.TYPES.INT);
|
this.#data[this.TYPES.LINT] = this.get(this.TYPES.INT)
|
||||||
this.#data[this.TYPES.LSTR] = this.get(this.TYPES.STR);
|
this.#data[this.TYPES.LSTR] = this.get(this.TYPES.STR)
|
||||||
this.#data[this.TYPES.LSPR] = this.get(this.TYPES.SPR);
|
this.#data[this.TYPES.LSPR] = this.get(this.TYPES.SPR)
|
||||||
this.#data[this.TYPES.LMNY] = this.get(this.TYPES.MNY);
|
this.#data[this.TYPES.LMNY] = this.get(this.TYPES.MNY)
|
||||||
this.#data[this.TYPES.HAGE] = this.get(this.TYPES.AGE);
|
this.#data[this.TYPES.HAGE] = this.get(this.TYPES.AGE)
|
||||||
this.#data[this.TYPES.HCHR] = this.get(this.TYPES.CHR);
|
this.#data[this.TYPES.HCHR] = this.get(this.TYPES.CHR)
|
||||||
this.#data[this.TYPES.HINT] = this.get(this.TYPES.INT);
|
this.#data[this.TYPES.HINT] = this.get(this.TYPES.INT)
|
||||||
this.#data[this.TYPES.HSTR] = this.get(this.TYPES.STR);
|
this.#data[this.TYPES.HSTR] = this.get(this.TYPES.STR)
|
||||||
this.#data[this.TYPES.HMNY] = this.get(this.TYPES.MNY);
|
this.#data[this.TYPES.HMNY] = this.get(this.TYPES.MNY)
|
||||||
this.#data[this.TYPES.HSPR] = this.get(this.TYPES.SPR);
|
this.#data[this.TYPES.HSPR] = this.get(this.TYPES.SPR)
|
||||||
}
|
}
|
||||||
|
|
||||||
get(prop) {
|
get(prop) {
|
||||||
const util = this.#util;
|
const util = this.#util
|
||||||
switch(prop) {
|
switch (prop) {
|
||||||
case this.TYPES.AGE:
|
case this.TYPES.AGE:
|
||||||
case this.TYPES.CHR:
|
case this.TYPES.CHR:
|
||||||
case this.TYPES.INT:
|
case this.TYPES.INT:
|
||||||
@@ -167,89 +163,83 @@ class Property {
|
|||||||
case this.TYPES.LIF:
|
case this.TYPES.LIF:
|
||||||
case this.TYPES.TLT:
|
case this.TYPES.TLT:
|
||||||
case this.TYPES.EVT:
|
case this.TYPES.EVT:
|
||||||
return util.clone(this.#data[prop]);
|
return util.clone(this.#data[prop])
|
||||||
case this.TYPES.LAGE:
|
case this.TYPES.LAGE:
|
||||||
case this.TYPES.LCHR:
|
case this.TYPES.LCHR:
|
||||||
case this.TYPES.LINT:
|
case this.TYPES.LINT:
|
||||||
case this.TYPES.LSTR:
|
case this.TYPES.LSTR:
|
||||||
case this.TYPES.LMNY:
|
case this.TYPES.LMNY:
|
||||||
case this.TYPES.LSPR:
|
case this.TYPES.LSPR:
|
||||||
return util.min(
|
return util.min(this.#data[prop], this.get(this.fallback(prop)))
|
||||||
this.#data[prop],
|
|
||||||
this.get(this.fallback(prop))
|
|
||||||
);
|
|
||||||
case this.TYPES.HAGE:
|
case this.TYPES.HAGE:
|
||||||
case this.TYPES.HCHR:
|
case this.TYPES.HCHR:
|
||||||
case this.TYPES.HINT:
|
case this.TYPES.HINT:
|
||||||
case this.TYPES.HSTR:
|
case this.TYPES.HSTR:
|
||||||
case this.TYPES.HMNY:
|
case this.TYPES.HMNY:
|
||||||
case this.TYPES.HSPR:
|
case this.TYPES.HSPR:
|
||||||
return util.max(
|
return util.max(this.#data[prop], this.get(this.fallback(prop)))
|
||||||
this.#data[prop],
|
case this.TYPES.SUM: {
|
||||||
this.get(this.fallback(prop))
|
const HAGE = this.get(this.TYPES.HAGE)
|
||||||
);
|
const HCHR = this.get(this.TYPES.HCHR)
|
||||||
case this.TYPES.SUM:
|
const HINT = this.get(this.TYPES.HINT)
|
||||||
const HAGE = this.get(this.TYPES.HAGE);
|
const HSTR = this.get(this.TYPES.HSTR)
|
||||||
const HCHR = this.get(this.TYPES.HCHR);
|
const HMNY = this.get(this.TYPES.HMNY)
|
||||||
const HINT = this.get(this.TYPES.HINT);
|
const HSPR = this.get(this.TYPES.HSPR)
|
||||||
const HSTR = this.get(this.TYPES.HSTR);
|
return Math.floor(util.sum(HCHR, HINT, HSTR, HMNY, HSPR) * 2 + HAGE / 2)
|
||||||
const HMNY = this.get(this.TYPES.HMNY);
|
}
|
||||||
const HSPR = this.get(this.TYPES.HSPR);
|
|
||||||
return Math.floor(util.sum(HCHR, HINT, HSTR, HMNY, HSPR)*2 + HAGE/2);
|
|
||||||
case this.TYPES.TMS:
|
case this.TYPES.TMS:
|
||||||
return this.lsget('times') || 0;
|
return this.lsget('times') || 0
|
||||||
case this.TYPES.EXT:
|
case this.TYPES.EXT:
|
||||||
return this.lsget('extendTalent') || null;
|
return this.lsget('extendTalent') || null
|
||||||
case this.TYPES.ATLT:
|
case this.TYPES.ATLT:
|
||||||
case this.TYPES.AEVT:
|
case this.TYPES.AEVT:
|
||||||
case this.TYPES.ACHV:
|
case this.TYPES.ACHV:
|
||||||
return this.lsget(prop) || [];
|
return this.lsget(prop) || []
|
||||||
case this.TYPES.CTLT:
|
case this.TYPES.CTLT:
|
||||||
case this.TYPES.CEVT:
|
case this.TYPES.CEVT:
|
||||||
case this.TYPES.CACHV:
|
case this.TYPES.CACHV:
|
||||||
return this.get(
|
return this.get(this.fallback(prop)).length
|
||||||
this.fallback(prop)
|
|
||||||
).length;
|
|
||||||
case this.TYPES.TTLT:
|
case this.TYPES.TTLT:
|
||||||
case this.TYPES.TEVT:
|
case this.TYPES.TEVT:
|
||||||
case this.TYPES.TACHV:
|
case this.TYPES.TACHV:
|
||||||
return this.#total[prop];
|
return this.#total[prop]
|
||||||
case this.TYPES.RTLT:
|
case this.TYPES.RTLT:
|
||||||
case this.TYPES.REVT:
|
case this.TYPES.REVT:
|
||||||
case this.TYPES.RACHV:
|
case this.TYPES.RACHV: {
|
||||||
const fb = this.fallback(prop);
|
const fb = this.fallback(prop)
|
||||||
return this.get(fb[0]) / this.get(fb[1]);
|
return this.get(fb[0]) / this.get(fb[1])
|
||||||
default: return 0;
|
}
|
||||||
|
default: return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fallback(prop) {
|
fallback(prop) {
|
||||||
switch(prop) {
|
switch (prop) {
|
||||||
case this.TYPES.LAGE:
|
case this.TYPES.LAGE:
|
||||||
case this.TYPES.HAGE: return this.TYPES.AGE;
|
case this.TYPES.HAGE: return this.TYPES.AGE
|
||||||
case this.TYPES.LCHR:
|
case this.TYPES.LCHR:
|
||||||
case this.TYPES.HCHR: return this.TYPES.CHR;
|
case this.TYPES.HCHR: return this.TYPES.CHR
|
||||||
case this.TYPES.LINT:
|
case this.TYPES.LINT:
|
||||||
case this.TYPES.HINT: return this.TYPES.INT;
|
case this.TYPES.HINT: return this.TYPES.INT
|
||||||
case this.TYPES.LSTR:
|
case this.TYPES.LSTR:
|
||||||
case this.TYPES.HSTR: return this.TYPES.STR;
|
case this.TYPES.HSTR: return this.TYPES.STR
|
||||||
case this.TYPES.LMNY:
|
case this.TYPES.LMNY:
|
||||||
case this.TYPES.HMNY: return this.TYPES.MNY;
|
case this.TYPES.HMNY: return this.TYPES.MNY
|
||||||
case this.TYPES.LSPR:
|
case this.TYPES.LSPR:
|
||||||
case this.TYPES.HSPR: return this.TYPES.SPR;
|
case this.TYPES.HSPR: return this.TYPES.SPR
|
||||||
case this.TYPES.CTLT: return this.TYPES.ATLT;
|
case this.TYPES.CTLT: return this.TYPES.ATLT
|
||||||
case this.TYPES.CEVT: return this.TYPES.AEVT;
|
case this.TYPES.CEVT: return this.TYPES.AEVT
|
||||||
case this.TYPES.CACHV: return this.TYPES.ACHV;
|
case this.TYPES.CACHV: return this.TYPES.ACHV
|
||||||
case this.TYPES.LIF: return this.TYPES.LIF;
|
case this.TYPES.LIF: return this.TYPES.LIF
|
||||||
case this.TYPES.RTLT: return [this.TYPES.CTLT, this.TYPES.TTLT];
|
case this.TYPES.RTLT: return [this.TYPES.CTLT, this.TYPES.TTLT]
|
||||||
case this.TYPES.REVT: return [this.TYPES.CEVT, this.TYPES.TEVT];
|
case this.TYPES.REVT: return [this.TYPES.CEVT, this.TYPES.TEVT]
|
||||||
case this.TYPES.RACHV: return [this.TYPES.CACHV, this.TYPES.TACHV];
|
case this.TYPES.RACHV: return [this.TYPES.CACHV, this.TYPES.TACHV]
|
||||||
default: return;
|
default: return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set(prop, value) {
|
set(prop, value) {
|
||||||
switch(prop) {
|
switch (prop) {
|
||||||
case this.TYPES.AGE:
|
case this.TYPES.AGE:
|
||||||
case this.TYPES.CHR:
|
case this.TYPES.CHR:
|
||||||
case this.TYPES.INT:
|
case this.TYPES.INT:
|
||||||
@@ -259,16 +249,17 @@ class Property {
|
|||||||
case this.TYPES.LIF:
|
case this.TYPES.LIF:
|
||||||
case this.TYPES.TLT:
|
case this.TYPES.TLT:
|
||||||
case this.TYPES.EVT:
|
case this.TYPES.EVT:
|
||||||
this.hl(prop, this.#data[prop] = this.#system.clone(value));
|
this.#data[prop] = this.#system.clone(value)
|
||||||
this.achieve(prop, value);
|
this.hl(prop, this.#data[prop])
|
||||||
return;
|
this.achieve(prop, value)
|
||||||
case this.TYPES.TMS:
|
|
||||||
this.lsset('times', parseInt(value) || 0);
|
|
||||||
return;
|
|
||||||
case this.TYPES.EXT:
|
|
||||||
this.lsset('extendTalent', value);
|
|
||||||
return
|
return
|
||||||
default: return;
|
case this.TYPES.TMS:
|
||||||
|
this.lsset('times', Number.parseInt(value) || 0)
|
||||||
|
return
|
||||||
|
case this.TYPES.EXT:
|
||||||
|
this.lsset('extendTalent', value)
|
||||||
|
return
|
||||||
|
default: return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,16 +271,15 @@ class Property {
|
|||||||
[this.TYPES.STR]: this.get(this.TYPES.STR),
|
[this.TYPES.STR]: this.get(this.TYPES.STR),
|
||||||
[this.TYPES.MNY]: this.get(this.TYPES.MNY),
|
[this.TYPES.MNY]: this.get(this.TYPES.MNY),
|
||||||
[this.TYPES.SPR]: this.get(this.TYPES.SPR),
|
[this.TYPES.SPR]: this.get(this.TYPES.SPR),
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
change(prop, value) {
|
change(prop, value) {
|
||||||
if(Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
for(const v of value)
|
for (const v of value) this.change(prop, Number(v))
|
||||||
this.change(prop, Number(v));
|
return
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
switch(prop) {
|
switch (prop) {
|
||||||
case this.TYPES.AGE:
|
case this.TYPES.AGE:
|
||||||
case this.TYPES.CHR:
|
case this.TYPES.CHR:
|
||||||
case this.TYPES.INT:
|
case this.TYPES.INT:
|
||||||
@@ -297,128 +287,146 @@ class Property {
|
|||||||
case this.TYPES.MNY:
|
case this.TYPES.MNY:
|
||||||
case this.TYPES.SPR:
|
case this.TYPES.SPR:
|
||||||
case this.TYPES.LIF:
|
case this.TYPES.LIF:
|
||||||
this.hl(prop, this.#data[prop] += Number(value));
|
this.#data[prop] += Number(value)
|
||||||
return;
|
this.hl(prop, this.#data[prop])
|
||||||
|
return
|
||||||
case this.TYPES.TLT:
|
case this.TYPES.TLT:
|
||||||
case this.TYPES.EVT:
|
case this.TYPES.EVT: {
|
||||||
const v = this.#data[prop];
|
const v = this.#data[prop]
|
||||||
if(value<0) {
|
if (value < 0) {
|
||||||
const index = v.indexOf(value);
|
const index = v.indexOf(value)
|
||||||
if(index!=-1) v.splice(index,1);
|
if (index != -1) v.splice(index, 1)
|
||||||
}
|
}
|
||||||
if(!v.includes(value)) v.push(value);
|
if (!v.includes(value)) v.push(value)
|
||||||
this.achieve(prop, value);
|
this.achieve(prop, value)
|
||||||
return;
|
return
|
||||||
|
}
|
||||||
case this.TYPES.TMS:
|
case this.TYPES.TMS:
|
||||||
this.set(
|
this.set(prop, this.get(prop) + Number.parseInt(value))
|
||||||
prop,
|
return
|
||||||
this.get(prop) + parseInt(value)
|
default: return
|
||||||
);
|
|
||||||
return;
|
|
||||||
default: return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hookSpecial(prop) {
|
hookSpecial(prop) {
|
||||||
switch(prop) {
|
if (prop === this.TYPES.RDM)
|
||||||
case this.TYPES.RDM:
|
return this.#util.listRandom(this.SPECIAL.RDM)
|
||||||
return this.#util.listRandom(this.SPECIAL.RDM);
|
return prop
|
||||||
default: return prop;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
effect(effects) {
|
effect(effects) {
|
||||||
for(let prop in effects)
|
for (let prop in effects)
|
||||||
this.change(
|
this.change(this.hookSpecial(prop), Number(effects[prop]))
|
||||||
this.hookSpecial(prop),
|
|
||||||
Number(effects[prop])
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
judge(prop) {
|
judge(prop) {
|
||||||
const value = this.get(prop);
|
const value = this.get(prop)
|
||||||
|
|
||||||
const d = this.#judge[prop];
|
const d = this.#judge[prop]
|
||||||
let length = d.length;
|
let length = d.length
|
||||||
|
|
||||||
const progress = () => Math.max(Math.min(value, 10), 0) / 10;
|
const progress = () => Math.max(Math.min(value, 10), 0) / 10
|
||||||
|
|
||||||
while(length--) {
|
while (length--) {
|
||||||
const [min, grade, judge] = d[length];
|
const [min, grade, judge] = d[length]
|
||||||
if(!length || min==void 0 || value >= min) return {prop, value, judge, grade, progress: progress()};
|
if (!length || min == void 0 || value >= min)
|
||||||
|
return { prop, value, judge, grade, progress: progress() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isEnd() {
|
isEnd() {
|
||||||
return this.get(this.TYPES.LIF) < 1;
|
return this.get(this.TYPES.LIF) < 1
|
||||||
}
|
}
|
||||||
|
|
||||||
ageNext() {
|
ageNext() {
|
||||||
this.change(this.TYPES.AGE, 1);
|
this.change(this.TYPES.AGE, 1)
|
||||||
const age = this.get(this.TYPES.AGE);
|
const age = this.get(this.TYPES.AGE)
|
||||||
const {event, talent} = this.getAgeData(age);
|
const { event, talent } = this.getAgeData(age)
|
||||||
return {age, event, talent};
|
return { age, event, talent }
|
||||||
}
|
}
|
||||||
|
|
||||||
getAgeData(age) {
|
getAgeData(age) {
|
||||||
return this.#system.clone(this.#ageData[age]);
|
return this.#system.clone(this.#ageData[age])
|
||||||
}
|
}
|
||||||
|
|
||||||
hl(prop, value) {
|
hl(prop, value) {
|
||||||
let keys;
|
let keys
|
||||||
switch(prop) {
|
switch (prop) {
|
||||||
case this.TYPES.AGE: keys = [this.TYPES.LAGE, this.TYPES.HAGE]; break;
|
case this.TYPES.AGE: keys = [this.TYPES.LAGE, this.TYPES.HAGE]; break
|
||||||
case this.TYPES.CHR: keys = [this.TYPES.LCHR, this.TYPES.HCHR]; break;
|
case this.TYPES.CHR: keys = [this.TYPES.LCHR, this.TYPES.HCHR]; break
|
||||||
case this.TYPES.INT: keys = [this.TYPES.LINT, this.TYPES.HINT]; break;
|
case this.TYPES.INT: keys = [this.TYPES.LINT, this.TYPES.HINT]; break
|
||||||
case this.TYPES.STR: keys = [this.TYPES.LSTR, this.TYPES.HSTR]; break;
|
case this.TYPES.STR: keys = [this.TYPES.LSTR, this.TYPES.HSTR]; break
|
||||||
case this.TYPES.MNY: keys = [this.TYPES.LMNY, this.TYPES.HMNY]; break;
|
case this.TYPES.MNY: keys = [this.TYPES.LMNY, this.TYPES.HMNY]; break
|
||||||
case this.TYPES.SPR: keys = [this.TYPES.LSPR, this.TYPES.HSPR]; break;
|
case this.TYPES.SPR: keys = [this.TYPES.LSPR, this.TYPES.HSPR]; break
|
||||||
default: return;
|
default: return
|
||||||
}
|
}
|
||||||
const [l, h] = keys;
|
const [l, h] = keys
|
||||||
this.#data[l] = this.#util.min(this.#data[l], value);
|
this.#data[l] = this.#util.min(this.#data[l], value)
|
||||||
this.#data[h] = this.#util.max(this.#data[h], value);
|
this.#data[h] = this.#util.max(this.#data[h], value)
|
||||||
}
|
}
|
||||||
|
|
||||||
achieve(prop, newData) {
|
achieve(prop, newData) {
|
||||||
let key;
|
let key
|
||||||
switch(prop) {
|
switch (prop) {
|
||||||
case this.TYPES.ACHV:
|
case this.TYPES.ACHV: {
|
||||||
const lastData = this.lsget(prop);
|
const lastData = this.lsget(prop)
|
||||||
this.lsset(
|
this.lsset(
|
||||||
prop,
|
prop,
|
||||||
(lastData || []).concat([[newData, Date.now()]])
|
(lastData || []).concat([[newData, Date.now()]]),
|
||||||
);
|
|
||||||
return;
|
|
||||||
case this.TYPES.TLT: key = this.TYPES.ATLT; break;
|
|
||||||
case this.TYPES.EVT: key = this.TYPES.AEVT; break;
|
|
||||||
default: return;
|
|
||||||
}
|
|
||||||
const lastData = this.lsget(key) || [];
|
|
||||||
this.lsset(
|
|
||||||
key,
|
|
||||||
Array.from(
|
|
||||||
new Set(
|
|
||||||
lastData
|
|
||||||
.concat(newData||[])
|
|
||||||
.flat()
|
|
||||||
)
|
)
|
||||||
)
|
return
|
||||||
|
}
|
||||||
|
case this.TYPES.TLT: key = this.TYPES.ATLT; break
|
||||||
|
case this.TYPES.EVT: key = this.TYPES.AEVT; break
|
||||||
|
default: return
|
||||||
|
}
|
||||||
|
const lastData = this.lsget(key) || []
|
||||||
|
this.lsset(key, Array.from(new Set(lastData.concat(newData || []).flat())))
|
||||||
|
}
|
||||||
|
|
||||||
|
#syncMerge(key, cloud) {
|
||||||
|
const local = this.lsget(key)
|
||||||
|
if (!cloud) return local
|
||||||
|
if (!local) {
|
||||||
|
localStorage.setItem(key, JSON.stringify(cloud))
|
||||||
|
return cloud
|
||||||
|
}
|
||||||
|
if (Array.isArray(cloud)) {
|
||||||
|
const merged = Array.from(new Set(cloud.concat(local)))
|
||||||
|
localStorage.setItem(key, JSON.stringify(merged))
|
||||||
|
return merged
|
||||||
|
}
|
||||||
|
if (Number.isNumber(cloud)) {
|
||||||
|
const merged = Math.max(cloud, local)
|
||||||
|
localStorage.setItem(key, JSON.stringify(merged))
|
||||||
|
return merged
|
||||||
|
}
|
||||||
|
return local
|
||||||
|
}
|
||||||
|
|
||||||
|
sync(cloudData) {
|
||||||
|
if (!cloudData) return this.#sync.size > 0
|
||||||
|
cloudData = JSON.parse(cloudData)
|
||||||
|
const syncData = Object.fromEntries(
|
||||||
|
Array.from(
|
||||||
|
this.#sync.union(new Set(Object.keys(cloudData))),
|
||||||
|
key => [key, this.#syncMerge(key, cloudData[key])],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
this.#sync.clear()
|
||||||
|
return JSON.stringify(syncData)
|
||||||
}
|
}
|
||||||
|
|
||||||
lsget(key) {
|
lsget(key) {
|
||||||
const data = localStorage.getItem(key);
|
const data = localStorage.getItem(key)
|
||||||
if(data === null || data === 'undefined') return;
|
if (data === null || data === 'undefined') return
|
||||||
return JSON.parse(data);
|
return JSON.parse(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
lsset(key, value) {
|
lsset(key, value) {
|
||||||
localStorage.setItem(
|
localStorage.setItem(key, JSON.stringify(value))
|
||||||
key,
|
this.#sync.add(key)
|
||||||
JSON.stringify(value)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Property;
|
export default Property
|
||||||
|
|||||||
Reference in New Issue
Block a user