add unique character

This commit is contained in:
Vick Scarlet
2022-01-27 16:04:55 +08:00
parent 8d71b73e94
commit d097b3bc15
43 changed files with 908 additions and 180 deletions

View File

@@ -160,11 +160,7 @@ class App{
globalThis.$ui = UIManager.getInstance();
if(theme=='default') {
if(!localStorage.getItem('__')) {
localStorage.setItem('__', 1);
localStorage.setItem('theme', 'cyber');
}
theme = localStorage.getItem('theme');
theme = localStorage.getItem('theme') || 'default';
}
$ui.theme = theme;

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

View File

@@ -141,9 +141,14 @@ export default ({
UI_CelebrityMode: 'Celebrity',
UI_CelebrityModeDescription: 'Past life is celebrity\nRebirth to modern',
UI_AllNot: '↻All Not',
UI_UniqueWaTaShi: 'Unique of mine',
UI_UniqueWaTaShiContent: '\nUnique character card different from other 60 million player\nAll property, All talent, All random\nAll has only one chance',
UI_GenerateNow: 'Generate Now',
M_NoRank: 'There is no rank',
M_PleaseSelectOne: 'Please Select One',
M_UnGenerate: 'Unique Character no generate',
M_DisableExtendTalent: 'Celebrity mode can\'t extends talent',
F_RemakeTimes: 'Remake {0} Times',

View File

@@ -143,10 +143,13 @@ export default ({
UI_CelebrityMode: '名人模式',
UI_CelebrityModeDescription: '前世是古代名人\n重开到了现代',
UI_AllNot: '↻都不是',
UI_UniqueWaTaShi: '独一无二的我',
UI_UniqueWaTaShiContent: '\n6000万玩家中独一无二的角色卡\n所有属性 所有天赋 随机生成\n 每人只能生成一次',
UI_GenerateNow: '立即生成',
M_NoRank: '别卷了,没有排行榜',
M_PleaseSelectOne: '请选择一个名人',
M_UnGenerate: '独一无二的我还没有生成',
M_DisableExtendTalent: '名人模式不能继承天赋',
F_RemakeTimes: '已重开{0}次',

View File

@@ -196,5 +196,29 @@ core.config({
],
},
},
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],
],
},
});
game.start(query);

View File

