import { fixValue, randNumber } from "./fightFun";
import { FightObj } from "./fightType";

type DPS_EXTDATA_TYPE = {
    'pro'?: number,
    'mofa'?: number,
    'islong'?: number
};
export function getFightDPS(fromRole: FightObj, toRole: FightObj, extData: DPS_EXTDATA_TYPE) {
    /*
    干部掉血公式	掉血数	最终伤害*主角攻防加成*伤害减免*伤害幅度*暴击幅度*伤害减免*等级差系数	（1，∞）
    最终伤害	"伤害=最小伤害~最大伤害随机
    最终伤害=伤害*技能加成"	
    最小最大伤害	"最小伤害=最小伤害基础值+攻击*(1+攻击提升百分比)
    最大伤害=最大伤害基础值+攻击*(1+攻击提升百分比)"	
    主角攻防加成	1+己方主角攻击/(己方主角攻击+敌方主角防御+500)	
    伤害减免	1-敌方干部防御/（敌方干部防御+1000+100*己方干部等级）	（0.25，1）
    伤害幅度	1+（己方干部伤害加成-敌方干部伤害减少）+（己方干部PVP伤害加成*敌方干部PVP伤害减少）+（对攻击种类加成-敌方攻击种类抗性）+（对职业种族伤害-敌方种族抗性）+(对元素属性的加成-敌方元素属性的抗性）	"（0.2，∞）
    如果战斗非PVP，则不需要计算PVP伤害加成减免"
    暴击几率	暴击几率=(自身暴击值/(自身暴击值+100+敌方等级*80))+暴击提升百分比	
    暴击幅度	"暴击幅度=1.5+暴击伤害加成
    未暴击时=1"	
    等级差系数	等级差修正=1+(干部自身等级-目标干部等级)*0.03	"(0.1，1.9）
    如果战斗类型为PVP，则=1"
    主角魔法掉血公式	掉血数	技能伤害*英雄力量知识加成*伤害幅度*等级差系数	（1，∞）
    主角力量知识加成	1+己方主角力量/(己方主角力量+敌方主角知识+500)	
    伤害幅度	1+（己方伤害加成-敌方伤害减少）+（对攻击种类加成-敌方攻击种类抗性）+（对职业伤害-敌方职业抗性）+(对元素属性的加成-敌方元素属性的抗性）	（0.2，∞）
    等级差系数	等级差修正=1+(自身主角等级-目标主角等级)*0.03	"(0.1，1.9）
    如果战斗类型为PVP，则=1"
    两次行动概率	两次行动几率	几率=干部自身士气/(干部自身士气+100+己方等级*100)	
    命中概率	命中概率	"命中几率=(干部自身命中值/(干部自身命中值+100+敌方等级*50))+命中百分比
    默认命中几率100%"	
    闪避几率	闪避几率	"闪避几率=(干部自身闪避值/(干部自身闪避值+100+敌方等级*50))+闪避百分比
    默认闪避几率0%"	
    最终是否命中概率	最终是否命中概率	是否命中几率=干部自身命中几率-目标闪避几率	（0.3，∞）
    速度计算	自身速度	运算速度*（1+速度提升百分比）	
    运算速度	自身速度*随机浮动值	
    随机浮动值	0.9-1.1（1位小数）	（-10，10）
    */
   
    if (fromRole.isDead || toRole.isDead) return { num: 0, dps: 0, miss: false, baoji: false, fromRole: fromRole, toRole: toRole };
    let miss = false, baoji = false, dps = 0;
    let fromRoleLv = fromRole.getData('lv'), toRoleLv = toRole.getData('lv');

    let _fmingzhong = (fromRole.getData('mingzhong') + 1) * fromRole.getDataPro('mingzhong');
    let fmingzhong = _fmingzhong / (_fmingzhong + 100 + toRoleLv * 50) + 1;
    let _tmiss = (toRole.getData('shanbi') + 1) * toRole.getDataPro('shanbi');
    let tmiss = _tmiss / (_tmiss + 100 + toRoleLv * 50) + 0;
    let mingzhongLv = fmingzhong - tmiss;
    mingzhongLv = fixValue(mingzhongLv, 0.3);

    if (randNumber() > mingzhongLv) {
        miss = true;
    } else {
        let _fbaoji = (fromRole.getData('baoji') + 1) * fromRole.getDataPro('baooji');
        let baojiLv = _fbaoji / (_fbaoji + 100 + toRoleLv * 80);
        baoji = randNumber(0, 1000) > baojiLv ? false : true;
        let baoshangpro = fromRole.getData('baoshangpro');
        if (fromRole.hasbuff("baonu")) baoji = true;
        let baoshang = baoji ? 1.5 + baoshangpro : 1;

        //干部等级差系数
        let playLvFix = fixValue(1 + (fromRoleLv - toRoleLv) * 0.03, 0.1, 1.9);
        playLvFix = fromRole.fightControl.fightType == 'pvp' ? 1 : playLvFix;

        //伤害减免 damage reduction
        let _tdef = toRole.getData('def') * (toRole.getDataPro('def') + 1);
        //wsdefpro
        let wsdefpro = fromRole.getData("wsdefpro");
        _tdef *= (1 - wsdefpro);
        let dmageReduction = 1 - _tdef / (_tdef + 1000 + 100 * fromRoleLv);
        dmageReduction = fixValue(dmageReduction, 0.25, 1);
        //伤害幅度
        let damagepro = 1 + (fromRole.getData('dpspro') - fromRole.getData('dpsdrop') - toRole.getData('undpspro'));
        if (extData.islong == 0) {
            damagepro += fromRole.getData('neardpspro') - toRole.getData('neardpsdrop');
        } else if (extData.islong == 1) {
            damagepro += fromRole.getData('longdpspro') - toRole.getData('longdpsdrop');
        };

        if (extData.mofa == 0) { //物理
            damagepro += fromRole.getData('phydpspro') - toRole.getData('phydpsdrop');
        } else if (extData.mofa == 5) { // 魔法
            damagepro += fromRole.getData('magdpspro') - toRole.getData('magdpsdrop');
        } else if (extData.mofa == 1) { //地
            damagepro += fromRole.getData('earthdpspro') - toRole.getData('earthdpsdrop');
        } else if (extData.mofa == 2) { //火
            damagepro += fromRole.getData('firedpspro') - toRole.getData('firedpsdrop');
        } else if (extData.mofa == 3) {//水
            damagepro += fromRole.getData('waterdpspro') - toRole.getData('waterdpsdrop');
        } else if (extData.mofa == 4) { //风
            damagepro += fromRole.getData('winddpspro') - toRole.getData('winddpsdrop');
        }
        if (fromRole.fightControl.fightType == 'pvp') {
            damagepro += fromRole.getData('pvpdpspro') - toRole.getData('pvpdpsdrop');
        }
        damagepro = fixValue(damagepro, 0.2);

        //主角攻防加成
        let zj_atk = fromRole.rolePlayer.getData('atk');
        let zj_def = toRole.rolePlayer.getData('def');
        let playerFactor = 1 + zj_atk / (zj_atk + zj_def + 500);

        //最大伤害
        let maxdps = fromRole.getData('maxdps') + (fromRole.getDataPro('atk') + 1) * fromRole.getData('atk');
        //最小伤害
        let mindps = fromRole.getData('mindps') + (fromRole.getDataPro('atk') + 1) * fromRole.getData('atk');

        dps = randNumber(mindps, maxdps);

        let pro = extData.pro || 1;
        dps *= pro;

        //掉血
        dps = dps * playerFactor * dmageReduction * damagepro * baoshang * playLvFix;
    }
    dps = Math.ceil(dps);
    return { num: -dps, dps: -dps, miss: miss, baoji: baoji, fromRole: fromRole, toRole: toRole };
}

