import MTools from "db://assets/mx/tools/MTools" import { SkillDataManager, SkillQuality } from "../../manager/SkillDataManager"; import { ConstManager, ConstEnum } from "../../manager/ConstManager"; import { SkillType } from "./WeaponSkill/SkillTypes"; import { GEvent } from "db://assets/mx/module/event/GEvent"; import { ChapterDataManager, BattleType, ChapterDifficulty } from "../../manager/ChapterDataManager"; import { MonsterDataManager, MonsterType } from "../../manager/MonsterDataManager"; import { TurnTableAwardType } from "../../manager/TurnTableDataManager"; import { OtherDataType } from "../../game/GameData"; import { DEV } from "cc/env"; import { sdkConfig } from "../../sdk/sdkConfig"; import { ConstReplicaEnum } from "../../manager/ConstReplicaManager"; import { ChapterNewPlayTypeEnum, IParatroopsProperty } from "../../game/ChapterPlayTypes"; import { AttrResult } from "../../interface/AttributeInterface"; import { ConstNumType } from "../../game/ConfigProjectData"; import { WeaponType } from "../../manager/WeaponDataManager"; /**已拥有技能数据模板 */ export class IBattleSkill { /**技能id */ public id: number; /**所属的武器id */ public weaponId: number; /**技能类型 默认/特殊 */ public type: number; /**拥有数量 */ public limit_num: number; } /**属性改变的类型 */ export enum PropertyChangeType { /**所有武器 */ allWeapon = 1, /**自身武器 */ selfWeapon = 2, /**冷冻食品武器 */ iceWeapon = 3, /**零食武器 */ snackWeapon = 4, /**饮料武器 */ drinkWeapon = 5, /**全局怪物 */ wholeMonster = 6, /**全局技能概率 */ wholeSkillRate = 7, } /**弹幕子弹类型效果 */ export enum BulletEffectType { /**数量+ */ launchCount = 1, /**连发+ */ burstCount = 2, /**穿透+ */ piercingCount = 3, /**弹射 */ catapultCount = 4, } /**抛物线子弹类型效果 */ export enum ThrowEffectType { /**数量+ */ throwCount = 1, /**爆炸范围+ */ explodeRadius = 2, /**控制时间+ */ controlTime = 3, } /**抛物线11生效范围 */ export enum ThrowEffectRangeType { /**范围伤害 */ radiusAtk = 1, /**范围控制 */ radiusControlTimes = 2, /**激光持续 */ laserContinue = 3, /**无人机数量 */ DroneCount = 4,//无人机数量 /**龙卷风/暴风雪持续 */ TornadoContinue = 5, /**分裂数量、穿透数量 */ splitCount = 6, /**转速、x秒/圈、减速x、持续时间x秒 */ rotateSpeed = 7, /**闪电球数量、感电倍数、时间 */ lightningBall = 8, /**泡泡数量、泡泡持续时间 */ bubbleCount = 9, /**烟花陀螺 转速、火焰数量、存在时间 */ fireworkGyro = 10, } /**武器的属性类别 */ export enum WeaponPropertyType { /**技能cd */ cd = 1, /**飞行速度 */ speed = 2, /**暴击率 */ critRate = 3, /**暴击伤害 */ critAtk = 4, /**体积 */ volume = 5, /**伤害增幅倍数1 */ atkTimes1 = 6, /**伤害增幅倍数2 */ atkTimes2 = 7, /**必定暴击 暴击率*2转化爆伤 */ certainlyCrit = 8, /**概率伤害 */ rateAtk = 9, /**伤害频率 */ atkFrequency = 10, /**总伤害时间 */ atkTotalTime = 11, /**武器数量+ */ addWeaponCount = 12, /**分裂数量 */ splitCount = 13, /**转速 */ rotateSpeed = 14, /**烟花数量 */ fireworkCount = 15, /**持续伤害范围 */ sustainRange = 16, /** 伤害增幅倍数3 */ atkTimes3 = 50, /**怪物移速减少 */ monsterSpeedReduce = 51, /**紫色概率+ */ purpleRateAdd = 61, } /**武器的基础属性 */ export class IWeaponProperty { /** 所属武器 id(getWeaponAddProperty 时写入,用于发射事件过滤) */ public weaponId: number = 0; /**技能cd */ public cd: number = 0; /**飞行速度 */ public speed: number = 0; /**攻击速度 */ public atkSpeed: number = 0; /**暴击率 */ public critRate: number = 0; /**暴击伤害 */ public critAtk: number = 0; /**体积 */ public volume: number = 0; /**伤害增幅倍数1 */ public atkTimes1: number = 0; /**伤害增幅倍数2 */ public atkTimes2: number = 0; /**伤害增幅倍数3 */ public atkTimes3: number = 0; /**是否必定暴击 */ public isCertainlyCrit: boolean = false; /**是否暴击 */ public isCrit: boolean = false; /**增加概率伤害倍数(是否增加概率伤害) */ public addRateAtk: number = 1; /**总伤害 */ public allAtk: number = 0; /**单次发射数量(弹幕) */ public launchCount: number = 1; /**连发射数量(弹幕) */ public burstCount: number = 1; /**穿透数量(弹幕) */ public piercingCount: number = 1; /**单次发射数量(抛物线11) */ public throwCount: number = 1; /**爆炸范围增加倍数(抛物线11) */ public explodeRTime: number = 1; /**爆炸范围(抛物线11) */ public explodeRadius: number = 0; /**范围控制时间(抛物线11) */ public controlTime: number = 0; /**弹射次数 */ public catapultCount: number = 0; /**武器数量(无人机) */ public weaponCount: number = 0; /**武器持续时间(激光武器) */ public weaponContinueTime: number = 0; /**伤害间隔时间(激光武器) */ public damageInterval: number = 0; /**伤害倍数(激光武器) */ public damageMultiple: number = 1; /**存在时间 */ public weaponExistTime: number = 5; /**烟花数量(烟花陀螺) */ public fireworkCount: number = 0; /**特殊技能信息 */ public specialSkillInfo: string[] = []; /**特殊技能命中后添加buff */ public specialSkillAddBuffInfo: string[] = []; /**抛物线武器额外添加落地效果 */ public specialSkillAddFallEffectInfo: string[] = []; //分裂子弹数量-牙签使用默认6开始 public splitCount: number = 0; /**转速 1秒*/ public rotateSpeed: number = 0; /**陀螺转速 */ public gyroRotateSpeed: number = 0; //减速时间 public reduceSpeedTime: number = 0; //减速范围 public reduceSpeedRange: number = 0; /**是否有紫色技能 */ public isHavePurpleSkill: boolean = false; /**是否有橙色技能 */ public isHaveOrangeSkill: boolean = false; /**斩杀血线(百分比) */ public killHp: number = 0; /**秒杀几率(百分比) */ public killRate: number = 0; } /**特殊技能类型 */ export enum SpecialSkillType { /**解锁技能id */ unLockSkillId = 1, /**分裂子弹 */ divideBullet = 2, /**弹射 */ catapult = 3, /**一定概率移除cd 概率 时间 */ removeCD = 4, /**同一单位伤害递增 */ damageIncrease = 5, /**必定暴击 暴击率*2转化爆伤 */ certainlyCritRate = 6, /**概率连发(抛物线用)概率,连发次数 */ rateBurst = 7, /**武器状态改变,身披火焰,落地伤害倍数增加且可点燃区域 */ addFire = 8, /**更改基础效果中的控制时间+X秒 */ addBaseControlTime = 9, /**城墙每X秒恢复最大生命值Y%血量 */ wallAddHp = 10, /**距离弹幕类专用,到达最远距离或者墙壁前时返回 */ bulletTurnBack = 11, /**距离弹幕类专用,越来越大,大小倍数、多少秒增伤一次、增伤万分比 */ moreLarge = 12, /**每x秒在原地造成x倍伤害 */ damageSameUnit = 13, /**额外伤害 同一个怪 */ extraDamage = 14, /**额外爆炸 添加范围伤害 */ extraExplode = 15, /**分裂穿透子弹 带持续时间和伤害范围和伤害百分比的*/ splitBulletWithContinueTime = 16, } /**特殊技能命中后添加效果 */ export enum SpecialSkillAddBuffType { /**燃烧 */ burn = 1, /**减速 */ reduceSpeed = 2, /**伤害增幅(感电) */ elec = 3, /**控制 */ control = 4, /**加速 */ accelerate = 5, /**秒杀(秒杀几率) */ kill = 6, /**斩杀 */ killHp = 7,//斩杀血线(百分比) /**流血 */ blood = 8,//流血 伤害间隔,伤害系数,持续时间 } //命中前额外效果,命中单位状态 export enum ExtraEffectType { /**减速 */ reduceSpeed = 1, /**控制 */ control = 2, /**感电 */ elec = 3, /**燃烧 */ burn = 4, /**概率伤害 */ rateDamage = 5, /**负面(所有怪物命中后的负面效果) */ negative = 6, /**流血 */ blood = 7, } /**抛物线武器额外添加落地效果 */ export enum BezierFallEffectType { /**添加落地伤害 */ fallDamage = 1, /**落地添加燃烧区域 */ fallBurnArea = 2, /**落地翻滚造成伤害 */ fallRatotion = 3, /**落地添加粘液区域 */ fallMucusArea = 4, /**落地添加漩涡区域 */ fallVortex = 5, /**落地爆炸并添加燃烧区域 */ fallBombBurnArea = 6, /**二次爆炸 */ secondExplode = 7, } /**保存战斗数据的类型 */ export enum SaveBattleDataType { /*************这里是BattleDataManager中所有需要保存的数据类型 *************/ /**章节id */ chapterId = 1, /**城墙最大生命值 */ wallMaxHp = 2, /**城墙当前生命值 */ curWallHp = 3, /**技能卡片3选1免费刷新次数 */ rogueFreeRefreshTimes = 4, /**技能卡片3选1广告刷新次数 */ rogueADRefreshTimes = 5, /**技能卡片3选1免费全部都要次数 */ rogueFreeAllGetTimes = 6, /**技能卡片3选1广告全部都要次数 */ rogueADAllGetTimes = 7, /**视频广告增加银币次数 */ videoAddCoinTimes = 8, /**视频广告增加银币总次数 */ videoAddCoinTotalTimes = 9, /**当前失败复活剩余次数 */ curFailReviveLeftNum = 10, /**新机制数据*/ chapterNewPlayInfo = 11, /**boss来临时间数组 */ bossTimeArr = 12, /**中期boss来临时间数组 */ midBossTimeArr = 13, /**当前章节怪物总数 */ totalMonsterNum = 14, /**当前已死亡怪物数量 */ curDeadMonsterNum = 15, /*当前波数 */ curWaveNum = 16, /**总波数 */ totalWaveNum = 17, /**装备的武器id池 */ equippedWeaponArr = 18, /**当前使用的武器id池 */ curUseWeaponArr = 19, /**当前选武器卡片(黄金宝箱)的次数 */ curRogueWeaponTimes = 20, /**当前已拥有的技能id池 */ curHaveSkillArr = 21, /**当前选技能卡片(白银宝箱)的次数 */ curRogueSkillTimes = 22, /**统计所有技能属于哪些武器 */ weaponSkillNum = 23, /**当前拥有特殊模式的技能 */ curHaveSpecialModleSkillArr = 24, /**当前银币数 */ curCoinNum = 25, /*************这里是BattleManager中所有需要保存的数据类型 *************/ /**当前时间 */ currentTime = 101, /**是否有未领取的钻石宝箱 */ isDiamondTreasureNoGet = 102, /**未领取钻石宝箱位置信息 */ diamondTreasurePos = 103, /*************这里是DamageStatistics中所有需要保存的数据类型 *************/ /**当前已进入统计的武器id */ dsCurWeaponIdArr = 201, /**武器伤害统计map */ dsWeaponDamageMap = 202, /**对怪物造成的总伤害 */ dsAllDamageNum = 203, /*************这里是MonsterSpawner中所有需要保存的数据类型 *************/ /**所有怪物数据 */ allMonsterData = 301, /**下一个普通生成事件索引 */ nextEventIndex = 302, /**下一个特殊生成事件索引 */ nextSpecialEventIndex = 303, /**是否正在生成怪物 */ isRunning = 304, /*************这里是ObstaclePlacer中所有需要保存的数据类型 *************/ /**所有障碍物的信息 */ allObstaclesInfo = 401, /**累积设置障碍物的数量 */ totalSetObstaclesNum = 402, } /**战斗数据处理 */ export class BattleDataManager { /** * 同品质根据权重获取特定卡片(白银宝箱) * @param tab 同品质的卡片数组 */ private static getSameQualityCardByWeight(tab: ITableSkill[], index: number, weight_add: string) { //章节表中weight_add字段,特定武器增加权重倍数 let weight_addArr = [] if (weight_add != '') { weight_addArr = weight_add.split('|') } //增加权重倍数 let addWeightNormal = (i) => { let weight_normal = tab[i].weight_normal; for (let j = 0; j < weight_addArr.length; j++) { if (weight_addArr[j].split(',')[0] == tab[i].weapon) { weight_normal *= Number(weight_addArr[j].split(',')[1]) } } return weight_normal } let allWeight = 0 for (let i = 0; i < tab.length; i++) { let weight_normal = addWeightNormal(i) allWeight += weight_normal } let r = Math.random() * allWeight let curWeight = 0 let id = 0 for (let i = 0; i < tab.length; i++) { let weight_normal = addWeightNormal(i) if (r >= curWeight && r < curWeight + weight_normal) { id = i break } curWeight += weight_normal } return tab[id] } /** * 获取3张技能卡片(困难模式第一次选卡) * @param account 卡片数量 */ public static getDiffModleThreeRogueSkill(bActive: boolean, account: number) { let str = gg.replicaManager.getConstStringById(ConstReplicaEnum.DifficultyModleSkillIdArr) let skillIdArr = str.split(',').map(x => Number(x)) //当前能使用的技能池config let list: ITableSkill[] = [] for (let i = 0; i < skillIdArr.length; i++) { let config = SkillDataManager.getSkillDataById(skillIdArr[i]) list.push(config) } //随机出3个技能 let resultArr: IBattleSkill[] = [] let num = 0 while (num < account) { //根据权重随机出一个品质 let randomQuaity = () => { let strArr = gg.replicaManager.getConstStringById(ConstReplicaEnum.DifficultyModleWeight).split('|') let weightArr = bActive ? strArr[0].split(',') : strArr[1].split(',') let allWeight = 0 for (let i = 0; i < weightArr.length; i++) { allWeight += parseInt(weightArr[i]) } let r = Math.random() * allWeight let curWeight = 0 let id = 0 for (let i = 0; i < weightArr.length; i++) { let x = parseInt(weightArr[i]) if (r >= curWeight && r < curWeight + x) { id = i break } curWeight += x } return id + 1 } let quaity = randomQuaity() let tab = list.filter(item => item.quality == quaity) if (tab.length > 0) { let index = Math.floor(Math.random() * tab.length) let config = tab[index] //有相同id的技能 let isSameId = resultArr.some(x => x.id == config.id) if (isSameId) { continue } let item = new IBattleSkill() item.id = config.id item.limit_num = 1 item.type = config.type item.weaponId = config.weapon resultArr.push(item) num++ } } return resultArr } /** * 获取技能卡片(转盘) */ public static getTurnTableRogueSkill(typeArr: TurnTableAwardType[]) { let chapterConfig: ITableChapter = gg.game.CurentBattle.CurentConfigChapter //已经拥有的技能数据 let tempArr = MTools.deepClone(gg.game.CurentBattle.CurUseSkillArr)//this.curHaveSkillArr.slice(0) //特殊技能id,只能出现一个 let specialIdArr = [48, 49, 50] let isHaveSpecialId = false //检查是否已拥有特殊技能id for (let i = 0; i < tempArr.length; i++) { if (specialIdArr.indexOf(tempArr[i].id) >= 0) { isHaveSpecialId = true } } //当前能使用的技能池id let arr = [] for (let i = 0; i < gg.game.CurentBattle.CurUseWeaponArr.length; i++) { let weaponId = gg.game.CurentBattle.CurUseWeaponArr[i].weaponid let weaponLevel = gg.data.project.getWeaponLevel(weaponId) //当前武器可用的技能 let a = gg.data.project.getAllCanUseSkillByWeaponLevel(weaponId, weaponLevel) arr = arr.concat(a) } //当前能使用的技能池config let list: ITableSkill[] = [] for (let i = 0; i < arr.length; i++) { let config = SkillDataManager.getSkillDataById(arr[i]) //过滤掉技能拥有数量已满的技能 let isLimit = false for (let i = 0; i < tempArr.length; i++) { //技能数量已经满了 if (tempArr[i].id == config.id && tempArr[i].limit_num >= config.limit_num) { isLimit = true break } } if (!isLimit) { list.push(config) } } // console.log('当前能使用的技能池config==',list) let resultArr: IBattleSkill[] = [] let num = 0 let tempIdArr = [] let isNotFindNum = 0 //随机出技能 while (num < typeArr.length) { isNotFindNum++ let type = typeArr[num] let tab = [] //技能(已有武器蓝色技能和紫色技能按权重随机) if (type == TurnTableAwardType.Skill) { tab = list.filter(item => item.quality == SkillQuality.Blue || item.quality == SkillQuality.Purple) //稀有技能(所有武器的一个橙色技能,没有变紫,没有变蓝) } else if (type == TurnTableAwardType.SpecialSkill) { tab = list.filter(item => item.quality == SkillQuality.Orange) if (tab.length <= 0 || isNotFindNum >= 10) { console.error('随机出橙色技能失败,已连续随机10次,尝试随机紫色技能') tab = list.filter(item => item.quality == SkillQuality.Purple) if (tab.length <= 0 || isNotFindNum >= 20) { console.warn('随机出紫色技能失败,已连续随机20次,尝试随机蓝色技能') tab = list.filter(item => item.quality == SkillQuality.Blue) } } } else if (type == TurnTableAwardType.PurpleSkill) { tab = list.filter(item => item.quality >= SkillQuality.Purple) if (tab.length <= 0 || isNotFindNum >= 20) { console.warn('随机出紫色技能失败,已连续随机20次,尝试随机蓝色技能') tab = list.filter(item => item.quality == SkillQuality.Blue) } } if (tab.length > 0) { //随机到一个技能 //是否为前x个银色宝箱 // let isBeforeX = false let config = this.getSameQualityCardByWeight(tab, 0, chapterConfig.weight_add) // let config = tab[Math.floor(Math.random()*tab.length)] //检查是否已拥有特殊技能id if (specialIdArr.indexOf(config.id) >= 0) { if (isHaveSpecialId) { continue } else { isHaveSpecialId = true } } //单次不能出现重复id if (tempIdArr.indexOf(config.id) >= 0) { continue; } //有相同id的技能 let isSameId = false for (let i = 0; i < tempArr.length; i++) { if (tempArr[i].id == config.id) { isSameId = true //技能数量已经满了 if (tempArr[i].limit_num >= config.limit_num) { //过滤掉技能拥有数量已满的技能 list.splice(list.indexOf(config), 1) } else { // tempArr[i].limit_num++ // resultArr.push(tempArr[i]) tempIdArr.push(tempArr[i].id) num++ isNotFindNum = 0 } break } } if (!isSameId) { let item: IBattleSkill = new IBattleSkill() item.id = config.id item.type = config.type item.limit_num = 1 item.weaponId = config.weapon // tempArr.push(item) resultArr.push(item) tempIdArr.push(config.id) num++ isNotFindNum = 0 } } } // console.log('随机出的转盘技能==',resultArr) return resultArr } /**中期boss来临时间数组 */ private static midBossTimeArr: number[] = [] /**获取中期boss来临时间数组 */ public static getMidBossTimeArr() { return this.midBossTimeArr } /**boss来临时间数组 */ private static bossTimeArr: number[] = [] /**获取boss来临时间数组 */ public static getBossTimeArr() { return this.bossTimeArr } /**初始化boss来临时间数组 */ public static initBossTimeArr() { this.bossTimeArr = [] this.midBossTimeArr = [] let config: ITableChapter = gg.game.CurentBattle.CurentConfigChapter2 || gg.game.CurentBattle.CurentConfigChapter; let monster3_1 = config.monster3_1.split('|') for (let i = 0; i < monster3_1.length; i++) { let t = monster3_1[i].split(',') let monsterId = Number(t[2]) let time = Number(t[0]) if (gg.game.CurentSelectBattleType == BattleType.BoxMode || gg.game.CurentSelectBattleType == BattleType.GachaMode) { if (monsterId == 30011 || monsterId == 40011) { continue; } } let monsterData: ITableMonster = MonsterDataManager.getMonsterDataById(monsterId) // console.log('monsterId,monsterData==',monsterId,monsterData) //提前3秒触发 if (monsterData.type == MonsterType.Boss) { this.bossTimeArr.push(time - 3) } else if (monsterData.type == MonsterType.MidBoss) { this.midBossTimeArr.push(time - 3) } } this.bossTimeArr.sort((a, b) => a - b) this.midBossTimeArr.sort((a, b) => a - b) // console.log('初始化boss来临时间数组==', JSON.stringify(this.bossTimeArr)) // console.log('初始化midBoss来临时间数组==', JSON.stringify(this.midBossTimeArr)) } /** * 获取武器的加成属性 * @param weaponId 武器id * @param buffTypeArr 怪物身上的所有buff类型(可选) */ public static getWeaponAddProperty(weaponId: number, buffTypeArr?: SpecialSkillAddBuffType[], tetriLevel: number = 1): IWeaponProperty { // let startTime = new Date().getTime() //当前等级武器的属性 let weaponLevel = gg.data.project.getWeaponLevel(weaponId); let weaponConfig = gg.data.project.getWeaponData(weaponId); if (weaponId == 12 && weaponLevel == 1 && gg.game.CurentBattle.IsGuideUseLian) { weaponLevel = gg.data.table.getConst(ConstNumType.GuideUseLianLevel); } let levelPara = gg.data.project.getLevelParaByWeaponLevel(weaponLevel, weaponId) //buff增益加成 let buffGainItem: IWeaponProperty = new IWeaponProperty() //所有加成 let allItem: IWeaponProperty = new IWeaponProperty() //没有除以10000的数值 let atkAdd = 0//gg.attrInterface.getAttrAtk1Value(weaponId) let atk2Add = 0//gg.attrInterface.getAttrAtk2Value(weaponId) let cdAdd = 0//gg.attrInterface.getAttrCDValue(weaponId) let critAdd = 0//gg.attrInterface.getAttrCritValue(weaponId) let damageAdd = 0//gg.attrInterface.getAttrDamageValue(weaponId) let critDamageAdd = 0//gg.attrInterface.getAttrCritDamageAddValue(weaponId) let igniteAdd = 0//gg.attrInterface.getAttrIgniteAddValue(weaponId) let shockAdd = 0//gg.attrInterface.getAttrShockAddValue(weaponId) let addProObj: AttrResult = { atkAdd: atkAdd, atk2Add: atk2Add, cdAdd: cdAdd, critAdd: critAdd, damageAdd: damageAdd, critDamageAdd: critDamageAdd, igniteAdd: igniteAdd, shockAdd: shockAdd, } //获取或计算固定属性 获取技能会重新清除缓存重新计算 let fixedProps = this.weaponFixedPropertyCache.get(weaponId) if (!fixedProps) { //基础武器属性 let baseItem: IWeaponProperty = new IWeaponProperty() //cd计算 let jisuanCd = weaponConfig.cd baseItem.cd = jisuanCd baseItem.speed = weaponConfig.speed baseItem.volume = weaponConfig.size //暴击计算 let critRateNum = gg.data.getPlayerCritCoefficient() baseItem.critRate = weaponConfig.critical_chance + critRateNum baseItem.critAtk = weaponConfig.critical_dam baseItem.atkTimes1 = 0 baseItem.atkTimes2 = 0 //抛物线爆炸范围 if (weaponConfig.flight == SkillType.抛物线没有碰撞) { let para = weaponConfig.effect_range.split(',') baseItem.explodeRadius = Number(para[0]) } else if (weaponConfig.flight == SkillType.抛物线碰撞) { } else if (weaponConfig.flight == SkillType.直线弹射) { let para = weaponConfig.effect_range.split(',') baseItem.catapultCount = Number(para[0]) } else if (weaponConfig.flight == SkillType.直线数量) { let para = weaponConfig.effect_range.split(',') baseItem.launchCount = Number(para[0]) } else if (weaponConfig.flight == SkillType.单点激光) { let para = weaponConfig.effect_range.split(',') baseItem.damageInterval = Number(para[0]) baseItem.damageMultiple = Number(para[1]) / 10000 baseItem.weaponContinueTime = Number(para[2]) }else if (weaponConfig.flight == SkillType.直线目标持续伤害) { let para = weaponConfig.effect_range.split(',') baseItem.explodeRadius = Number(para[0]) //伤害范围 baseItem.damageMultiple = Number(para[1]) / 10000 baseItem.damageInterval = Number(para[2]) baseItem.weaponContinueTime = Number(para[3]) }else if (weaponConfig.flight == SkillType.直线分裂) { let para = weaponConfig.effect_range.split(',') // baseItem.splitCount = Number(para[0]) } //全局加成 let mainItem: IWeaponProperty = new IWeaponProperty() //自身加成 let selfItem: IWeaponProperty = new IWeaponProperty() //特殊类型加成 let specialItem: IWeaponProperty = new IWeaponProperty() //是否必定暴击 selfItem.isCertainlyCrit = false // //增加概率伤害倍数(是否增加概率伤害) // selfItem.addRateAtk = 1 selfItem.throwCount = baseItem.throwCount //遍历所有技能,加成属性 let arr = gg.game.CurentBattle.CurUseSkillArr for (let i = 0; i < arr.length; i++) { let num = 1; let skillConfig = SkillDataManager.getSkillDataById(arr[i].id) if (skillConfig.weapon == weaponId && skillConfig.quality == SkillQuality.Purple) { selfItem.isHavePurpleSkill = true } else if (skillConfig.weapon == weaponId && skillConfig.quality == SkillQuality.Orange) { selfItem.isHaveOrangeSkill = true } let weaponData: ITableWeapon2 = gg.data.project.getWeaponData(skillConfig.weapon); //property1字段 if (skillConfig.property1 == PropertyChangeType.allWeapon) { let para = skillConfig.property_para1.split(',') this.addProperty(mainItem, para, num, addProObj) } else if (skillConfig.property1 == PropertyChangeType.selfWeapon && skillConfig.weapon == weaponId) { let para = skillConfig.property_para1.split(',') this.addProperty(selfItem, para, num, addProObj) //是否增加概率伤害(由于是概率出,不能进缓存,移到下面处理了) if (para[0] == WeaponPropertyType.rateAtk + '') { // let rate = Number(para[1])/10000 // let isAddRateAtk = Math.random() < rate // if(isAddRateAtk){ // selfItem.addRateAtk = Number(para[2]) // } //加快伤害频率 } else if (para[0] == WeaponPropertyType.atkFrequency + '') { let v = Number(para[1]) / 10000 let n = Math.floor(baseItem.damageInterval / (1 + v) * 100) / 100 baseItem.damageInterval = n } } else if (skillConfig.property1 == PropertyChangeType.iceWeapon && weaponData.type == PropertyChangeType.iceWeapon) { let para = skillConfig.property_para1.split(',') this.addProperty(specialItem, para, num, addProObj) } else if (skillConfig.property1 == PropertyChangeType.snackWeapon && weaponData.type == PropertyChangeType.snackWeapon) { let para = skillConfig.property_para1.split(',') this.addProperty(specialItem, para, num, addProObj) } else if (skillConfig.property1 == PropertyChangeType.drinkWeapon && weaponData.type == PropertyChangeType.drinkWeapon) { let para = skillConfig.property_para1.split(',') this.addProperty(specialItem, para, num, addProObj) } //是否必定暴击 if (skillConfig.property_para1 == WeaponPropertyType.certainlyCrit + '' && skillConfig.weapon == weaponId) { selfItem.isCertainlyCrit = true } //property2字段 if (skillConfig.property2 == PropertyChangeType.allWeapon) { let para = skillConfig.property_para2.split(',') this.addProperty(mainItem, para, num, addProObj) } else if (skillConfig.property2 == PropertyChangeType.selfWeapon && skillConfig.weapon == weaponId) { let para = skillConfig.property_para2.split(',') this.addProperty(selfItem, para, num, addProObj) } else if (skillConfig.property2 == PropertyChangeType.iceWeapon && weaponData.type == PropertyChangeType.iceWeapon) { let para = skillConfig.property_para2.split(',') this.addProperty(specialItem, para, num, addProObj) } else if (skillConfig.property2 == PropertyChangeType.snackWeapon && weaponData.type == PropertyChangeType.snackWeapon) { let para = skillConfig.property_para2.split(',') this.addProperty(specialItem, para, num, addProObj) } else if (skillConfig.property2 == PropertyChangeType.drinkWeapon && weaponData.type == PropertyChangeType.drinkWeapon) { let para = skillConfig.property_para2.split(',') this.addProperty(specialItem, para, num, addProObj) } //bullet_effect字段 if (skillConfig.weapon == weaponId && skillConfig.bullet_effect) { let para = skillConfig.bullet_effect.split(',') let type = parseInt(para[0]) let count = parseInt(para[1]) if (type == BulletEffectType.launchCount) { selfItem.launchCount += count * num } else if (type == BulletEffectType.burstCount) { selfItem.burstCount += count * num } else if (type == BulletEffectType.piercingCount) { selfItem.piercingCount += count * num } else if (type == BulletEffectType.catapultCount) { selfItem.catapultCount += count * num } } if (skillConfig.weapon == weaponId && skillConfig.bullet_effect2) { let para = skillConfig.bullet_effect2.split(',') let type = parseInt(para[0]) let count = parseInt(para[1]) if (type == BulletEffectType.launchCount) { selfItem.launchCount += count * num } else if (type == BulletEffectType.burstCount) { selfItem.burstCount += count * num } else if (type == BulletEffectType.piercingCount) { selfItem.piercingCount += count * num } } //throw_effect字段 if (skillConfig.weapon == weaponId && skillConfig.throw_effect) { let para = skillConfig.throw_effect.split(',') let type = parseInt(para[0]) let count = parseInt(para[1]) if (type == ThrowEffectType.throwCount) { selfItem.throwCount += count * num } else if (type == ThrowEffectType.explodeRadius) { selfItem.explodeRadius += count * num selfItem.explodeRTime += count * num / 10000 } else if (type == ThrowEffectType.controlTime) { selfItem.controlTime += count * num } } if (skillConfig.weapon == weaponId && skillConfig.throw_effect2) { let para = skillConfig.throw_effect2.split(',') let type = parseInt(para[0]) let count = parseInt(para[1]) if (type == ThrowEffectType.throwCount) { selfItem.throwCount += count * num } else if (type == ThrowEffectType.explodeRadius) { selfItem.explodeRadius += count * num selfItem.explodeRTime += count * num / 10000 } else if (type == ThrowEffectType.controlTime) { selfItem.controlTime += count * num } } //special_skill字段 if (skillConfig.weapon == weaponId && skillConfig.special_skill != '') { //特殊技能信息 selfItem.specialSkillInfo.push(skillConfig.special_skill) } //add_buff字段 if (skillConfig.weapon == weaponId && skillConfig.add_buff != '') { //特殊技能命中后添加buff selfItem.specialSkillAddBuffInfo.push(skillConfig.add_buff) } //fall_effect字段 if (skillConfig.weapon == weaponId && skillConfig.fall_effect != '') { //抛物线武器额外添加落地效果 selfItem.specialSkillAddFallEffectInfo.push(skillConfig.fall_effect) } } //缓存固定属性 fixedProps = { baseItem, mainItem, selfItem, specialItem } this.weaponFixedPropertyCache.set(weaponId, fixedProps) } //使用缓存的固定属性 const { baseItem, mainItem, selfItem, specialItem } = fixedProps //计算buff增益加成 let arr = gg.game.CurentBattle.CurUseSkillArr for (let i = 0; i < arr.length; i++) { let skillConfig = arr[i]; if (skillConfig.property1 == PropertyChangeType.selfWeapon && skillConfig.weapon == weaponId) { let para = skillConfig.property_para1.split(',') //是否增加概率伤害(由于概率出,移到这里特殊处理了,这是个补丁) if (para[0] == WeaponPropertyType.rateAtk + '') { let rate = Number(para[1]) / 10000 let isAddRateAtk = Math.random() < rate if (isAddRateAtk) { buffGainItem.addRateAtk = Number(para[2]) } } } //////////////////////////// //extra_effect字段(命中前额外效果,命中单位状态) if (skillConfig.weapon == weaponId && buffTypeArr && buffTypeArr.length > 0) { //怪物有减速buff if ((skillConfig.extra_effect == ExtraEffectType.negative || skillConfig.extra_effect == ExtraEffectType.reduceSpeed) && buffTypeArr.indexOf(SpecialSkillAddBuffType.reduceSpeed) != -1) { let extra_num = skillConfig.extra_num.split(',') let type = parseInt(extra_num[0]) let value = parseInt(extra_num[1]) //增加暴击伤害 if (type == WeaponPropertyType.critAtk) { buffGainItem.critAtk += value //增加暴击率 } else if (type == WeaponPropertyType.critRate) { buffGainItem.critRate += value //增加伤害增幅倍数1 } else if (type == WeaponPropertyType.atkTimes1) { buffGainItem.atkTimes1 += value } } //怪物有燃烧buff if ((skillConfig.extra_effect == ExtraEffectType.negative || skillConfig.extra_effect == ExtraEffectType.burn) && buffTypeArr.indexOf(SpecialSkillAddBuffType.burn) != -1) { let extra_num = skillConfig.extra_num.split(',') let type = parseInt(extra_num[0]) let value = parseInt(extra_num[1]) //增加暴击率 if (type == WeaponPropertyType.critRate) { buffGainItem.critRate += value } else if (type == WeaponPropertyType.atkTimes1) { buffGainItem.atkTimes1 += addProObj.damageAdd } } //怪物有控制buff if ((skillConfig.extra_effect == ExtraEffectType.negative || skillConfig.extra_effect == ExtraEffectType.control) && buffTypeArr.indexOf(SpecialSkillAddBuffType.control) != -1) { let extra_num = skillConfig.extra_num.split(',') let type = parseInt(extra_num[0]) let value = parseInt(extra_num[1]) //增加伤害增幅倍数1 if (type == WeaponPropertyType.atkTimes1) { buffGainItem.atkTimes1 += value } } //怪物有感电buff if ((skillConfig.extra_effect == ExtraEffectType.negative || skillConfig.extra_effect == ExtraEffectType.elec) && buffTypeArr.indexOf(SpecialSkillAddBuffType.elec) != -1) { let extra_num = skillConfig.extra_num.split(',') let type = parseInt(extra_num[0]) let value = parseInt(extra_num[1]) //增加伤害增幅倍数1 if (type == WeaponPropertyType.atkTimes1) { buffGainItem.atkTimes1 += value } else if (type == WeaponPropertyType.atkTimes3) { buffGainItem.atkTimes3 += addProObj.shockAdd }else if(type == WeaponPropertyType.certainlyCrit){ //必定暴击 buffGainItem.isCertainlyCrit = true; } } //怪物有流血buff if ((skillConfig.extra_effect == ExtraEffectType.negative || skillConfig.extra_effect == ExtraEffectType.blood) && buffTypeArr.indexOf(SpecialSkillAddBuffType.blood) != -1) { let extra_num = skillConfig.extra_num.split(',') let type = parseInt(extra_num[0]) let value = parseInt(extra_num[1]) //增加伤害增幅倍数1 if (type == WeaponPropertyType.atkTimes1) { buffGainItem.atkTimes1 += value } } } } ////////////////////////////// // console.log('mainItem==',mainItem) // console.log('selfItem==',selfItem) // console.log('specialItem==',specialItem) //暴击率=min(默认暴击率+其它暴击率加成,1) let critRate = (baseItem.critRate + mainItem.critRate + selfItem.critRate + specialItem.critRate + buffGainItem.critRate) / 10000 critRate += (gg.game.CurentBattle.fubenBoxAddCrit / 10000) allItem.critRate = critRate <= 1 ? critRate : 1 allItem.fireworkCount = baseItem.fireworkCount + selfItem.fireworkCount; //暴击伤害=默认暴击伤害+所有暴击伤害加成 allItem.critAtk = (baseItem.critAtk + mainItem.critAtk + selfItem.critAtk + specialItem.critAtk + buffGainItem.critAtk) / 10000 //必定暴击时 allItem.isCertainlyCrit = selfItem.isCertainlyCrit || buffGainItem.isCertainlyCrit if (allItem.isCertainlyCrit) { allItem.critAtk += critRate * 2 allItem.critRate = 1 } //伤害增幅倍数1=1+所有伤害增加加成1 allItem.atkTimes1 = 1 + (baseItem.atkTimes1 + mainItem.atkTimes1 + selfItem.atkTimes1 + specialItem.atkTimes1 + buffGainItem.atkTimes1) / 10000 //伤害增幅倍数2=1+所有伤害增加加成2 allItem.atkTimes2 = 1 + (baseItem.atkTimes2 + mainItem.atkTimes2 + selfItem.atkTimes2 + specialItem.atkTimes2 + buffGainItem.atkTimes2) / 10000 //伤害增幅倍数3=1+所有伤害增加加成3 allItem.atkTimes3 = 1 + (baseItem.atkTimes3 + mainItem.atkTimes3 + selfItem.atkTimes3 + specialItem.atkTimes3 + buffGainItem.atkTimes3) / 10000 //cd时间=初始cd时间/(1+所有cd减少增益) let cdNum = gg.data.getPlayerCoolCoefficient() allItem.cd = Math.floor(baseItem.cd / (1 + (cdNum + mainItem.cd + selfItem.cd + specialItem.cd + gg.game.CurentBattle.fubenBoxSkillCoolDown) / 10000) * 100) / 100 //console.log(' allItem.cd cdNum==', baseItem.cd, allItem.cd, gg.game.fubenBoxSkillCoolDown) // console.log('baseItem.cd==',allItem.cd, baseItem.cd,mainItem.cd,selfItem.cd,specialItem.cd,(1+(mainItem.cd+selfItem.cd+specialItem.cd)/10000) ) //飞行速度=初始飞行速度*(1+飞行速度加成) allItem.speed = Math.floor(baseItem.speed * (1 + (mainItem.speed + selfItem.speed + specialItem.speed) / 10000)) //体积=初始*(1+加成和) allItem.volume = Math.floor(baseItem.volume * (1 + (mainItem.volume + selfItem.volume + specialItem.volume) / 10000) * 100) / 100 if (weaponConfig.flight == SkillType.直线数量) { allItem.launchCount = selfItem.launchCount + baseItem.launchCount } else { allItem.launchCount = selfItem.launchCount } allItem.burstCount = selfItem.burstCount allItem.piercingCount = selfItem.piercingCount//穿透次数 allItem.catapultCount = baseItem.catapultCount+selfItem.catapultCount // if (weaponConfig.flight == SkillType.牙签) { // allItem.piercingCount = selfItem.piercingCount + baseItem.piercingCount - 1//穿透次数 初始自带3穿透 // } allItem.isHavePurpleSkill = selfItem.isHavePurpleSkill allItem.isHaveOrangeSkill = selfItem.isHaveOrangeSkill allItem.specialSkillInfo = selfItem.specialSkillInfo allItem.specialSkillAddBuffInfo = selfItem.specialSkillAddBuffInfo allItem.specialSkillAddFallEffectInfo = selfItem.specialSkillAddFallEffectInfo //抛物线11发射数量 allItem.throwCount = selfItem.throwCount //抛物线11爆炸范围 allItem.explodeRadius = Math.floor(baseItem.explodeRadius * (1 + selfItem.explodeRadius / 10000)) //抛物线11爆炸范围倍数 allItem.explodeRTime = selfItem.explodeRTime //抛物线11落地控制时间 allItem.controlTime = baseItem.controlTime + selfItem.controlTime //武器持续时间(激光武器) allItem.weaponContinueTime = baseItem.weaponContinueTime + selfItem.weaponContinueTime //伤害间隔时间(激光武器) allItem.damageInterval = baseItem.damageInterval //伤害倍数(激光武器) allItem.damageMultiple = baseItem.damageMultiple //武器数量(无人机) allItem.weaponCount = baseItem.weaponCount + selfItem.weaponCount //增加概率伤害倍数(是否增加概率伤害) allItem.addRateAtk = buffGainItem.addRateAtk allItem.atkSpeed = baseItem.atkSpeed + selfItem.atkSpeed; allItem.weaponExistTime = baseItem.weaponExistTime; //是否暴击 allItem.isCrit = Math.random() < allItem.critRate //伤害=攻击力*(有无暴击伤害)*伤害增幅*受到伤害增加增幅 const levelMul = Number.isFinite(tetriLevel as any) && (tetriLevel as any) > 0 ? (tetriLevel as any) : 1; //攻击力计算 let attack = (1 + atkAdd / 10000 + atk2Add / 10000) * gg.data.getPlayerAtk() * levelMul let allAttack = weaponConfig.weapon_para * attack * levelPara const speedModeAtkMul = gg.game.CurentBattle?.getSpeedModeAttackBonus?.() ?? 1; if (allItem.isCrit) { allItem.allAtk = Math.floor(allAttack * allItem.critAtk * allItem.atkTimes1 * allItem.atkTimes2 * allItem.atkTimes3 * allItem.addRateAtk * allItem.damageMultiple * (1 + gg.game.CurentBattle.fubenBoxAddAtk / 10000) * speedModeAtkMul) } else { allItem.allAtk = Math.floor(allAttack * allItem.atkTimes1 * allItem.atkTimes2 * allItem.atkTimes3 * allItem.addRateAtk * allItem.damageMultiple * (1 + gg.game.CurentBattle.fubenBoxAddAtk / 10000) * speedModeAtkMul) } // console.log('allItem.allAtk==',allItem.allAtk) allItem.splitCount = baseItem.splitCount + selfItem.splitCount //分裂数量 //陀螺转速 1秒 //保留两位小数 allItem.gyroRotateSpeed = baseItem.gyroRotateSpeed + selfItem.gyroRotateSpeed; //转速 1秒 //保留两位小数 allItem.rotateSpeed = Math.floor((baseItem.rotateSpeed / (1 + selfItem.rotateSpeed / 10000)) / 10000 * 100) / 100 //减速时间 allItem.reduceSpeedTime = baseItem.reduceSpeedTime //减速范围 allItem.reduceSpeedRange = baseItem.reduceSpeedRange // let endTime = new Date().getTime() // console.log('getWeaponAddProperty耗时==',endTime-startTime) // console.log('allItem==',allItem) allItem.weaponId = weaponId return allItem } /**加成单个属性 */ public static addProperty(item: IWeaponProperty, para, num, addProObj: AttrResult) { if (parseInt(para[0]) == WeaponPropertyType.cd) { item.cd += parseInt(para[1]) * num item.cd += addProObj.cdAdd } else if (parseInt(para[0]) == WeaponPropertyType.speed) { item.speed += parseInt(para[1]) * num } else if (parseInt(para[0]) == WeaponPropertyType.critRate) { item.critRate += parseInt(para[1]) * num item.critRate += addProObj.critAdd } else if (parseInt(para[0]) == WeaponPropertyType.critAtk) { item.critAtk += parseInt(para[1]) * num item.critAtk += addProObj.critDamageAdd } else if (parseInt(para[0]) == WeaponPropertyType.volume) { item.volume += parseInt(para[1]) * num } else if (parseInt(para[0]) == WeaponPropertyType.atkTimes1) { item.atkTimes1 += parseInt(para[1]) * num item.atkTimes1 += addProObj.damageAdd } else if (parseInt(para[0]) == WeaponPropertyType.atkTimes2) { item.atkTimes2 += parseInt(para[1]) * num } else if (parseInt(para[0]) == WeaponPropertyType.atkTotalTime) { item.weaponContinueTime += parseInt(para[1]) * num } else if (parseInt(para[0]) == WeaponPropertyType.addWeaponCount) { item.weaponCount += parseInt(para[1]) * num } else if (parseInt(para[0]) == WeaponPropertyType.splitCount) { item.splitCount += parseInt(para[1]) * num //console.log('addProperty splitCount==',item.splitCount) } else if (parseInt(para[0]) == WeaponPropertyType.rotateSpeed) { item.rotateSpeed += parseInt(para[1]) * num } else if (parseInt(para[0]) == WeaponPropertyType.fireworkCount) { item.fireworkCount += parseInt(para[1]) * num }else if (parseInt(para[0]) == WeaponPropertyType.sustainRange) { item.explodeRadius += parseInt(para[1]) * num item.volume += parseInt(para[1]) * num } } /**武器固定属性缓存 */ private static weaponFixedPropertyCache: Map = new Map() /** * 刷新武器固定属性缓存 * 清空所有缓存的武器固定属性,以便重新计算 */ public static refreshWeaponFixedPropertyCache(): void { this.weaponFixedPropertyCache.clear() } /**获取本地/数据库配置数据表 */ public static getLeveData() { return new Promise(async (resolve, reject) => { if (DEV) { // this.levelData = gg.data.table.getTableList(TableNames.level).find(x => x.lv == this.level); // this.AllDifficultyData = gg.data.table.getTableList(TableNames.difficulty); // this.AllBasketLevel = gg.data.table.getTableList(TableNames.basketLevel); resolve(null); return; } ZYSDK.ZYSDK.getGameConfig(`${sdkConfig.config.name}${sdkConfig.config.vsion}`, (res) => { try { let key = "ZYZTGAMEHKCX2025SSHH12345678ZYZT"; // console.log("获取游戏配置数据", res); if (res == null || res == '') { console.error("获取远端游戏json配置失败,res为空"); gg.sdk.reportDY("inLevel", "获取章节配置-失败"); resolve(null); return; } let str = ZYSDK.ZYSDK.decryptWithKey(res, key); let data = MTools.decompressJsonData(str); console.log("获取远端游戏json配置成功++++++++", data); if (data && typeof data === 'object') { gg.data.table.applyHotUpdateTables(data); } resolve(data); } catch (error) { resolve(error); } }, (err) => { resolve(err); console.log("获取游戏配置失败", err); }); }) } }