大侠
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

735 lines
27 KiB

import { EGongFaType, EGongFaTypeZh, EShopType, ESuitType, EWuGongArrTypeZh, GameAbility, GameTotalType, ITEM_TYPE, PropType, TASK_TYPE } from "../const/GameEnum";
import { CONFIDANTE_TYPE, OFFLINE_PARAMS, TREASURE_TYPE } from "../const/GGameData";
import WuGongData from "../const/WuGongData";
import MathUtils from "../ExUtils/MathUtils";
import UIMgr from "../Mgr_UI/UIMgr";
import { TreasureDataProxy } from "./DataTypeProxy/TreasureDataProxy";
import { GameDataProxy } from "./DataTypeProxy/GameDataProxy";
import { BuildsDataProxy } from "./DataTypeProxy/BuildsDataProxy";
import { DateDataProxy } from "./DataTypeProxy/DateDataProxy";
import { IDataArray, IItemsData, ROLE_PARAMS } from "../const/GameInterface";
import MesMgr from "../MesEvent/MesMgr";
import { EGlobalEvent } from "../MesEvent/EGlobalEvent";
import { LocalDataMgr } from "./LocalDataMgr";
import { TaskDataProxy } from "./DataTypeProxy/TaskDataProxy";
import SceneDataMgr from "./SceneDataMgr";
import { Global } from "../Global";
import { TokenDataProxy } from "./DataTypeProxy/TokenDataProxy";
import { BagDataProxy } from "./DataTypeProxy/BagDataProxy";
import { ShopDataProxy } from "./DataTypeProxy/ShopDataProxy";
import Language from "../Language";
import SoulDataMgr from "./SoulDataMgr";
import GDUtils from "../ExCUtils/GDUtils";
import ResLoad from "../ResUrl/ResLoad";
import PlatformManager from "../Platform/PlatformManager";
import PlatformManagerProxy from "../Platform/PlatformManagerProxy";
import Base64 from "./Base/Base64";
import { ISuitEffect } from "../Mgr_CSV/CsvEnum";
import StringUtils from "../ExUtils/StringUtils";
export default class RoleDataMgr {
private static _ins: RoleDataMgr = null;
public static get Ins() {
if (!this._ins) {
this._ins = new RoleDataMgr();
this._ins.init();
}
return this._ins;
}
private get _GameData() {
return GameDataProxy.Ins;
}
private get _data() {
return this._GameData.data;
}
attack_type: number = 0;
attackWuGong: WuGongData = null; // 当前使用的攻击武功
defenseWuGong: WuGongData = null; // 当前使用的防御武功
speedWuGong: WuGongData = null; // 当前使用的轻功
attack: number = 0;
defense: number = 0;
speed: number = 0;
fighting: number = 0;
wugongs: { [key: number]: WuGongData[] } = {}; // 按武功种类分
attainments: { [key: number]: number } = {}; // 武功种类的属性
attackTimes: number = 0;
private _craft: number = 0; // 技能
private _lucky: number = 0; // 幸运
private _weapon: IItemsData;
private _armor: IItemsData;
// private _myRedeemCodeCfg: string[] = [];
suitInfo: { [key: number]: number } = {}; // 每种套装类型的激活数量
suitSkillCD: { [key: number]: number } = {}; // 每种套装技能的CD
suitSkillProp: { [key: number]: number } = {}; // 每种套装技能效果值
skillplaying = false; // 技能是否正在播放
skillSuitCfg:ISuitEffect = null; // 当前已激活技能的套装
skillSuitDesc:string = ""; // 当前技能的描述
init() {
for (let type = EGongFaType.剑法; type <= EGongFaType.内功; type++) {
this.wugongs[type] = [];
this.attainments[type] = 0;
}
for (let i = 0; i < this._data.wugongs.length; i++) {
const tWugong = this._data.wugongs[i];
const WugongPoxy: WuGongData = new WuGongData(tWugong);
this.wugongs[WugongPoxy.config.type].push(WugongPoxy);
}
// 排序武功
for (let type in this.wugongs){
this.order_wugongs(this.wugongs[type]);
}
// 套装信息初始化
for (let i = ESuitType.YinYang; i <= ESuitType.CuiYu; i++) {
this.suitSkillCD[i] = 0;
}
this.initCraftLucky();
this.refreshAttackType();
this.refreshDefense();
this.refreshSpeed();
this.refreshSuit();
for (let type = EGongFaType.剑法; type <= EGongFaType.内功; type++) {
this.refreshAttainment(type);
}
this.refreshFighting();
}
initOfflineInfo(){
// 处理离线时间
this.offlineSeconds = DateDataProxy.Ins.getOfflinetime();
// 计算收益倍率
const multiplier = 1 + 0.01 * (TreasureDataProxy.Ins.getProp1(TREASURE_TYPE.OFFLINE) + LocalDataMgr.Confidante.getProp(CONFIDANTE_TYPE.离线收益));
// 增加挑战时间
LocalDataMgr.Pass.add_PlayedTime(Math.floor(0.3 * this.offlineSeconds * multiplier));
}
rebuild(){
this._craft = 0;
this._lucky = 0;
this.attack_type = 0;
this.attackTimes = 0;
this._weapon = null;
this._armor = null;
this.attackWuGong = null;
this.defenseWuGong = null;
this.speedWuGong = null;
this.wugongs = {};
this.attainments = {};
this.init();
}
addStage(type:number) {
++this._data.stages[type];
MesMgr.event(EGlobalEvent.UP_GONGFA);
UIMgr.Ins.ShowTipsUI(EGongFaTypeZh[type] + "精进+1");
}
//#region 武功相关
// addWuGong() {
// }
// 获得武功
getWugong(type, id): WuGongData {
for (const wugong of this.wugongs[type]) {
if (wugong.id == id) {
return wugong;
}
}
return null;
}
// 是否已学
isLearned(id: number) {
for (let i = 0; i < this._data.wugongs.length; i++) {
if (id == this._data.wugongs[i].id)
return true
}
return false;
}
// 学武功
learnWG(id:number) {
if (this.isLearned(id))
return false;
if(!TaskDataProxy.Ins.isCompleteAllTask()) {
const taskConfig = TaskDataProxy.Ins.task.config;
if(taskConfig.condition === TASK_TYPE.ADD_WUGONG && taskConfig.conditionId === id){
SceneDataMgr.Ins.refreshTaskProgress();
}
}
// const quest = Quest_Data.Instance;
// // 更新任务进度
// if (quest.task) {
// if (quest.task.needType === 7 && quest.task.needId === e) {
// quest.task.update_num(1);
// }
// }
const wg = {id: id, level: 1};
this._data.wugongs.push(wg);
const WugongPoxy: WuGongData = new WuGongData(wg);
this.wugongs[WugongPoxy.config.type].push(WugongPoxy);
const wgname = Language.getValue(WugongPoxy.config.name);
UIMgr.Ins.ShowTipsUI("学会武功:" + (WugongPoxy.config.quality > 1? GDUtils.GetHEXByQualityForStr(wgname, WugongPoxy.config.quality):wgname));
this.refreshWuGong(WugongPoxy.config.type);
ConsoleEx.Log("学会功法:" + WugongPoxy.config.name);
// this.order_wugongs()
// t.levelUp_core()
return true
}
/**
* 对武功数组按ID排序
*/
order_wugongs(wugong: WuGongData[]): void {
wugong.sort((a, b) => b.value_keyAtt - a.value_keyAtt);
}
/**
* 武功升级方法
* @param {EGongFaType} type 武学类型
* @param {number} id 武功ID
*/
levelUpWg(wgdata:WuGongData): void {
// 执行升级核心逻辑
if(wgdata){
let oldattprop = wgdata.value_keyAtt;
wgdata.upgrade();
this.refreshWuGong(wgdata.config.type);
const gfcfg = Global.CsvMgr.GongFa_csv[wgdata.config.type];
// UIMgr.Ins.ShowTipsUI(`战力 +${this.fighting - oldfighting}`);
UIMgr.Ins.ShowTipsUI(`${gfcfg.key_name} <color=#218026>+${wgdata.value_keyAtt - oldattprop}</color>`);
UIMgr.Ins.ShowTipsUI(`${gfcfg.prop1} <color=#218026>+${wgdata.config.overAll}</color>`);
(gfcfg.prop2 && gfcfg.prop2.length > 0) && UIMgr.Ins.ShowTipsUI(`${gfcfg.prop2} <color=#218026>+${wgdata.config.overAll}</color>`);
}
}
/**
* 指定id的武功是否可以升级
* @param {EGongFaType} type 武学类型
* @param type
* @returns
*/
canUpgrade(type:EGongFaType, id: number): {res: number; data: WuGongData} {
let wugong = this.getWugong(type, id);
if (!wugong)
return {res:-1, data:null};
// 检查武学等级是否满足升级条件
if (this.wuxue < wugong.levelUp_condition) {
return {res:2, data:null}; // 武学等级不足
}
if(!LocalDataMgr.Token.checkToken(PropType.eGold, wugong.levelUp_paycoin)){
// UIMgr.Ins.ShowTipsUI("铜钱不足!")
return {res:1, data:null};
}
return {res:0, data:wugong};
}
/**指定类型的武功可否有可以升级的 */
canUpgradeByType(type:EGongFaType){
const wglist:WuGongData[] = this.wugongs[type];
for (let j = 0; j < wglist.length; j++) {
const uplvres = this.canUpgrade(type, wglist[j].id);
if (uplvres.res == 0) {
return true;
}
}
return false;
}
getGongFaArr(type:EGongFaType){
let maxValue: number = 0;
let wuGong: WuGongData = null;
const tList = this.wugongs[type] || [];
for (let i = 0; i < tList.length; i++) {
const wugong = tList[i];
if (wugong.value_keyAtt > maxValue) {
maxValue = wugong.value_keyAtt;
wuGong = wugong;
}
}
return { maxValue, wuGong }
}
getCurrSuitSkillCD(): number {
return this.skillSuitCfg !== null? this.suitSkillCD[this.skillSuitCfg.suit_type] : 9999;
}
private refreshSuit() {
this.skillSuitCfg = null;
// 套装信息初始化
for (let i = ESuitType.YinYang; i <= ESuitType.CuiYu; i++) {
this.suitInfo[i] = 0;
this.suitSkillProp[i] = 0;
}
if(this._weapon){
const wpcfg = Global.CsvMgr.Items_csv[this._weapon.id];
if(wpcfg && wpcfg.suittype > 0){
this.suitInfo[wpcfg.suittype]++;
}
}
if(this._armor){
const arcfg = Global.CsvMgr.Items_csv[this._armor.id];
if(arcfg && arcfg.suittype > 0){
this.suitInfo[arcfg.suittype]++;
}
}
if(this.attackWuGong){
const wgcfg = Global.CsvMgr.Items_csv[this.attackWuGong.id];
if(wgcfg && wgcfg.suittype > 0){
this.suitInfo[wgcfg.suittype]++;
}
}
this.refreshSuitSkillInfo();
}
private refreshSuitSkillInfo(){
let num = 0;
this.skillSuitDesc = "";
for(const key in this.suitInfo){
const lv = this.suitInfo[key];
if(lv <= 0) {
continue;
}
num > 0 && (this.skillSuitDesc += " ");
const cfgs = Global.CsvMgr.Suit_eff_type_csv[key];
const suitname = GDUtils.GetHEXBySuitTypeForStr(cfgs[0].suit_name, Number(key));
// this.suitSkillProp[key] = 0;
let effect = "";
let skillname = "";
if(lv <= cfgs.length - 1){
for(let i = 0; i < cfgs.length; i++){
const cfg = cfgs[i];
if(cfg.level <= lv){
this.suitSkillProp[key] += cfg.prop1;
}
}
effect = StringUtils.format(cfgs[lv - 1].suit_effect, (this.suitSkillProp[key] * 100).toFixed(0));
}else if(lv == cfgs.length){
const cfg = cfgs[cfgs.length - 1];
skillname = cfg.suit_effect;
const precfg = cfgs[cfgs.length - 2];
this.suitSkillProp[key] = precfg.prop1;
effect = `${StringUtils.format(precfg.suit_effect, (this.suitSkillProp[key] * 100).toFixed(0))} ${skillname}`;
this.skillSuitCfg = cfg;
}
this.skillSuitDesc += `${suitname}:${effect}`;
++num;
}
}
refreshAttackType() {
var e = this.attack_type;
this.attack_type = EGongFaType.剑法;
let oldsuit = false;
let newsuit = false;
if (this.weapon) {
this.attack_type = this.weapon.att_type;
}
let oldwgid = 0;
if(this.attackWuGong){
oldwgid = this.attackWuGong.id;
this.attackWuGong.isUseing = false;
oldsuit = Global.CsvMgr.Items_csv[oldwgid].suittype > 0;
}
const ArrObject = this.getGongFaArr(this.attack_type);
let maxAttack = ArrObject.maxValue;
this.attackWuGong = ArrObject.wuGong;
this.attack = maxAttack;
this.weapon && (this.attack += this.weapon.effect);
this.attackWuGong && (this.attackWuGong.isUseing = true);
let usenew = false;
if (this.attackWuGong){
usenew = (oldwgid != 0 && oldwgid != this.attackWuGong.id);
const wugongList = this.wugongs[this.attack_type];
if (usenew && wugongList && wugongList.length > 0){
const index = wugongList.indexOf(this.attackWuGong);
if (index > -1) {
// 从当前位置移除
wugongList.splice(index, 1);
// 放到最前面
wugongList.unshift(this.attackWuGong);
// 新启用的武功
MesMgr.event(EGlobalEvent.USENEW_WUGONG, oldwgid);
// 套装武功相关
newsuit = Global.CsvMgr.Items_csv[this.attackWuGong.id].suittype > 0;
}
}
}
// 套装相关的武功有变化
if(oldsuit || newsuit){
this.refreshSuit();
}
if (ResLoad.allDoen && e && (this.attack_type != e || usenew)) {
//app.manager.toast.pop(f.GONGFA, "当前使用武学:" + EWuGongArrTypeZh[this.attack_type]);
const wgname = Language.getValue(this.attackWuGong.config.name);
UIMgr.Ins.ShowTipsUI("启用武功:" + (this.attackWuGong.config.quality > 1? GDUtils.GetHEXByQualityForStr(wgname, this.attackWuGong.config.quality):wgname));
}
}
refreshDefense() {
const ArrObject = this.getGongFaArr(EGongFaType.内功);
let maxDefense = ArrObject.maxValue;
this.defenseWuGong = ArrObject.wuGong;
this.defense = maxDefense;
if (this.armor) {
this.defense += this.armor.effect;
}
}
refreshSpeed() {
const ArrObject = this.getGongFaArr(EGongFaType.轻功);
let maxSpeed = ArrObject.maxValue;
this.speedWuGong = ArrObject.wuGong;
this.speed = maxSpeed;
}
// 刷新战力
refreshFighting() {
let old = this.fighting;
let t = (this.attainments[this.attack_type] + 1e3) / 1e3
let n = this.attainments[this.attack_type];
this.fighting = Math.floor((this.attack * t + this.defense * (800 + this.attainments[EGongFaType.内功]) / 800) * (this.speed + this.attainments[EGongFaType.轻功] + 2100) / 2100 * .99) + this.attainments[EGongFaType.轻功] + n;
MesMgr.event(EGlobalEvent.REFRESH_FIGHTING, old);
// app.view.doAction(h.REFRESH_FIGHTING);
// e && (this.fighting > e ? app.manager.toast.pop(f.FIGHTING, "战斗力 <color=#218026>提高" + (this.fighting - e) + "点</c>") : this.fighting < e && app.manager.toast.pop(f.FIGHTING, "战斗力 <color=#C82E2E>下降" + (e - this.fighting) + "点</c>"));
}
// 刷新指定武功的属性值
refreshAttainment(type) {
let conftype:CONFIDANTE_TYPE = CONFIDANTE_TYPE.剑法;
switch (type) {
case EGongFaType.剑法:
conftype = CONFIDANTE_TYPE.剑法;
break;
case EGongFaType.刀法:
conftype = CONFIDANTE_TYPE.刀法;
break;
case EGongFaType.枪法:
conftype = CONFIDANTE_TYPE.枪法;
break;
case EGongFaType.轻功:
conftype = CONFIDANTE_TYPE.轻功;
break;
case EGongFaType.内功:
conftype = CONFIDANTE_TYPE.内功;
break;
default:
break;
}
this.attainments[type] = LocalDataMgr.Confidante.getProp(conftype);
for (const wugong of this.wugongs[type]) {
this.attainments[type] += wugong.attainment;
}
}
refreshWuGong(wgtype) {
switch (wgtype) {
case EGongFaType.剑法:
case EGongFaType.刀法:
case EGongFaType.枪法:
this.refreshAttackType();
break;
case EGongFaType.轻功:
this.refreshSpeed();
break;
case EGongFaType.内功:
this.refreshDefense();
break;
default:
break;
}
this.refreshAttainment(wgtype);
this.refreshFighting();
}
// refreshEquip(item) {
// if (item.config.type % 10 === this.attack_type) {
// this.refreshAttackType();
// this.refreshFighting();
// } else if (item.config.type === ITEM_TYPE.ARMOR) {
// this.refreshDefense();
// this.refreshFighting();
// }
// }
getWuGongLevel(wugongId) {
const wugong = this._data.wugongs.find(w => w.id === wugongId);
return wugong ? wugong.level : 0;
}
//#endregion
//#region 商店相关
/**
* 购买物品
* @param item 要购买的物品
* @returns 购买结果状态码:
* 0 - 购买成功
* 1 - 银两不足
* 2 - 背包空间不足或其他限制
* 3 - 商品非法
* 5 - 特殊物品已达携带上限
*/
buyGoods(id: number, shoptype: EShopType = EShopType.普通商店){
const cfg = Global.CsvMgr.Items_csv[id];
// 特殊类型物品(工具类)检查携带上限
if ((cfg.type === ITEM_TYPE.TOOL || cfg.type === ITEM_TYPE.TALISMAN) && BagDataProxy.Ins.getItemCount(id) > 0) {
// ConsoleEx.Log("特殊唯一物品,携带上限已满")
UIMgr.Ins.ShowTipsUI("特殊的唯一物品,携带上限已满")
return 5;
}
// 检查背包空间
if (!BagDataProxy.Ins.haveSpace()) {
// ConsoleEx.Log("背包满了")
UIMgr.Ins.ShowTipsUI("背包满了")
return 2;
}
// 商店安全检查
if (!ShopDataProxy.Ins.safety_check(id, shoptype)) {
UIMgr.Ins.ShowTipsUI("道具不合法,请重进游戏")
return 3;
}
// 计算折扣后价格并检查银两是否足够
const discountedPrice = (cfg.pricetype === 1)? Math.floor(cfg.price * ShopDataProxy.Ins.discount) : cfg.price;
// const discountedPrice = Math.floor(cfg.price * ShopDataProxy.Ins.discount);
if (!TokenDataProxy.Ins.checkToken(cfg.pricetype, discountedPrice)) {
// ConsoleEx.Log("钱不够")
const config = Global.CsvMgr.base_res_csv[cfg.pricetype];
const name = GDUtils.GetHEXByQualityForStr(config.name, config.quality)
UIMgr.Ins.ShowTipsUI(`没有足够的${name}`);
// UIMgr.Ins.ShowTipsUI("没有足够的铜钱")
return 1;
}
// 执行购买操作
BagDataProxy.Ins.addItem(id);
ShopDataProxy.Ins.buyGoods(id, shoptype);
TokenDataProxy.Ins.subToken(cfg.pricetype, discountedPrice);
// UIMgr.Ins.ShowTipsUI(`成功购买${cfg.name}`);
return 0
}
//#endregion
getStage(stageType) {
return this._data.stages[stageType] || 0;
}
// 每50攻击50次,有几率增加对应的武功造诣
addAttackTimes() {
this.attackTimes++;
if (this.attackTimes >= ROLE_PARAMS.STAGE_CHECK_INTERVAL) {
this.attackTimes = 0;
MathUtils.getRandom(ROLE_PARAMS.STAGE_TOTAL_WEIGHT(this.getStage(this.attack_type))) < ROLE_PARAMS.STAGE_UPGRADE_WEIGHT && this.addStage(this.attack_type);
}
}
// 检查指定的兑换码是否已兑换
checkCode(code:string) {
return this._data.redeemCode && this._data.redeemCode.indexOf(code) > -1;
}
// 指定的兑换码是否还能兑换
canRedeemCode(code:string):{code:number,awards:IDataArray} {
const redemData = Global.CsvMgr.GetRedemData();
if(!this.checkCode(code)){
if(redemData && redemData.length > 0){
const platName = PlatformManager.PlatformInstance.platform;
// const codedata = redemData.find(item => item.code === code && (("EPlatformType_" + item.platform) === platName || item.platform === ""));
const codedata = redemData.find(item => item.code === code);
if(codedata){
let loginState = PlatformManager.PlatformInstance.loginState;
if (!loginState.uid && !!loginState.openid) {
loginState.uid = Base64.encode(`${loginState.openid}_10086`)
}
if(codedata.openid === "" || codedata.openid === loginState.uid){
return { code: 1, awards: codedata.awards };
}
}
}
return {code: -1, awards:null};
}else{
return {code: 0, awards:null};
}
}
// 兑换
redeemCode(code:string): boolean {
const resdata = this.canRedeemCode(code);
if(resdata.code === 0){
UIMgr.Ins.ShowTipsUI("兑换失败,请勿重复兑换");
}
else if(resdata.code === 1){
this._data.redeemCode = this._data.redeemCode || [];
this._data.redeemCode.push(code);
GDUtils.DistributeRewards(resdata.awards)
UIMgr.Ins.ShowTipsUI("兑换成功");
for(let i = 0; i < resdata.awards.length; i++) {
const element = resdata.awards[i];
if (element.type === GameTotalType.TOKEN) {
const config = Global.CsvMgr.base_res_csv[element.id];
const name = GDUtils.GetHEXByQualityForStr(`${config.name}+${element.num}`, config.quality)
UIMgr.Ins.ShowTipsUI(`恭喜${name}`);
}else if(element.type === GameTotalType.ABILITY){
if(element.id === GameAbility.SHOP_REFRESH_TIMES){
UIMgr.Ins.ShowTipsUI(`商店刷新次数+${element.num}`);
}
}
}
} else {
UIMgr.Ins.ShowTipsUI("兑换失败,请检查兑换码是否正确");
}
return resdata.code === 1;
}
initCraftLucky(){
this._craft += TreasureDataProxy.Ins.getProp1(TREASURE_TYPE.CRAFT);
this._lucky += TreasureDataProxy.Ins.getProp1(TREASURE_TYPE.LUCKY);
}
refreshCraftLucky(){
let data:{craft: number; lucky: number} = LocalDataMgr.Bag.getItemCraftAndLucky();
this._craft = data.craft + TreasureDataProxy.Ins.getProp1(TREASURE_TYPE.CRAFT);
this._lucky = data.lucky + TreasureDataProxy.Ins.getProp1(TREASURE_TYPE.LUCKY);
}
addCraft(value){
this._craft += value;
this._craft <= 0 && (this._craft = 0);
}
addLucky(value){
this._lucky += value;
this._lucky <= 0 && (this._lucky = 0);
}
get craft() {
return this._craft;
}
get lucky() {
return this._lucky;
}
get offlineSeconds() {
return this._data.offline || 0;
}
set offlineSeconds(value:number) {
this._data.offline = value;
this._GameData.Save();
}
// 武器
get weapon() {
return this._weapon;
}
set weapon(value) {
let oldsuit = false;
let newsuit = false;
if (this._weapon) {
this._weapon.weared = false;
oldsuit = Global.CsvMgr.Items_csv[this._weapon.id].suittype > 0;
}
this._weapon = value;
this._data.weapon = value ? value.uuid : null;
if (value) {
value.weared = true;
newsuit = Global.CsvMgr.Items_csv[this._weapon.id].suittype > 0;
}
// 套装相关的武器有变化
if(oldsuit || newsuit){
this.refreshSuit();
}
this.refreshAttackType();
this.refreshFighting();
this._GameData.Save();
}
// 防具
get armor() {
return this._armor;
}
set armor(value) {
let oldsuit = false;
let newsuit = false;
if (this._armor) {
this._armor.weared = false;
oldsuit = Global.CsvMgr.Items_csv[this._armor.id].suittype > 0;
}
this._armor = value;
this._data.armor = value ? value.uuid : null;
if (value) {
value.weared = true;
newsuit = Global.CsvMgr.Items_csv[this._armor.id].suittype > 0;
}
// 套装相关的防具有变化
if(oldsuit || newsuit){
this.refreshSuit();
}
this.refreshDefense();
this.refreshFighting();
this._GameData.Save();
}
get wuxue() {
return this.attainments[EGongFaType.剑法] + this.attainments[EGongFaType.刀法] + this.attainments[EGongFaType.枪法];
}
// 暴击率
get crit() {
let e = this.getStage(this.attack_type);
return Math.floor(1000 * e / (500 + e)) / 10 + (TreasureDataProxy.Ins.getProp1(TREASURE_TYPE.CRIT) + LocalDataMgr.Confidante.getProp(CONFIDANTE_TYPE.暴击率));
}
// 是否暴击
get isCrit() {
return MathUtils.getRandom(100) < this.crit;
}
// 建筑资源产生的离线收益
get offlineEarn() {
let totalIncome = BuildsDataProxy.Ins.getTotalIncome();
const offlineBonus = 1 + 0.01 * TreasureDataProxy.Ins.getProp1(TREASURE_TYPE.OFFLINE);
return Math.floor(0.3 * this.offlineSeconds * offlineBonus * totalIncome * 3 / 10);
}
// 御器离线收益
get offlineFight() {
const offlineBonus = 1 + 0.01 * TreasureDataProxy.Ins.getProp1(TREASURE_TYPE.OFFLINE);
return SoulDataMgr.Ins.unlock? Math.floor(
this.offlineSeconds * this.fighting * offlineBonus * (0.01 * this.crit + 1) *
SoulDataMgr.Ins.attackSpeed * 10 / 10 / SceneDataMgr.Ins.level.monster.totalHP *
Number(SceneDataMgr.Ins.level.monster.config.bounty) * 0.3 * (40 + SceneDataMgr.Ins.level.config.index) / 40
) : 0;
}
// 商店刷新次数的离线收益
get offlineTimes() {
const offlineBonus = 1 + 0.01 * TreasureDataProxy.Ins.getProp1(TREASURE_TYPE.OFFLINE);
const baseTimes = Math.min(
20 + Math.floor((this.offlineSeconds - OFFLINE_PARAMS.REWARD_TIME) / 20 / 60 * 5),
OFFLINE_PARAMS.MAX_REFRESH_TIMES
);
return Math.floor(baseTimes * offlineBonus);
}
}