export function getPlayerMFDPS(fromRole: FightObj, toRole: FightObj, extData: DPS_EXTDATA_TYPE) {
    if (toRole.isDead) return { num: 0, dps: 0, miss: false, baoji: false, fromRole: fromRole, toRole: toRole };
    let miss = false, baoji = false, dps = 0;
    let fromPlayerLv = fromRole.rolePlayer.getData('lv'), toPlayerLv = toRole.rolePlayer.getData('lv');
    let playLvFix = fixValue(1 + (fromPlayerLv - toPlayerLv) * 0.03, 0.1, 1.9);
    playLvFix = fromRole.fightControl.fightType == 'pvp' ? 1 : playLvFix;

    //伤害幅度
    let damagepro = 1 + (fromRole.getData('dpspro') - toRole.getData('dpsdroppro'));
    if (extData.islong == 0) {
        damagepro += fromRole.getData('neardpspro') - toRole.getData('neardpsdrop');
    } else if (extData.islong == 1) {
        damagepro += fromRole.getData('longdpspro') - toRole.getData('longdpsdrop');
    };

    if (extData.mofa == 0) { //物理
        damagepro += fromRole.getData('phydpspro') - toRole.getData('phydpsdrop');
    } else if (extData.mofa == 5) { // 魔法
        damagepro += fromRole.getData('magdpspro') - toRole.getData('magdpsdrop');
    } else if (extData.mofa == 1) { //地
        damagepro += fromRole.getData('earthdpspro') - toRole.getData('earthdpsdrop');
    } else if (extData.mofa == 2) { //火
        damagepro += fromRole.getData('firedpspro') - toRole.getData('firedpsdrop');
    } else if (extData.mofa == 3) {//水
        damagepro += fromRole.getData('waterdpspro') - toRole.getData('waterdpsdrop');
    } else if (extData.mofa == 4) { //风
        damagepro += fromRole.getData('winddpspro') - toRole.getData('winddpsdrop');
    }
    if (fromRole.fightControl.fightType == 'pvp') {
        damagepro += fromRole.getData('pvpdpspro') - toRole.getData('pvpdpsdrop');
    }
    damagepro = fixValue(damagepro, 0.2);

    //知识力量 加成
    let fplayer = fromRole.rolePlayer, tplayer = toRole.rolePlayer;
    let pl = 1 + fplayer.getData('zhishi') / (fplayer.getData('liliang') + tplayer.getData('zhishi') + 500);
    //掉血
    dps = extData.pro * damagepro * pl * playLvFix;
    dps = Math.ceil(dps);
    return { num: -dps, dps: -dps, miss: miss, baoji: baoji, fromRole: fromRole, toRole: toRole };
}