@@ -1,8 +1,7 @@
import { clone } from '../functions/util.js';
import { checkCondition } from '../functions/condition.js';
class Achievement {
constructor() {}
constructor(system) {
this.#system = system;
}
// 时机
Opportunity = {
@@ -12,6 +11,7 @@ class Achievement {
END: "END", // 游戏完成,点击重开 重开次数在这之后才会+1
};
#system;
#achievements;
initial({achievements}) {
@@ -23,7 +23,11 @@ class Achievement {
return Object.keys(this.#achievements).length;
}
list(property) {
get #prop() {
return this.#system.request(this.#system.Module.PROPERTY);
}
list() {
return Object
.values(this.#achievements)
.map(({
@@ -32,34 +36,34 @@ class Achievement {
})=>({
id, name, opportunity,
description, hide, grade,
isAchieved: this.isAchieved(id, property),
isAchieved: this.isAchieved(id, this.#prop),
}));
}
get(achievementId) {
const achievement = this.#achievements[achievementId];
if(!achievement) throw new Error(`[ERROR] No Achievement[${achievementId}]`);
return clone(achievement);
return this.#system.clone(achievement);
}
check(achievementId, property) {
check(achievementId) {
const { condition } = this.get(achievementId);
return checkCondition(property, condition);
return this.#system.check(condition);
}
isAchieved(achievementId, property) {
for(const [achieved] of (property.get(property.TYPES.ACHV)||[]))
isAchieved(achievementId) {
for(const [achieved] of (this.#prop.get(this.#prop.TYPES.ACHV)||[]))
if(achieved == achievementId) return true;
return false;
}
achieve(opportunity, property) {
this.list(property)
achieve(opportunity) {
this.list()
.filter(({isAchieved})=>!isAchieved)
.filter(({opportunity: o})=>o==opportunity)
.filter(({id})=>this.check(id, property))
.filter(({id})=>this.check(id, this.#prop))
.forEach(({id})=>{
property.achieve(property.TYPES.ACHV, id)
this.#prop.achieve(this.#prop.TYPES.ACHV, id)
$$event('achievement', this.get(id))
});
}

View File

@@ -1,15 +1,23 @@
import { clone, weightRandom } from '../functions/util.js';
class Character {
constructor() {}
constructor(system) {
this.#system = system;
}
#system;
#characters;
#characterPullCount;
#rateableKnife;
#rate;
#pipe = [];
#uniqueWaTaShi;
#propertyWeight;
#talentWeight
initial({characters}) {
this.#characters = characters;
const uniqueWaTaShi = localStorage.getItem('uniqueWaTaShi');
if(uniqueWaTaShi != null || uniqueWaTaShi != 'undefined')
this.#uniqueWaTaShi = JSON.parse(uniqueWaTaShi);
return this.count;
}
@@ -20,16 +28,70 @@ class Character {
config({
characterPullCount = 3,
rateableKnife = 10,
propertyWeight,
talentWeight,
} = {}) {
this.#characterPullCount = characterPullCount;
this.#rateableKnife = rateableKnife;
this.#propertyWeight = propertyWeight;
this.#talentWeight = talentWeight;
}
get #unique() {
if(this.#uniqueWaTaShi) {
return this.#system.clone(this.#uniqueWaTaShi);
}
const now = Date.now();
this.#pipe.push(now);
if(this.#pipe.length < 10) return null;
const time = this.#pipe.shift();
if(now - time > 10000) return null;
return {unique: true, generate: false};
}
set #unique(data) {
this.#uniqueWaTaShi = this.#system.clone(data);
this.#uniqueWaTaShi.unique = true;
this.#uniqueWaTaShi.generate = true;
localStorage.setItem(
'uniqueWaTaShi',
JSON.stringify(this.#uniqueWaTaShi)
);
}
get #weightRandom() {
return this.#system.function(this.#system.Function.UTIL).weightRandom;
}
generateUnique() {
if(this.#uniqueWaTaShi) return this.#unique;
const weightRandom = this.#weightRandom;
const {CHR, INT, STR, MNY} = this.#system.PropertyTypes;
this.#unique = {
property: {
[CHR]: weightRandom(this.#propertyWeight),
[INT]: weightRandom(this.#propertyWeight),
[STR]: weightRandom(this.#propertyWeight),
[MNY]: weightRandom(this.#propertyWeight),
},
talent: this.#system
.request(this.#system.Module.TALENT)
.random(weightRandom(this.#talentWeight)),
}
return this.#unique;
}
random() {
return this.rateable();
return {
unique: this.#unique,
normal: this.#rateable(),
}
}
rateable() {
#rateable() {
if(!this.#rate) {
this.#rate = {};
for(const id in this.#characters) {
@@ -38,6 +100,7 @@ class Character {
}
const r = [];
const weightRandom = this.#weightRandom;
new Array(this.#characterPullCount)
.fill(0)
.forEach(()=>{
@@ -63,7 +126,7 @@ class Character {
this.#rate[id] -= this.#rateableKnife;
}
}
return r.map(id=>clone(this.#characters[id]));
return r.map(id=>this.#system.clone(this.#characters[id]));
}
}

View File

@@ -1,9 +1,9 @@
import { clone } from '../functions/util.js';
import { checkCondition } from '../functions/condition.js';
class Event {
constructor() {}
constructor(system) {
this.#system = system;
}
#system;
#events;
initial({events}) {
@@ -24,18 +24,18 @@ class Event {
return Object.keys(this.#events).length;
}
check(eventId, property) {
check(eventId) {
const { include, exclude, NoRandom } = this.get(eventId);
if(NoRandom) return false;
if(exclude && checkCondition(property, exclude)) return false;
if(include) return checkCondition(property, include);
if(exclude && this.#system.check(exclude)) return false;
if(include) return this.#system.check(include);
return true;
}
get(eventId) {
const event = this.#events[eventId];
if(!event) throw new Error(`[ERROR] No Event[${eventId}]`);
return clone(event);
return this.#system.clone(event);
}
information(eventId) {
@@ -43,11 +43,11 @@ class Event {
return { description };
}
do(eventId, property) {
do(eventId) {
const { effect, branch, event: description, postEvent, grade } = this.get(eventId);
if(branch)
for(const [cond, next] of branch)
if(checkCondition(property, cond))
if(this.#system.check(cond))
return { effect, next, description, grade };
return { effect, postEvent, description, grade };
}

View File

@@ -1,4 +1,6 @@
import { clone, weightRandom, getListValuesMap, getConvertedMap } from '../functions/util.js'
import * as util from '../functions/util.js';
import * as fCondition from '../functions/condition.js';
import Property from './property.js';
import Event from './event.js';
import Talent from './talent.js';
@@ -7,11 +9,24 @@ import Character from './character.js';
class Life {
constructor() {
this.#property = new Property();
this.#event = new Event();
this.#talent = new Talent();
this.#achievement = new Achievement();
this.#character = new Character();
this.#property = new Property(this);
this.#event = new Event(this);
this.#talent = new Talent(this);
this.#achievement = new Achievement(this);
this.#character = new Character(this);
}
Module = {
PROPERTY: 'PROPERTY',
TALENT: 'TALENT',
EVENT: 'EVENT',
ACHIEVEMENT: 'ACHIEVEMENT',
CHARACTER: 'CHARACTER',
}
Function = {
CONDITION: 'CONDITION',
UTIL: 'UTIL',
}
#property;
@@ -65,24 +80,47 @@ class Life {
this.#character.config(characterConfig);
}
request(module) {
switch (module) {
case this.Module.ACHIEVEMENT: return this.#achievement;
case this.Module.CHARACTER: return this.#character;
case this.Module.EVENT: return this.#event;
case this.Module.PROPERTY: return this.#property;
case this.Module.TALENT: return this.#talent;
default: return null;
}
}
function(type) {
switch (type) {
case this.Function.CONDITION: return fCondition;
case this.Function.UTIL: return util;
}
}
check(condition) {
return fCondition.checkCondition(this.#property,condition);
}
clone(...args) {
return util.clone(...args);
}
remake(talents) {
this.#initialData = clone(this.#defaultPropertys);
this.#initialData.TLT = clone(talents);
this.#initialData = util.clone(this.#defaultPropertys);
this.#initialData.TLT = util.clone(talents);
this.#triggerTalents = {};
return this.talentReplace(this.#initialData.TLT);
}
start(allocation) {
for(const key in allocation) {
this.#initialData[key] = clone(allocation[key]);
this.#initialData[key] = util.clone(allocation[key]);
}
this.#property.restart(this.#initialData);
this.doTalent()
this.#property.restartLastStep();
this.#achievement.achieve(
this.AchievementOpportunity.START,
this.#property
);
this.#achievement.achieve(this.AchievementOpportunity.START);
}
getPropertyPoints() {
@@ -102,10 +140,7 @@ class Life {
const isEnd = this.#property.isEnd();
const content = [talentContent, eventContent].flat();
this.#achievement.achieve(
this.AchievementOpportunity.TRAJECTORY,
this.#property
)
this.#achievement.achieve(this.AchievementOpportunity.TRAJECTORY);
return { age, content, isEnd };
}
@@ -131,7 +166,7 @@ class Life {
const contents = [];
for(const talentId of talents) {
const result = this.#talent.do(talentId, this.#property);
const result = this.#talent.do(talentId);
if(!result) continue;
this.#triggerTalents[talentId] = this.getTalentCurrentTriggerCount(talentId) + 1;
const { effect, name, description, grade } = result;
@@ -148,7 +183,7 @@ class Life {
}
doEvent(eventId) {
const { effect, next, description, postEvent, grade } = this.#event.do(eventId, this.#property);
const { effect, next, description, postEvent, grade } = this.#event.do(eventId);
this.#property.change(this.PropertyTypes.EVT, eventId);
this.#property.effect(effect);
const content = {
@@ -162,7 +197,7 @@ class Life {
}
random(events) {
return weightRandom(
return util.weightRandom(
events.filter(
([eventId])=>this.#event.check(eventId, this.#property)
)
@@ -181,11 +216,12 @@ class Life {
characterRandom() {
const characters = this.#character.random();
characters.forEach(
v=>v.talent=v.talent.map(
id=>this.#talent.get(id)
)
const replaceTalent = v=>v.talent=v.talent.map(
id=>this.#talent.get(id)
);
characters.normal.forEach(replaceTalent);
if(characters.unique && characters.unique.talent)
replaceTalent(characters.unique);
return characters;
}
@@ -197,12 +233,16 @@ class Life {
return this.#talent.exclude(talents, exclusive);
}
generateUnique() {
this.#character.generateUnique();
}
#getJudges(...types) {
return getListValuesMap(types.flat(), key => this.#property.judge(key));
return util.getListValuesMap(types.flat(), key => this.#property.judge(key));
}
#getPropertys(...types) {
return getListValuesMap(types.flat(), key => this.#property.get(key));
return util.getListValuesMap(types.flat(), key => this.#property.get(key));
}
get lastExtendTalent() {
@@ -210,10 +250,7 @@ class Life {
}
get summary() {
this.#achievement.achieve(
this.AchievementOpportunity.SUMMARY,
this.#property
)
this.#achievement.achieve(this.AchievementOpportunity.SUMMARY);
const pt = this.PropertyTypes;
@@ -259,16 +296,13 @@ class Life {
get PropertyTypes() { return this.#property.TYPES; }
get AchievementOpportunity() { return this.#achievement.Opportunity; }
get talentSelectLimit() { return this.#talentSelectLimit; }
get propertyAllocateLimit() { return clone(this.#propertyAllocateLimit); }
get propertyAllocateLimit() { return util.clone(this.#propertyAllocateLimit); }
get propertys() { return this.#property.getPropertys(); }
get times() { return this.#property.get(this.PropertyTypes.TMS) || 0; }
set times(v) {
this.#property.set(this.PropertyTypes.TMS, v);
this.#achievement.achieve(
this.AchievementOpportunity.END,
this.#property
)
this.#achievement.achieve(this.AchievementOpportunity.END);
}
get specialThanks() { return this.#specialThanks; }
}

View File

@@ -1,7 +1,7 @@
import { max, min, sum, clone, listRandom } from '../functions/util.js';
class Property {
constructor() {}
constructor(system) {
this.#system = system;
}
TYPES = {
// 本局
@@ -70,11 +70,16 @@ class Property {
]
}
#system;
#ageData;
#data = {};
#total;
#judge;
get #util() {
return this.#system.function(this.#system.Function.UTIL);
}
initial({age, total}) {
this.#ageData = age;
for(const a in age) {
@@ -151,6 +156,7 @@ class Property {
}
get(prop) {
const util = this.#util;
switch(prop) {
case this.TYPES.AGE:
case this.TYPES.CHR:
@@ -161,14 +167,14 @@ class Property {
case this.TYPES.LIF:
case this.TYPES.TLT:
case this.TYPES.EVT:
return clone(this.#data[prop]);
return util.clone(this.#data[prop]);
case this.TYPES.LAGE:
case this.TYPES.LCHR:
case this.TYPES.LINT:
case this.TYPES.LSTR:
case this.TYPES.LMNY:
case this.TYPES.LSPR:
return min(
return util.min(
this.#data[prop],
this.get(this.fallback(prop))
);
@@ -178,7 +184,7 @@ class Property {
case this.TYPES.HSTR:
case this.TYPES.HMNY:
case this.TYPES.HSPR:
return max(
return util.max(
this.#data[prop],
this.get(this.fallback(prop))
);
@@ -189,7 +195,7 @@ class Property {
const HSTR = this.get(this.TYPES.HSTR);
const HMNY = this.get(this.TYPES.HMNY);
const HSPR = this.get(this.TYPES.HSPR);
return Math.floor(sum(HCHR, HINT, HSTR, HMNY, HSPR)*2 + HAGE/2);
return Math.floor(util.sum(HCHR, HINT, HSTR, HMNY, HSPR)*2 + HAGE/2);
case this.TYPES.TMS:
return this.lsget('times') || 0;
case this.TYPES.EXT:
@@ -253,7 +259,7 @@ class Property {
case this.TYPES.LIF:
case this.TYPES.TLT:
case this.TYPES.EVT:
this.hl(prop, this.#data[prop] = clone(value));
this.hl(prop, this.#data[prop] = this.#system.clone(value));
this.achieve(prop, value);
return;
case this.TYPES.TMS:
@@ -267,7 +273,7 @@ class Property {
}
getPropertys() {
return clone({
return this.#system.clone({
[this.TYPES.AGE]: this.get(this.TYPES.AGE),
[this.TYPES.CHR]: this.get(this.TYPES.CHR),
[this.TYPES.INT]: this.get(this.TYPES.INT),
@@ -315,7 +321,8 @@ class Property {
hookSpecial(prop) {
switch(prop) {
case this.TYPES.RDM: return listRandom(this.SPECIAL.RDM);
case this.TYPES.RDM:
return this.#util.listRandom(this.SPECIAL.RDM);
default: return prop;
}
}
@@ -334,15 +341,6 @@ class Property {
const d = this.#judge[prop];
let length = d.length;
// progress judge
// const p = 1/length;
// const progress = () => {
// const min = d[length][0] || 0;
// const max = d[length+1]?.[0] || value;
// if(max == min) return 1;
// return p * (length + (value - min) / (max - min));
// }
const progress = () => Math.max(Math.min(value, 10), 0) / 10;
while(length--) {
@@ -363,7 +361,7 @@ class Property {
}
getAgeData(age) {
return clone(this.#ageData[age]);
return this.#system.clone(this.#ageData[age]);
}
hl(prop, value) {
@@ -378,8 +376,8 @@ class Property {
default: return;
}
const [l, h] = keys;
this.#data[l] = min(this.#data[l], value);
this.#data[h] = max(this.#data[h], value);
this.#data[l] = this.#util.min(this.#data[l], value);
this.#data[h] = this.#util.max(this.#data[h], value);
}
achieve(prop, newData) {

View File

@@ -1,9 +1,9 @@
import { clone, weightRandom } from '../functions/util.js';
import { checkCondition, extractMaxTriggers } from '../functions/condition.js';
class Talent {
constructor() {}
constructor(system) {
this.#system = system;
}
#system;
#talents;
#talentPullCount;
#talentRate;
@@ -11,11 +11,12 @@ class Talent {
initial({talents}) {
this.#talents = talents;
const emt = this.#system.function(this.#system.Function.CONDITION).extractMaxTriggers;
for(const id in talents) {
const talent = talents[id];
talent.id= Number(id);
talent.grade = Number(talent.grade);
talent.max_triggers = extractMaxTriggers(talent.condition);
talent.max_triggers = emt(talent.condition);
if(talent.replacement) {
for(let key in talent.replacement) {
const obj = {};
@@ -34,6 +35,10 @@ class Talent {
return Object.keys(this.#talents).length;
}
get #prop() {
return this.#system.request(this.#system.Module.PROPERTY);
}
config({
talentPullCount = 10, // number of talents to pull from the talent pool
talentRate = { 1:100, 2:10, 3:1, total: 1000 }, // rate of talent pull
@@ -45,15 +50,15 @@ class Talent {
}
check(talentId, property) {
check(talentId) {
const { condition } = this.get(talentId);
return checkCondition(property, condition);
return this.#system.check(this.#prop, condition);
}
get(talentId) {
const talent = this.#talents[talentId];
if(!talent) throw new Error(`[ERROR] No Talent[${talentId}]`);
return clone(talent);
return this.#system.clone(talent);
}
information(talentId) {
@@ -81,7 +86,7 @@ class Talent {
}
getRate(additionValues = {}) {
const rate = clone(this.#talentRate);
const rate = this.#system.clone(this.#talentRate);
const addition = { 1:1, 2:1, 3:1, };
Object.keys(additionValues).forEach(key => {
@@ -131,6 +136,19 @@ class Talent {
});
}
random(count) {
const talents = Object
.keys(this.#talents)
.filter(id=>!this.#talents[id].exclusive);
return new Array(count)
.fill(1)
.map(()=>talents.splice(
Math.floor(Math.random()*talents.length)%talents.length,
1
)[0]
);
}
allocationAddition(talents) {
if(Array.isArray(talents)) {
let addition = 0;
@@ -141,9 +159,9 @@ class Talent {
return Number(this.get(talents).status) || 0;
}
do(talentId, property) {
do(talentId) {
const { effect, condition, grade, name, description } = this.get(talentId);
if(condition && !checkCondition(property, condition))
if(condition && !this.#system.check(condition))
return null;
return { effect, grade, name, description };
}
@@ -154,7 +172,8 @@ class Talent {
if(!replacement) return null;
const list = [];
if(replacement.grade) {
this.forEach(({id, grade})=>{
this.forEach(({id, grade, exclusive})=>{
if(exclusive) return;
if(!replacement.grade[grade]) return;
if(this.exclude(talents, id)) return;
list.push([id, replacement.grade[grade]]);
@@ -170,16 +189,17 @@ class Talent {
return list;
}
const wr = this.#system.function(this.#system.Function.UTIL).weightRandom;
const replace = (talent, talents) => {
const replaceList = getReplaceList(talent, talents);
if(!replaceList) return talent;
const rand = weightRandom(replaceList);
const rand = wr(replaceList);
return replace(
rand, talents.concat(rand)
);
}
const newTalents = clone(talents);
const newTalents = this.#system.clone(talents);
const result = {};
for(const talent of talents) {
const replaceId = replace(talent, newTalents);
@@ -194,7 +214,7 @@ class Talent {
forEach(callback) {
if(typeof callback != 'function') return;
for(const id in this.#talents)
callback(clone(this.#talents[id]), id);
callback(this.#system.clone(this.#talents[id]), id);
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,14 +1,13 @@
export default class CyberCelebrity extends ui.view.CyberTheme.CelebrityUI {
constructor() {
super();
this.btnRetry.on(Laya.Event.CLICK, this, this.random);
this.btnRetry.on(Laya.Event.CLICK, this, ()=>this.random());
this.btnNext.on(Laya.Event.CLICK, this, this.next);
this.panelCharacter.vScrollBar.elasticDistance = 150;
}
#characters;
#selected;
static #createComponent = Laya.plugin.extractComponents(CyberCelebrity.uiView, ['boxCharacter','boxTalent']);
static #createComponent = Laya.plugin.extractComponents(CyberCelebrity.uiView, ['boxCharacter','boxTalent','boxUniqueUnGenerate']);
#createCharacterItem(dataSource, click) {
const {name, property, talent} = dataSource;
const item = CyberCelebrity.#createComponent('boxCharacter');
@@ -45,6 +44,30 @@ export default class CyberCelebrity extends ui.view.CyberTheme.CelebrityUI {
if(click) item.click(click);
return item;
}
#createUniqueUnGenerateItem(generate) {
const item = CyberCelebrity.#createComponent('boxUniqueUnGenerate');
const boxName = item.getChildByName('boxName');
const vboxStates = item.getChildByName('vboxStates');
const label = vboxStates.getChildByName('label');
const boxBtn = vboxStates.getChildByName('boxBtn');
const btn = boxBtn.getChildByName('btn');
label.event(Laya.Event.RESIZE);
vboxStates.scaleY = 0;
item.dataSource = false;
item.switch = showDetails => vboxStates.scaleY = !!showDetails?1:0;
item.click = (cb, caller) => {
boxName.offAll(Laya.Event.CLICK);
boxName.on(Laya.Event.CLICK, caller || this, cb);
}
item.generate = (cb, caller) => {
btn.offAll(Laya.Event.CLICK);
btn.on(Laya.Event.CLICK, caller || this, cb);
}
if(generate) item.generate(generate);
return item;
}
init() {
this.random();
@@ -55,27 +78,47 @@ export default class CyberCelebrity extends ui.view.CyberTheme.CelebrityUI {
this.vboxCharacter.destroyChildren(true);
}
random() {
random(g) {
this.#selected = null;
this.vboxCharacter.destroyChildren(true);
this.#characters = core.characterRandom();
this.#characters.forEach(character => {
const item = this.#createCharacterItem(character);
const {unique, normal} = core.characterRandom();
const items = [];
const uniqueItem = this.generateUnique(unique, ()=>{
core.generateUnique();
this.random(normal);
});
if(uniqueItem) items.push(uniqueItem);
(g||normal).forEach(character => items.push(this.#createCharacterItem(character)));
items.forEach((item, i) => {
item.y = i;
this.vboxCharacter.addChild(item);
item.click(()=>{
if(this.#selected) this.#selected.switch(false);
this.#selected = item;
item.switch(true);
item.event(Laya.Event.RESIZE);
});
})
});
if(g&&uniqueItem) {
this.#selected = uniqueItem;
uniqueItem.switch(true);
uniqueItem.event(Laya.Event.RESIZE);
}
}
generateUnique(data, generate) {
if(!data) return null;
if(!data.generate) return this.#createUniqueUnGenerateItem(generate);
data.name = $lang.UI_UniqueWaTaShi;
return this.#createCharacterItem(data);
}
next() {
if(!this.#selected) {
$$event('message', ['M_PleaseSelectOne']);
return;
}
if(!this.#selected) return $$event('message', ['M_PleaseSelectOne']);
if(!this.#selected.dataSource) return $$event('message', ['M_UnGenerate']);
const {property: propertyAllocate, talent: talents} = this.#selected.dataSource;
const replace = core.remake(talents.map(talent => talent.id));
if(replace.length > 0) {

View File

@@ -1,14 +1,13 @@
export default class Celebrity extends ui.view.DefaultTheme.CelebrityUI {
constructor() {
super();
this.btnRetry.on(Laya.Event.CLICK, this, this.random);
this.btnRetry.on(Laya.Event.CLICK, this, ()=>this.random());
this.btnNext.on(Laya.Event.CLICK, this, this.next);
this.panelCharacter.vScrollBar.elasticDistance = 150;
}
#characters;
#selected;
static #createComponent = Laya.plugin.extractComponents(Celebrity.uiView, ['boxCharacter','boxTalent']);
static #createComponent = Laya.plugin.extractComponents(Celebrity.uiView, ['boxCharacter','boxTalent','boxUniqueUnGenerate']);
#createCharacterItem(dataSource, click) {
const {name, property, talent} = dataSource;
const style = $ui.common.characterItem;
@@ -47,6 +46,35 @@ export default class Celebrity extends ui.view.DefaultTheme.CelebrityUI {
if(click) item.click(click);
return item;
}
#createUniqueUnGenerateItem(generate) {
const style = $ui.common.characterItem;
const item = Celebrity.#createComponent('boxUniqueUnGenerate');
const boxName = item.getChildByName('boxName');
const vboxStates = item.getChildByName('vboxStates');
const label = vboxStates.getChildByName('label');
const boxBtn = vboxStates.getChildByName('boxBtn');
const btn = boxBtn.getChildByName('btn');
$_.deepMapSet(boxName, style.name);
$_.deepMapSet(vboxStates, style.state);
$_.deepMapSet(btn, style.name);
boxBtn.y = label.height + vboxStates.space;
label.event(Laya.Event.RESIZE);
vboxStates.scaleY = 0;
item.dataSource = false;
item.switch = showDetails => vboxStates.scaleY = !!showDetails?1:0;
item.click = (cb, caller) => {
boxName.offAll(Laya.Event.CLICK);
boxName.on(Laya.Event.CLICK, caller || this, cb);
}
item.generate = (cb, caller) => {
btn.offAll(Laya.Event.CLICK);
btn.on(Laya.Event.CLICK, caller || this, cb);
}
if(generate) item.generate(generate);
return item;
}
init() {
this.random();
@@ -57,27 +85,47 @@ export default class Celebrity extends ui.view.DefaultTheme.CelebrityUI {
this.vboxCharacter.destroyChildren(true);
}
random() {
random(g) {
this.#selected = null;
this.vboxCharacter.destroyChildren(true);
this.#characters = core.characterRandom();
this.#characters.forEach(character => {
const item = this.#createCharacterItem(character);
const {unique, normal} = core.characterRandom();
const items = [];
const uniqueItem = this.generateUnique(unique, ()=>{
core.generateUnique();
this.random(normal);
});
if(uniqueItem) items.push(uniqueItem);
(g||normal).forEach(character => items.push(this.#createCharacterItem(character)));
items.forEach((item, i) => {
item.y = i;
this.vboxCharacter.addChild(item);
item.click(()=>{
if(this.#selected) this.#selected.switch(false);
this.#selected = item;
item.switch(true);
item.event(Laya.Event.RESIZE);
});
})
});
if(g&&uniqueItem) {
this.#selected = uniqueItem;
uniqueItem.switch(true);
uniqueItem.event(Laya.Event.RESIZE);
}
}
generateUnique(data, generate) {
if(!data) return null;
if(!data.generate) return this.#createUniqueUnGenerateItem(generate);
data.name = $lang.UI_UniqueWaTaShi;
return this.#createCharacterItem(data);
}
next() {
if(!this.#selected) {
$$event('message', ['M_PleaseSelectOne']);
return;
}
if(!this.#selected) return $$event('message', ['M_PleaseSelectOne']);
if(!this.#selected.dataSource) return $$event('message', ['M_UnGenerate']);
const {property: propertyAllocate, talent: talents} = this.#selected.dataSource;
const replace = core.remake(talents.map(talent => talent.id));
if(replace.length > 0) {