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.
837 lines
32 KiB
837 lines
32 KiB
import { math, Skeleton } from "cc";
|
|
import { BOUNTY_PARAMS, ESuitType, EVideoType, FIGHTING_TYPE, GameState, PropType, TASK_TYPE, TRIGGER_TYPE } from "../const/GameEnum";
|
|
import { CONFIDANTE_TYPE, GAME_PARAMS, MUTATE_PARAMS, SOUL_PARAMS, TREASURE_TYPE } from "../const/GGameData";
|
|
import { EGlobalEvent } from "../MesEvent/EGlobalEvent";
|
|
import MesMgr from "../MesEvent/MesMgr";
|
|
import { ITask } from "../Mgr_CSV/CsvEnum";
|
|
import CsvMgr from "../Mgr_CSV/CsvMgr";
|
|
import UIMgr from "../Mgr_UI/UIMgr";
|
|
import { BuildsDataProxy } from "./DataTypeProxy/BuildsDataProxy";
|
|
import { DateDataProxy } from "./DataTypeProxy/DateDataProxy";
|
|
import { GameDataProxy } from "./DataTypeProxy/GameDataProxy";
|
|
import { ShopDataProxy } from "./DataTypeProxy/ShopDataProxy";
|
|
import { TaskDataProxy } from "./DataTypeProxy/TaskDataProxy";
|
|
import { TokenDataProxy } from "./DataTypeProxy/TokenDataProxy";
|
|
import { TreasureDataProxy } from "./DataTypeProxy/TreasureDataProxy";
|
|
import LevelDataPoxy from "./LevelDataPoxy";
|
|
import RoleDataMgr from "./RoleDataMgr";
|
|
import SoulDataMgr from "./SoulDataMgr";
|
|
import { Global } from "../Global";
|
|
import { EUIForms } from "../const/UIFormCnf";
|
|
import AudioUtils from "../Mgr_Audio/AudioUtils";
|
|
import { ESounds } from "../MesEvent/ESounds";
|
|
import { TDAnalyticsMgr } from "../Mgr_Ge/TDAnalyticsMgr";
|
|
import { GEData, GEType } from "../Mgr_Ge/GeDifine";
|
|
import { RedNotice } from "../Mgr_RedPoint/RedNotice";
|
|
import { HomeUIRedEnum, MainRedEnum } from "../Mgr_RedPoint/RedEnumType";
|
|
import { LocalDataMgr } from "./LocalDataMgr";
|
|
import PlatformData from "../Platform/Data/PlatformData";
|
|
import PlatformManager from "../Platform/PlatformManager";
|
|
import { TXSDKMgr } from "../Mgr_Ge/TXSDKMgr";
|
|
import LocalStorage from "./LocalStorage";
|
|
import { MainConfig } from "../../Launch/_MainConfig";
|
|
import { GEAnalyticsMgr } from "../Mgr_Ge/GEAnalyticsMgr";
|
|
import EnemyData from "./EnemyData";
|
|
import MathUtils from "../ExUtils/MathUtils";
|
|
import CySDK from "../Mgr_Ge/CySDK";
|
|
|
|
export default class SceneDataMgr {
|
|
private constructor() { };
|
|
private static _ins: SceneDataMgr = null;
|
|
public static get Ins() {
|
|
if (!this._ins) { this._ins = new SceneDataMgr(); this._ins.init(); }
|
|
return this._ins;
|
|
}
|
|
/**真实的攻速 */
|
|
realSpeed: number = 0;
|
|
bossCD: number = 0;
|
|
lastAttack: number = 0;
|
|
state: GameState;
|
|
attackRecords:number[] = [];
|
|
moduleTags = {};
|
|
autoCD: number = 0;
|
|
clearattackRecordsTime:number = 0;
|
|
timeStart: number = 0;
|
|
level: LevelDataPoxy = null;
|
|
|
|
time_attack:number = 0;
|
|
|
|
// boss关卡相关统计
|
|
boss_start_time: number = 0;
|
|
boss_ad_time: number = 0;
|
|
|
|
// 通关状态
|
|
isPassedState:boolean = false;
|
|
|
|
// 当前的攻击模式
|
|
currTriggerType:TRIGGER_TYPE = TRIGGER_TYPE.MANUALLY;
|
|
|
|
fighting_type: FIGHTING_TYPE = FIGHTING_TYPE.PVE;
|
|
|
|
init() {
|
|
this.autoCD = 0;
|
|
this.time_attack = 0;
|
|
this.timeStart = 0;
|
|
this.state = GameState.Prepare;
|
|
this.realSpeed = SoulDataMgr.Ins.attackSpeed;
|
|
this.level = new LevelDataPoxy(GameDataProxy.Ins.data.mLevelData);
|
|
MesMgr.on(EGlobalEvent.E_MINIGAME_PAUSE, this.onGameState, this);
|
|
MesMgr.on(EGlobalEvent.E_UI_OPEN_CALL_BACK, (uiFormName) => {
|
|
if(uiFormName !== "TipsUI"){
|
|
TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.open_ui, { enter_level_id:this.getRealLevel(), ui_name: uiFormName});
|
|
}
|
|
}, this);
|
|
}
|
|
|
|
rebuild() {
|
|
this.autoCD = 0;
|
|
this.time_attack = 0;
|
|
this.timeStart = 0;
|
|
this.state = GameState.Prepare;
|
|
this.realSpeed = SoulDataMgr.Ins.attackSpeed;
|
|
this.level = new LevelDataPoxy(GameDataProxy.Ins.data.mLevelData);
|
|
// this.level.id = 1;
|
|
// this.level.task_count = 0;
|
|
// this.level.refreshConfig();
|
|
// this.level.reset();
|
|
// this.level.passed = false;
|
|
// MesMgr.off(EGlobalEvent.E_MINIGAME_PAUSE, this.onGameState, this);
|
|
}
|
|
|
|
/**游戏开始 */
|
|
start() {
|
|
this.state = GameState.Playing;
|
|
this.fighting_type = FIGHTING_TYPE.PVE;
|
|
this.resetAutoCD();
|
|
// this.schedule(this.updateOnce, 1);
|
|
// // 初始化商店解锁状态
|
|
// if (!this.model.shop.unlock) {
|
|
// this.model.shop.unlock = true;
|
|
// }
|
|
this.onLevelStart();
|
|
}
|
|
onGameState(pause){
|
|
pause ? this.onGamePause() : this.onGameResume();
|
|
}
|
|
onLevelStart() {
|
|
this.timeStart = DateDataProxy.Ins.seconds;
|
|
}
|
|
// 战斗失败
|
|
onLevelFail() {
|
|
if(this.fighting_type === FIGHTING_TYPE.PVE){
|
|
UIMgr.Ins.ShowUI(EUIForms.DefeatUI)
|
|
const currreallv = this.getRealLevel();
|
|
// 挑战超时失败
|
|
TXSDKMgr.ins.onLevel_Lose(
|
|
{
|
|
level_id: currreallv,
|
|
ad_cnt: this.level.ad_cnt,
|
|
duration: this.level.duration,
|
|
coin_amount: LocalDataMgr.Token.getTokenCount(PropType.eGold)
|
|
}
|
|
);
|
|
CySDK.onLevelFail("normal", `真实关卡:${currreallv}`, this.level.id);
|
|
}else if(this.fighting_type === FIGHTING_TYPE.TRIALBOSS){
|
|
this.state = GameState.Pausing;
|
|
MesMgr.event(EGlobalEvent.BOSS_FAIL);
|
|
}else if(this.fighting_type === FIGHTING_TYPE.MUTATEBOSS){
|
|
UIMgr.Ins.ShowUI(EUIForms.DefeatUI);
|
|
}
|
|
}
|
|
// 正常战斗胜利
|
|
onLevelSuccess(bounty:number, reward:number, bossName:string, bossStory:string, levelid:number){
|
|
UIMgr.Ins.ShowUI(EUIForms.VictoryUI, { param: {fttype:this.fighting_type, coin:bounty, exp:reward, bossName:bossName, bossStory:bossStory, levelid:levelid } })
|
|
}
|
|
|
|
// 当前关卡通关成功
|
|
onPassLevel(){
|
|
const coin = Math.floor(this.level.target.config.bounty);
|
|
TokenDataProxy.Ins.addToken(PropType.eGold, coin);
|
|
|
|
SoulDataMgr.Ins.exp += Math.floor(this.level.exp);
|
|
UIMgr.Ins.ShowTipsUI("缉拿成功,获得铜钱 +" + coin);
|
|
UIMgr.Ins.ShowTipsUI("御剑经验 +" + this.level.exp);
|
|
}
|
|
|
|
/**
|
|
* 重置自动攻击冷却
|
|
*/
|
|
resetAutoCD() {
|
|
if (SoulDataMgr.Ins.unlock) {
|
|
this.autoCD = SoulDataMgr.Ins.attackInterval;
|
|
}
|
|
// 试炼只能手动攻击
|
|
if (this.fighting_type == FIGHTING_TYPE.TRIALBOSS){
|
|
this.autoCD = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Boss战斗失败处理
|
|
*/
|
|
fightBossFail() {
|
|
this.autoCD = 0;
|
|
this.bossCD = 0;
|
|
this.onLevelFail();
|
|
}
|
|
|
|
/**
|
|
* 游戏暂停
|
|
*/
|
|
onGamePause() {
|
|
this.state = GameState.Pausing;
|
|
}
|
|
|
|
/**
|
|
* 游戏恢复
|
|
*/
|
|
onGameResume() {
|
|
this.state = GameState.Playing;
|
|
}
|
|
|
|
/**
|
|
* 每帧更新 @param {number} deltaTime - 时间增量
|
|
*/
|
|
|
|
update(deltaTime:number) {
|
|
if (this.state !== GameState.Playing) return;
|
|
// 自动攻击冷却
|
|
// const level = this.level;
|
|
// if (null != level.target && SoulDataMgr.Ins.unlock && level.target.hp > 0 && this.autoCD > 0) {
|
|
// this.time_attack += 1000 * deltaTime;
|
|
// var t = 1e4 / this.autoCD;
|
|
// this.time_attack >= t && this.onAttackOnce(TRIGGER_TYPE.AUTO, t) && (this.time_attack -= t);
|
|
// }
|
|
// 自动攻击冷却
|
|
if (this.autoCD > 0) {
|
|
this.autoCD -= deltaTime;
|
|
if (this.autoCD <= 0) {
|
|
const remainingTime = this.autoCD;
|
|
this.autoCD += SoulDataMgr.Ins.attackInterval;
|
|
if (this.autoCD <= 0) {
|
|
this.autoCD = SoulDataMgr.Ins.attackInterval;
|
|
}
|
|
!RoleDataMgr.Ins.skillplaying && this.onAttackOnce(TRIGGER_TYPE.AUTO, remainingTime);
|
|
}
|
|
}
|
|
|
|
if (this.attackRecords.length >= 0 && this.clearattackRecordsTime > 0) {
|
|
this.clearattackRecordsTime = Math.max(0, this.clearattackRecordsTime - deltaTime);
|
|
if (this.clearattackRecordsTime === 0) {
|
|
this.attackRecords.shift();
|
|
this.refalshAttackSpeed();
|
|
}
|
|
}
|
|
|
|
// Boss战斗冷却
|
|
if (!RoleDataMgr.Ins.skillplaying && this.bossCD > 0) {
|
|
this.bossCD -= deltaTime;
|
|
if (this.bossCD <= 0) {
|
|
this.bossCD = 0;
|
|
// 正常关卡boss战失败,50%触发异兽
|
|
if(this.fighting_type === FIGHTING_TYPE.PVE && LocalDataMgr.Mutate.unlock && MathUtils.randomRangeInt(0,100) < Global.CsvMgr.cnf_discretization_csv[3].num1){
|
|
LocalDataMgr.Mutate.triggerMTFight(this.level.boss.config, false, "boss失败50%");
|
|
}
|
|
this.fightBossFail();
|
|
}
|
|
}
|
|
|
|
// 商店冷却
|
|
if (ShopDataProxy.Ins.data.cd > 0) {
|
|
ShopDataProxy.Ins.data.cd -= deltaTime;
|
|
if (ShopDataProxy.Ins.data.cd <= 0) {
|
|
ShopDataProxy.Ins.addTimes();
|
|
}
|
|
}
|
|
|
|
// 投资建筑收益计算
|
|
const buildings = BuildsDataProxy.Ins.buildings;
|
|
for (const buildingId in buildings) {
|
|
const building = buildings[buildingId];
|
|
if (building.cd > 0) {
|
|
building.cd -= deltaTime;
|
|
if (building.cd <= 0) {
|
|
building.earnOnce();
|
|
MesMgr.event(EGlobalEvent.EARN_ONCE, building);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 套装技能冷却
|
|
for (const suittype in RoleDataMgr.Ins.suitSkillCD) {
|
|
RoleDataMgr.Ins.suitSkillCD[suittype] -= deltaTime;
|
|
if (RoleDataMgr.Ins.suitSkillCD[suittype] <= 0) {
|
|
RoleDataMgr.Ins.suitSkillCD[suittype] = 0;
|
|
}
|
|
}
|
|
|
|
// 游戏时长刷新
|
|
// this.level.add_PlayedTime(deltaTime);
|
|
}
|
|
|
|
refalshAttackSpeed(){
|
|
if (this.attackRecords.length > 0) {
|
|
// 计算实时攻击速度
|
|
let totalInterval = 0;
|
|
for (const interval of this.attackRecords) {
|
|
totalInterval += interval;
|
|
}
|
|
this.realSpeed = this.attackRecords.length / totalInterval;
|
|
//this.realSpeed = Math.max(this.realSpeed, SoulDataMgr.Ins.attackSpeed);
|
|
} else {
|
|
this.realSpeed = SoulDataMgr.Ins.attackSpeed
|
|
}
|
|
MesMgr.event(EGlobalEvent.REFRESH_SPEED);
|
|
this.clearattackRecordsTime = 0.5;
|
|
}
|
|
|
|
|
|
onAttack(triggerType: TRIGGER_TYPE, anispeeds, currentTime, callback?) {
|
|
this.currTriggerType = triggerType;
|
|
// 增加攻击次数
|
|
RoleDataMgr.Ins.addAttackTimes();
|
|
let damage = RoleDataMgr.Ins.fighting;
|
|
// 御剑自动攻击珍宝加成
|
|
if (SoulDataMgr.Ins.unlock && triggerType === TRIGGER_TYPE.AUTO) {
|
|
const soulBonus = TreasureDataProxy.Ins.getProp1(TREASURE_TYPE.SOUL);
|
|
damage += damage * soulBonus * 0.01;
|
|
}
|
|
|
|
let finalDamage = damage;
|
|
|
|
// 根据战斗模式获取攻击目标
|
|
let target: EnemyData = null;//this.fighting_type === FIGHTING_TYPE.PVE ? this.level.target : LocalDataMgr.Trial.getTrialBoss();
|
|
switch (this.fighting_type) {
|
|
case FIGHTING_TYPE.PVE:
|
|
target = this.level.target
|
|
break;
|
|
case FIGHTING_TYPE.TRIALBOSS:
|
|
target = LocalDataMgr.Trial.getTrialBoss();
|
|
break;
|
|
case FIGHTING_TYPE.MUTATEBOSS:
|
|
target = LocalDataMgr.Mutate.getMutateBoss();
|
|
break;
|
|
}
|
|
if(!target){
|
|
ConsoleEx.Log("attack target is null");
|
|
// callback && callback(null);
|
|
return false;
|
|
}
|
|
|
|
// Boss或异兽防御减免
|
|
const isBossOrMutate = (target.config.boss || this.fighting_type === FIGHTING_TYPE.MUTATEBOSS);
|
|
if (isBossOrMutate) {
|
|
finalDamage += (finalDamage * LocalDataMgr.Confidante.getProp(CONFIDANTE_TYPE.挑战boss战力) * 0.01);
|
|
const defenseType = `defense_${RoleDataMgr.Ins.attack_type}`;
|
|
const defenseReduction = 1 - 0.01 * target.config[defenseType];
|
|
finalDamage *= defenseReduction;
|
|
}
|
|
|
|
// 试炼模式,伤害加成
|
|
if(this.fighting_type === FIGHTING_TYPE.TRIALBOSS){
|
|
finalDamage *= (1 + LocalDataMgr.Pass.passed_times * 0.05)
|
|
}
|
|
|
|
// 暴击判断
|
|
const isCritical = RoleDataMgr.Ins.isCrit;
|
|
if (isCritical) {
|
|
finalDamage *= 2;
|
|
}
|
|
|
|
// 如果是技能攻击,直接基础战力*对应的值
|
|
if(triggerType == TRIGGER_TYPE.SKILL && RoleDataMgr.Ins.skillSuitCfg){
|
|
finalDamage = RoleDataMgr.Ins.fighting * RoleDataMgr.Ins.skillSuitCfg.prop1;
|
|
target.hp = Math.max(0, target.hp - finalDamage);
|
|
}else{
|
|
// 套装伤害加成
|
|
finalDamage *= (1 + RoleDataMgr.Ins.suitSkillProp[ESuitType.LieYan]);
|
|
// 最终伤害向上取整
|
|
finalDamage = Math.ceil(finalDamage);
|
|
// 正常伤害计算流程
|
|
if(this.fighting_type === FIGHTING_TYPE.TRIALBOSS){
|
|
let damage = Math.min(2 * LocalDataMgr.Role.fighting, finalDamage);
|
|
const currhp = Math.max(0, target.hp - damage);
|
|
LocalDataMgr.Trial.setTrialBossHp(currhp);
|
|
}else{
|
|
target.hp = Math.max(0, target.hp - finalDamage);
|
|
}
|
|
}
|
|
// callback && callback(target, finalDamage, isCritical);
|
|
// 非技能攻击,播放常规攻击动画
|
|
triggerType !== TRIGGER_TYPE.SKILL && MesMgr.event(EGlobalEvent.ROLE_PLAY_ANIMATION, anispeeds);
|
|
MesMgr.event(EGlobalEvent.ATTACK_ONCE, triggerType, finalDamage, isCritical);
|
|
// 目标死亡处理
|
|
const isdeadd = target.hp <= 0;
|
|
MesMgr.event(EGlobalEvent.ROLE_ENEMY_HIT_ANI, isdeadd, isBossOrMutate, anispeeds);
|
|
if (isdeadd) {
|
|
if(this.fighting_type === FIGHTING_TYPE.PVE){
|
|
const taskConfig = TaskDataProxy.Ins.task.config;
|
|
const level = this.level;
|
|
if (target.config.boss) {
|
|
this._handleBossDefeat(level, taskConfig);
|
|
} else {
|
|
this._handleNormalEnemyDefeat(currentTime, level, taskConfig);
|
|
}
|
|
}else if(this.fighting_type === FIGHTING_TYPE.TRIALBOSS){
|
|
ConsoleEx.Com("试炼boss战斗结束")
|
|
this.fightBossFail();
|
|
}else if(this.fighting_type === FIGHTING_TYPE.MUTATEBOSS){
|
|
ConsoleEx.Com("异兽战斗结束")
|
|
this._mutateBossDefeat(target);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 执行一次攻击
|
|
* @param {number} triggerType - 触发类型
|
|
* @param {number} remainingTime - 剩余时间
|
|
*/
|
|
onAttackOnce(triggerType: TRIGGER_TYPE, remainingTime = 0): boolean {
|
|
this.currTriggerType = triggerType;
|
|
if (this.state !== GameState.Playing) return;
|
|
// 非试炼模式下,手动攻击时重置自动攻击冷却
|
|
if (SoulDataMgr.Ins.unlock && triggerType === TRIGGER_TYPE.MANUALLY && this.fighting_type !== FIGHTING_TYPE.TRIALBOSS) {
|
|
this.autoCD = 1.5;
|
|
}
|
|
|
|
const currentTime = performance.now() / 1000 + remainingTime;
|
|
const lastAttackTime = this.lastAttack;
|
|
|
|
// 攻击频率限制检查
|
|
if (currentTime - lastAttackTime < 1 / SOUL_PARAMS.MAX_SPEED) {
|
|
if (SoulDataMgr.Ins.unlock && triggerType === TRIGGER_TYPE.AUTO) {
|
|
this.autoCD = 1 / SOUL_PARAMS.MAX_SPEED - (currentTime - lastAttackTime);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
// 记录攻击时间
|
|
this.lastAttack = currentTime;
|
|
|
|
// 维护攻击记录队列
|
|
if (lastAttackTime) {
|
|
if (this.attackRecords.length >= 20) {
|
|
this.attackRecords.shift();
|
|
}
|
|
const attackInterval = triggerType === TRIGGER_TYPE.AUTO ?
|
|
SoulDataMgr.Ins.attackInterval :
|
|
Math.max(1 / SOUL_PARAMS.MAX_SPEED, Math.min(0.3, currentTime - lastAttackTime));
|
|
|
|
this.attackRecords.push(attackInterval);
|
|
this.refalshAttackSpeed();
|
|
}
|
|
|
|
const currentAttackInterval = Math.min(0.3, SoulDataMgr.Ins.attackInterval);
|
|
const currentAttackSpeed = 1 / currentAttackInterval;
|
|
|
|
// 使用 clamp 和线性插值
|
|
const clampedSpeed = Math.min(Math.max(currentAttackSpeed, SOUL_PARAMS.SPEED), SOUL_PARAMS.MAX_SPEED);
|
|
const speedRatio = (clampedSpeed - SOUL_PARAMS.SPEED) / (SOUL_PARAMS.MAX_SPEED - SOUL_PARAMS.SPEED);
|
|
const anispeeds = 2.5 + speedRatio * 2;
|
|
|
|
return this.onAttack(triggerType, anispeeds, currentTime);
|
|
}
|
|
|
|
/**
|
|
* 处理Boss击败
|
|
* @private
|
|
*/
|
|
_handleBossDefeat(level: LevelDataPoxy, taskConfig:ITask) {
|
|
const currreallv = this.getRealLevel();
|
|
// 通关关卡
|
|
TXSDKMgr.ins.onLevel_Pass(
|
|
{
|
|
level_id: currreallv,
|
|
ad_cnt: this.level.ad_cnt,
|
|
duration: this.level.duration,
|
|
coin_amount: LocalDataMgr.Token.getTokenCount(PropType.eGold)
|
|
}
|
|
);
|
|
// 打boss胜利统计
|
|
const data = {
|
|
ad_name: (this.boss_ad_time? EVideoType.CritSoul : "无"),
|
|
adcnt: this.boss_ad_time,
|
|
enter_level_id: currreallv,
|
|
}
|
|
TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.level_pass, data);
|
|
GEAnalyticsMgr.ins.TrySendtrack(GEType.level_pass, currreallv);
|
|
CySDK.onLevelSuccess("normal", `真实关卡:${currreallv}`, level.id);
|
|
|
|
// 奖励发放
|
|
this.state = GameState.Pausing;
|
|
// TokenDataProxy.Ins.addToken(PropType.eGold, level.target.config.bounty)
|
|
const bounty = level.target.config.bounty;
|
|
const reward = level.bossConfig.reward;
|
|
const bossname = level.bossConfig.name;
|
|
const story = level.bossConfig.story;
|
|
const levelKeys = Object.keys(CsvMgr.Level_csv);
|
|
// const currentIndex = level.index;
|
|
const lastLevelId = Number(levelKeys[levelKeys.length - 1]);
|
|
const currentLevelId = Number(level.id);
|
|
// let newIndex = currentIndex;
|
|
level.task_count = 0;
|
|
level.id++;
|
|
// 超过最大关卡,通关
|
|
if (currentLevelId >= lastLevelId) {
|
|
level.passed = true;
|
|
this.isPassedState = true;
|
|
// 首次通关,奖励一个玄武符
|
|
if(LocalDataMgr.Pass.passed_times === 1){
|
|
TokenDataProxy.Ins.addToken(PropType.eAdopt, 1);
|
|
UIMgr.Ins.ShowTipsUI("恭喜首次通关,奖励:玄武符+1");
|
|
}else{
|
|
UIMgr.Ins.ShowTipsUI("恭喜通关!!");
|
|
}
|
|
}
|
|
|
|
// 自动挂机解锁检查
|
|
if (!SoulDataMgr.Ins.unlock && level.id === SOUL_PARAMS.UNLOCK_LEVEL) {
|
|
this.onUnlockSoul();
|
|
}
|
|
// 异兽解锁检查
|
|
if (!LocalDataMgr.Mutate.unlock && level.id === MUTATE_PARAMS.UNLOCK_LEVEL){
|
|
LocalDataMgr.Mutate.unlockMT();
|
|
}
|
|
this.autoCD = 0;
|
|
this.bossCD = 0;
|
|
// 御剑经验奖励
|
|
const expBonus = 1 + 0.01 * TreasureDataProxy.Ins.getProp2(TREASURE_TYPE.SOUL);
|
|
SoulDataMgr.Ins.exp += Math.floor(level.exp * expBonus);
|
|
MesMgr.event(EGlobalEvent.BOSS_SUCCESS);
|
|
setTimeout(() => {
|
|
this.onLevelSuccess(bounty, reward, bossname, story, currentLevelId);
|
|
}, 2000);
|
|
/**关卡通关 */
|
|
// 任务进度更新
|
|
if (taskConfig && (taskConfig.condition === TASK_TYPE.BOSS || taskConfig.condition === TASK_TYPE.XIAOGUAI)) {
|
|
this.refreshTaskProgress();
|
|
}
|
|
// 进入新关卡
|
|
TXSDKMgr.ins.onLevel_Enter(
|
|
{
|
|
level_id: this.getRealLevel(),
|
|
enter_level_name:level.displayName,
|
|
coin_amount:LocalDataMgr.Token.getTokenCount(PropType.eGold)
|
|
}
|
|
);
|
|
// this.onGameResume();
|
|
/**远程存档标记 */
|
|
//app.service.archive.checkRemote();
|
|
}
|
|
|
|
/**
|
|
* 处理普通敌人击败
|
|
* @private
|
|
*/
|
|
_handleNormalEnemyDefeat(currentTime, level: LevelDataPoxy, taskConfig) {
|
|
|
|
// 自动攻击冷却调整
|
|
if (SoulDataMgr.Ins.unlock) {
|
|
this.autoCD += 0.2;
|
|
this.lastAttack = currentTime + 0.2;
|
|
}
|
|
|
|
level.target.reset();
|
|
level.task_count++;
|
|
|
|
// 任务完成奖励
|
|
if (level.task_count >= BOUNTY_PARAMS.TARGET) {
|
|
level.task_count = 0;
|
|
MesMgr.event(EGlobalEvent.ENEMY_DEATH_COIN, level.task_money, 1);
|
|
TokenDataProxy.Ins.addToken(PropType.eGold, level.task_money)
|
|
// LocalStorage.CheckSaveServerData();
|
|
}
|
|
|
|
// 套装金币掉落加成
|
|
const bounty = Math.floor(level.target.config.bounty * (1 + RoleDataMgr.Ins.suitSkillProp[ESuitType.CuiYu]));
|
|
TokenDataProxy.Ins.addToken(PropType.eGold, bounty);
|
|
MesMgr.event(EGlobalEvent.ENEMY_DEATH_COIN, bounty, 0);
|
|
// 套装源气掉落
|
|
const dropRate = RoleDataMgr.Ins.suitSkillProp[ESuitType.YinYang] * 100;
|
|
const nowtimes = Date.now();
|
|
if(dropRate > 0 && LocalDataMgr.Game.SuitDropTJTotle > 0 && nowtimes > LocalDataMgr.Game.SuitDropTimes){
|
|
const rand = MathUtils.randomRangeInt(0, 100);
|
|
const isdrop = rand < dropRate;
|
|
if(isdrop){
|
|
LocalDataMgr.Game.SuitDropTJTotle--;
|
|
LocalDataMgr.Game.SuitDropTimes = nowtimes + GAME_PARAMS.DROPTJLIMIT;
|
|
TokenDataProxy.Ins.addToken(PropType.eTaiJi,1);
|
|
UIMgr.Ins.ShowTipsUI("套装效果:掉落源气一颗");
|
|
MesMgr.event(EGlobalEvent.ENEMY_TJ_COIN, 1);
|
|
ConsoleEx.Log(`套装效果:掉落源气一颗,rand:${rand},dropRate:${dropRate},今日还可掉落源气${LocalDataMgr.Game.SuitDropTJTotle}个`);
|
|
}
|
|
// if(SoulDataMgr.Ins.crit){
|
|
// const weigthnum = 10
|
|
// const randomRewardnum = math.randomRange(1,drop)
|
|
// if(randomRewardnum < weigthnum){
|
|
// TokenDataProxy.Ins.addToken(PropType.eTaiJi,1)
|
|
// UIMgr.Ins.ShowTipsUI("掉落源气一颗")
|
|
// MesMgr.event(EGlobalEvent.ENEMY_TJ_COIN, 1);
|
|
// }
|
|
// //测试MesMgr.event(EGlobalEvent.ENEMY_TJ_COIN, 1);
|
|
// }
|
|
// else{
|
|
// const weigthnum = 5
|
|
// const randomRewardnum = math.randomRange(1,drop)
|
|
// if(randomRewardnum < weigthnum){
|
|
// TokenDataProxy.Ins.addToken(PropType.eTaiJi,1)
|
|
// UIMgr.Ins.ShowTipsUI("掉落源气一颗")
|
|
// MesMgr.event(EGlobalEvent.ENEMY_TJ_COIN, 1);
|
|
// }
|
|
// }
|
|
}
|
|
MesMgr.event(EGlobalEvent.REFRESH_XIAOGUAI);
|
|
// 小怪任务进度更新
|
|
if (taskConfig && taskConfig.condition === TASK_TYPE.XIAOGUAI && taskConfig.conditionId === level.id) {
|
|
this.refreshTaskProgress(1);
|
|
}
|
|
|
|
// 正常关卡打完小怪,10%触发异兽
|
|
if(this.fighting_type === FIGHTING_TYPE.PVE && LocalDataMgr.Mutate.unlock &&
|
|
MathUtils.randomRangeInt(0,100) < Global.CsvMgr.cnf_discretization_csv[1].num1 && !LocalDataMgr.Mutate.isAlive()){
|
|
LocalDataMgr.Mutate.triggerMTFight(this.level.boss.config, false, "小怪10%") && MesMgr.event(EGlobalEvent.REFRESH_MUTATE);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 处理异兽击败
|
|
* @private
|
|
*/
|
|
_mutateBossDefeat(target: EnemyData) {
|
|
// 奖励发放
|
|
this.state = GameState.Pausing;
|
|
this.autoCD = 0;
|
|
this.bossCD = 0;
|
|
LocalDataMgr.Mutate.refreshCD();
|
|
MesMgr.event(EGlobalEvent.BOSS_SUCCESS);
|
|
LocalDataMgr.Token.addToken(PropType.eSLStone, target.realReward);
|
|
LocalDataMgr.Token.addToken(PropType.eGold, target.realCoin);
|
|
setTimeout(() => {
|
|
UIMgr.Ins.ShowUI(EUIForms.VictoryUI, { param: {fttype:this.fighting_type, coin:target.realCoin, sl:target.realReward} });
|
|
}, 2000);
|
|
}
|
|
|
|
//#region 常规战斗
|
|
/**准备攻击Boss */
|
|
onAttackBoss() {
|
|
Global.Audio.playBgm(ESounds.So_boss)
|
|
const level = this.level;
|
|
level.monster.fighting = false;
|
|
level.boss.fighting = true;
|
|
level.boss.reset();
|
|
this.bossCD = level.boss.config.duration;
|
|
this.resetAutoCD();
|
|
MesMgr.event(EGlobalEvent.REFRESH_FIGHT);
|
|
this.boss_ad_time = 0;
|
|
this.boss_start_time = Date.now();
|
|
const reallv = this.getRealLevel();
|
|
TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.level_enter,{enter_level_id: reallv});
|
|
GEAnalyticsMgr.ins.TrySendtrack(GEType.level_enter,{level_id:reallv});
|
|
CySDK.onLevelStart("normal", `真实关卡:${reallv}`, level.id);
|
|
}
|
|
|
|
/**
|
|
* 战斗撤退或失败
|
|
*/
|
|
onFightRetreat() {
|
|
Global.Audio.playBgm(ESounds.So_bgm)
|
|
const level = this.level;
|
|
level.monster.fighting = true;
|
|
level.boss.fighting = false;
|
|
this.bossCD = 0;
|
|
this.resetAutoCD();
|
|
this.onGameResume();
|
|
this.onLevelStart();
|
|
MesMgr.event(EGlobalEvent.REFRESH_FIGHT);
|
|
this.boss_ad_time = this.boss_start_time = 0;
|
|
}
|
|
|
|
/**战斗总结完成 */
|
|
onSummaryComplete(resetLevel = false) {
|
|
Global.Audio.playBgm(ESounds.So_bgm)
|
|
const level = this.level;
|
|
if (resetLevel) {
|
|
level.reset();
|
|
}
|
|
level.monster.fighting = true;
|
|
level.boss.fighting = false;
|
|
this.resetAutoCD();
|
|
this.onGameResume();
|
|
this.onLevelStart();
|
|
// 只有过了第一关才自动弹出添加桌面
|
|
if(level.id === 2){
|
|
const isAdd = PlatformManager.PlatformInstance.isAddShortcut;
|
|
const getnum = LocalDataMgr.Game.getAddShortCutNum();
|
|
(!isAdd && getnum === 0) && UIMgr.Ins.ShowUI(EUIForms.AddShortCutUI);
|
|
}
|
|
// 打完boss,100触发异兽
|
|
if(this.fighting_type === FIGHTING_TYPE.PVE && LocalDataMgr.Mutate.unlock){
|
|
LocalDataMgr.Mutate.triggerMTFight(level.boss.config, true, "boss成功100%");
|
|
}
|
|
MesMgr.event(EGlobalEvent.ENTER_NEW_SCENE);
|
|
MesMgr.event(EGlobalEvent.REFRESH_FIGHT);
|
|
this.boss_ad_time = this.boss_start_time = 0;
|
|
LocalStorage.CheckSaveServerData();
|
|
}
|
|
//#endregion
|
|
|
|
|
|
//#region 试炼战斗
|
|
/**准备攻击试炼Boss */
|
|
onAttackTrialBoss(){
|
|
Global.Audio.playBgm(ESounds.So_boss)
|
|
this.fighting_type = FIGHTING_TYPE.TRIALBOSS;
|
|
this.resetAutoCD();
|
|
const boss = LocalDataMgr.Trial.getTrialBoss()
|
|
this.bossCD = boss.config.duration;
|
|
MesMgr.event(EGlobalEvent.CHANGE_FIGHTING_TYPE);
|
|
this.boss_start_time = Date.now();
|
|
const trialinfo = LocalDataMgr.Trial.getCurrTrialInfo();
|
|
TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.finaltral_start,{
|
|
enter_level_id: this.getRealLevel(),
|
|
type: trialinfo.name,
|
|
hp: trialinfo.prohp,
|
|
});
|
|
}
|
|
|
|
/**试炼挑战完毕 */
|
|
onTrialChallengeDone(){
|
|
this.fighting_type = FIGHTING_TYPE.PVE;
|
|
this.onFightRetreat();
|
|
const trialinfo = LocalDataMgr.Trial.getCurrTrialInfo();
|
|
const passtime = Math.floor((Date.now() - this.boss_start_time) / 1000);
|
|
const data = {
|
|
death: trialinfo.death,
|
|
enter_level_id: this.getRealLevel(),
|
|
hp: trialinfo.prohp,
|
|
type: trialinfo.name,
|
|
// passtime: passtime
|
|
}
|
|
TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.finaltral_finsh, data);
|
|
}
|
|
//#endregion
|
|
|
|
|
|
//#region 异兽战斗
|
|
/**准备开始异兽战斗 */
|
|
onAttackMutateBoss() {
|
|
this.fighting_type = FIGHTING_TYPE.MUTATEBOSS;
|
|
this.resetAutoCD();
|
|
const boss = LocalDataMgr.Mutate.getMutateBoss();
|
|
boss.reset();
|
|
this.bossCD = boss.duration;
|
|
MesMgr.event(EGlobalEvent.CHANGE_FIGHTING_TYPE);
|
|
Global.Audio.playEffect({ bundle: "Sound", url: boss.config.audio });
|
|
// switch(boss.config.audio){
|
|
// case "beast_001":
|
|
// Global.Audio.playEffect(ESounds.So_beast_001)
|
|
// break;
|
|
// case "beast_002":
|
|
// Global.Audio.playEffect(ESounds.So_beast_002)
|
|
// break;
|
|
// case "beast_003":
|
|
// Global.Audio.playEffect(ESounds.So_beast_003)
|
|
// break;
|
|
// }
|
|
LocalDataMgr.Game.FreeChallengeTimes--;
|
|
TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.beast_enter,{
|
|
enter_level_id: LocalDataMgr.Scene.getRealLevel(),
|
|
beast_id: boss.config.id,
|
|
beast_showtype: boss.tgDesc,
|
|
beast_reward: boss.realReward,
|
|
});
|
|
}
|
|
|
|
/**异兽战斗结束 */
|
|
onMutateBossDone(result:boolean) {
|
|
this.fighting_type = FIGHTING_TYPE.PVE;
|
|
this.onFightRetreat();
|
|
const boss = LocalDataMgr.Mutate.getMutateBoss();
|
|
TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.beast_finish,{
|
|
beast_id: boss.config.id,
|
|
beast_showtype: boss.tgDesc,
|
|
beast_reward: boss.realReward,
|
|
beast_end: result?"成功":"失败",
|
|
});
|
|
if(result){
|
|
LocalDataMgr.Mutate.onMutateBossDone();
|
|
LocalStorage.CheckSaveServerData();
|
|
}
|
|
}
|
|
//#endregion
|
|
|
|
/**
|
|
* 解锁灵魂系统
|
|
* @param {boolean} [isAD=false] 是否需要看广告解锁
|
|
*/
|
|
onUnlockSoul(isAD = false) {
|
|
if (isAD){
|
|
Global.showvideo({name: EVideoType.UnlockSoul, gamelv: this.getRealLevel()},()=>{
|
|
SoulDataMgr.Ins.unlock = true;
|
|
// SoulDataMgr.Ins.level = 1;
|
|
this.resetAutoCD();
|
|
MesMgr.event(EGlobalEvent.UNLOCK_SOUL);
|
|
TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.autoattack_unlock,{
|
|
enter_level_id: this.level.id,
|
|
unlock_type: (MainConfig.isNoAD && MainConfig.isGmOpen)? "gm免广解锁" : "广告解锁",
|
|
});
|
|
});
|
|
}else if(this.level.id === SOUL_PARAMS.UNLOCK_LEVEL){
|
|
SoulDataMgr.Ins.unlock = true;
|
|
this.resetAutoCD();
|
|
MesMgr.event(EGlobalEvent.UNLOCK_SOUL);
|
|
TDAnalyticsMgr.ins.TrySendtrack(GEData.GEeventName.autoattack_unlock,{
|
|
enter_level_id: this.level.id,
|
|
unlock_type: "第三关解锁",
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 灵魂暴击
|
|
*/
|
|
onSoulCrit() {
|
|
SoulDataMgr.Ins.setCrit();
|
|
if(this.level.boss.fighting){
|
|
this.boss_ad_time++;
|
|
}
|
|
this.level.ad_cnt++;
|
|
}
|
|
|
|
/**
|
|
* 单次更新(用于暴击检查)
|
|
*/
|
|
updateOnce() {
|
|
if (this.state === GameState.Playing && SoulDataMgr.Ins.crit) {
|
|
SoulDataMgr.Ins.checkCrit();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 刷新任务进度
|
|
*/
|
|
refreshTaskProgress(increment = 0) {
|
|
if (increment) {
|
|
TaskDataProxy.Ins.task.addProgress(increment);
|
|
}
|
|
MesMgr.event(EGlobalEvent.REFRESH_TASK);
|
|
if (TaskDataProxy.Ins.task.completeDirty && TaskDataProxy.Ins.task.complete) {
|
|
TaskDataProxy.Ins.task.completeDirty = false;
|
|
UIMgr.Ins.ShowTipsUI("任务已完成,可领取奖励");
|
|
RedNotice.emit(EGlobalEvent.E_RED_UPDATE,[MainRedEnum.游历, HomeUIRedEnum.任务完成]);
|
|
//app.manager.toast.pop(TOAST_STYLE.TASK, "任务已完成,可领取奖励");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 真实关卡id
|
|
* @returns
|
|
*/
|
|
getRealLevel():number{
|
|
return this.level.id + LocalDataMgr.Pass.passed_times * 21;
|
|
}
|
|
}
|