export function getBuffDPS(toRole: FightObj, fromRole: FightObj, extData: { xiaoguocanshu: k_v<any>, overlapTimes: number }) {
    let miss = false, baoji = false;
    let dps = 0;

    //固定伤害
    if (extData.xiaoguocanshu.value) {
        dps = extData.xiaoguocanshu.value;
    } else if (extData.xiaoguocanshu.type == "maxhp") {
        dps = Math.ceil(toRole.getData('maxHp') * extData.xiaoguocanshu.pro);
    } else if (extData.xiaoguocanshu.type == "hp") {
        dps = Math.ceil(toRole.getData('hp') * extData.xiaoguocanshu.pro);
    } else if (extData.xiaoguocanshu.pro) {
        dps = Math.ceil(fromRole.getData('atk') * extData.xiaoguocanshu.pro);
    }

    dps *= extData.overlapTimes;

    let maxDps = fromRole.getData('maxdps') * 2;

    // todo 主角技能还没有限制百分比的最大伤害，以下判断修复技能buff没有伤害
    if (fromRole.getData('pos') != 7){
        dps = dps > maxDps ? maxDps : dps;
    } else {
        // 主角技能伤害最大值: avg(所有上场干部的maxDps) * 2
        let sumHeroMaxDps = 0, heroCount = 0;
        const fromRoleSide = fromRole.getData('side');
        fromRole.fightControl.fightRolesArr.forEach(role => {
            if (role.getData('pos') < 7 && role.getData('side') === fromRoleSide) {
                sumHeroMaxDps += role.getData('maxdps');
                heroCount++;
            }
        });
        maxDps = sumHeroMaxDps / heroCount * 2;
        dps = dps > maxDps ? maxDps : dps;
    }

    return { num: -dps, dps: -dps, miss: miss, baoji: baoji, fromRole: fromRole, toRole: toRole };

}

export function getFightAddHP(toRole: FightObj, fromRole: FightObj, extData: { pro: number, type: string } & { [k: string]: any; }) {
    let miss = false, baoji = false;
    let dps = 0;

    //根据最大生命回血
    if (extData.type == 'maxhp') {
        dps = toRole.getData('maxHp') * extData.pro;
    };
    let xixuepro = toRole.getData('xixuepro');
    let addhpdrop = toRole.getData('addhpdrop');
    dps *= (1 + xixuepro - addhpdrop);
    dps = Math.ceil(dps);

    return { num: dps, dps: dps, miss: miss, baoji: baoji, fromRole: fromRole, toRole: toRole };
}

