本文共 17650 字,大约阅读时间需要 58 分钟。
@Datapublic final class CBattleMobMessage extends ClientMessage { private String mobId;}
@Datapublic class SBattleMobMessage extends ServerMessage { private BattleMobResult battleMobResult;}
@Datapublic class BattleMobResult implements Serializable { // 总回合数 private Integer totalRound; // 回合列表 private ListroundList; // 是否玩家获胜 private Boolean playerWin; // 战斗结果信息 private String resultMessage; public BattleMobResult() { this.roundList = new ArrayList<>(); } public void putBattleRound(BattleRound battleRound) { this.roundList.add(battleRound); }}
@Datapublic class BattleRound implements Serializable { // 当前回合数 private Integer number; // 回合内战斗记录 private Listmessages; // 是否战斗结束 private Boolean end; public BattleRound() { this.messages = new ArrayList<>(); this.end = false; } public BattleRound(Integer roundNum) { this(); this.number = roundNum; } public void putMessage(String message) { this.messages.add(message); }}
/** * 获取伤害减免Damage Reduce * * @return */ public Double getDR() { Integer ac = this.getAC(); return ac / (ac + 85 * this.level + 400.0); }
package com.idlewow.game.logic.battle;import com.idlewow.character.model.Character;import com.idlewow.character.model.LevelProp;import com.idlewow.character.service.CharacterService;import com.idlewow.character.service.LevelPropService;import com.idlewow.common.model.CommonResult;import com.idlewow.game.GameConst;import com.idlewow.game.logic.battle.dto.BattleMonster;import com.idlewow.game.logic.battle.dto.BattlePlayer;import com.idlewow.game.logic.battle.util.ExpUtil;import com.idlewow.game.hub.message.vo.battle.BattleMobResult;import com.idlewow.game.logic.battle.dto.BattleUnit;import com.idlewow.game.logic.battle.util.BattleUtil;import com.idlewow.game.hub.message.vo.battle.BattleRound;import com.idlewow.mob.model.MapMob;import com.idlewow.mob.service.MapMobService;import com.idlewow.support.util.CacheUtil;import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.util.LinkedList;import java.util.List;import java.util.Random;@Componentpublic final class BattleCore { private static final Logger logger = LogManager.getLogger(BattleCore.class); // 战斗最大回合数 private static final Integer MaxRound = 20; // 暴击系数 private static final Integer CriticalFactor = 2; @Autowired MapMobService mapMobService; @Autowired LevelPropService levelPropService; @Autowired CharacterService characterService; /** * 在线打怪 * * @param character * @param mobId * @return */ public BattleMobResult battleMapMob(Character character, String mobId) { // 获取地图怪物信息 CommonResult commonResult = mapMobService.find(mobId); if (!commonResult.isSuccess()) { logger.error("未找到指定怪物:id" + mobId); return null; } // 初始化参战方信息 MapMob mapMob = (MapMob) commonResult.getData(); ListatkList = new LinkedList<>(); atkList.add(this.getBattlePlayer(character, GameConst.BattleTeam.ATK)); List defList = new LinkedList<>(); defList.add(this.getBattleMonster(mapMob, GameConst.BattleTeam.DEF)); List battleList = new LinkedList<>(); battleList.addAll(atkList); battleList.addAll(defList); battleList = BattleUtil.sortUnitBySpeed(battleList); // 回合循环 BattleMobResult battleMobResult = new BattleMobResult(); for (int i = 0; i < MaxRound; i++) { BattleRound battleRound = new BattleRound(i + 1); for (BattleUnit battleUnit : battleList) { if (!battleUnit.getIsDefeat()) { // 选定攻击目标 BattleUnit targetUnit = null; if (battleUnit.getTeam().equals(GameConst.BattleTeam.ATK)) { Integer targetIndex = new Random().nextInt(defList.size()); targetUnit = defList.get(targetIndex); } else if (battleUnit.getTeam().equals(GameConst.BattleTeam.DEF)) { Integer targetIndex = new Random().nextInt(atkList.size()); targetUnit = atkList.get(targetIndex); } // 攻方出手ROLL点 Integer roll = new Random().nextInt(100); Double miss = (1 - battleUnit.getHitRate() / (battleUnit.getHitRate() + battleUnit.getDodgeRate())) * 100; Double critical = battleUnit.getCriticalRate() * 100; logger.info("round: " + i + "atk: " + battleUnit.getName() + " def: " + targetUnit.getName() + " roll:" + roll + " miss: " + miss + " cri: " + critical); String desc = ""; if (roll <= miss) { desc = battleUnit.getName() + " 的攻击未命中 " + targetUnit.getName(); } else if (roll <= miss + critical) { Integer damage = BattleUtil.actualDamage(battleUnit.getAP(), targetUnit.getDR()) * CriticalFactor; desc = battleUnit.getName() + " 的攻击暴击,对 " + targetUnit.getName() + " 造成 " + damage + " 点伤害(" + targetUnit.getHp() + " - " + damage + " )"; targetUnit.setHp(targetUnit.getHp() - damage); } else { Integer damage = BattleUtil.actualDamage(battleUnit.getAP(), targetUnit.getDR()); desc = battleUnit.getName() + " 的攻击,对 " + targetUnit.getName() + " 造成 " + damage + " 点伤害(" + targetUnit.getHp() + " - " + damage + " )"; targetUnit.setHp(targetUnit.getHp() - damage); } // 检测守方存活 if (targetUnit.getHp() <= 0) { targetUnit.setIsDefeat(true); desc += ", " + targetUnit.getName() + " 阵亡"; if (battleUnit.getTeam().equals(GameConst.BattleTeam.ATK)) { defList.remove(targetUnit); } else if (battleUnit.getTeam().equals(GameConst.BattleTeam.DEF)) { atkList.remove(targetUnit); } } else { // 检测守方反击动作 // todo } battleRound.putMessage(desc); // 检测战斗结束 if (atkList.size() == 0 || defList.size() == 0) { Boolean playerWin = defList.size() == 0; battleRound.setEnd(true); battleMobResult.setTotalRound(i); battleMobResult.setPlayerWin(playerWin); String resultMessage = "战斗结束! " + character.getName() + (playerWin ? " 获得胜利!" : " 不幸战败!"); battleMobResult.putBattleRound(battleRound); battleMobResult.setResultMessage(resultMessage); // 玩家获胜 进行战斗结算 if (playerWin) { // 经验结算 this.settleExp(character.getLevel(), mapMob.getLevel(), character); // 更新角色数据 characterService.updateSettle(character); } return battleMobResult; } } } battleMobResult.putBattleRound(battleRound); } battleMobResult.setTotalRound(MaxRound); battleMobResult.setResultMessage("战斗回合数已用尽!守方获胜!"); return battleMobResult; } /** * 经验值结算 * @param charLevel 角色等级 * @param mobLevel 怪物等级 * @param character 角色信息 */ private void settleExp(Integer charLevel, Integer mobLevel, Character character) { Integer exp = ExpUtil.getBattleMobExp(charLevel, mobLevel); if (exp > 0) { Integer levelUpExp = CacheUtil.getLevelExp(charLevel); if (character.getExperience() + exp >= levelUpExp) { character.setLevel(charLevel + 1); character.setExperience(character.getExperience() + exp - levelUpExp); } else { character.setExperience(character.getExperience() + exp); } } } /** * 获取角色战斗状态 * @param character 角色信息 * @param battleTeam 所属队伍 * @return */ private BattlePlayer getBattlePlayer(Character character, String battleTeam) { LevelProp levelProp = levelPropService.findByJobAndLevel(character.getJob(), character.getLevel()); BattlePlayer battlePlayer = new BattlePlayer(); battlePlayer.setId(character.getId()); battlePlayer.setName(character.getName()); battlePlayer.setJob(character.getJob()); battlePlayer.setLevel(character.getLevel()); battlePlayer.setHp(levelProp.getHp()); battlePlayer.setStrength(levelProp.getStrength()); battlePlayer.setStamina(levelProp.getStamina()); battlePlayer.setAgility(levelProp.getAgility()); battlePlayer.setIntellect(levelProp.getIntellect()); battlePlayer.setTeam(battleTeam); return battlePlayer; } /** * 获取怪物战斗状态 * @param mapMob 怪物信息 * @param battleTeam 所属队伍 * @return */ private BattleMonster getBattleMonster(MapMob mapMob, String battleTeam) { BattleMonster battleMonster = new BattleMonster(); battleMonster.setId(mapMob.getId()); battleMonster.setName(mapMob.getName()); battleMonster.setLevel(mapMob.getLevel()); battleMonster.setHp(mapMob.getHp()); battleMonster.setDamage(mapMob.getDamage()); battleMonster.setArmour(mapMob.getArmour()); battleMonster.setTeam(battleTeam); return battleMonster; }}
// 加载在线打怪战况 loadBattleMobResult: async function (data) { let that = this; $('.msg-battle').html(''); let rounds = data.battleMobResult.roundList; if (data.battleMobResult.totalRound > 0) { for (let i = 0; i < rounds.length; i++) { let round = rounds[i]; let content = "【第" + round.number + "回合】
"; for (let j = 0; j < round.messages.length; j++) { content += "" + round.messages[j] + "
"; } content += "
"; $('.msg-battle').append(content); await this.sleep(1500); } $('.msg-battle').append("" + data.battleMobResult.resultMessage + "
"); if (data.battleMobResult.playerWin) { that.sendLoadCharacter(); } if (that.isBattle) { that.battleInterval = setTimeout(function () { that.sendBattleMob(that.battleMobId); }, 5000); } // await this.sleep(5000).then(function () { // that.sendBattleMob(data.battleMobResult.mobId); // }); } },
/* 在线打怪 */function battleMob(mobId) { let diff = new Date().getTime() - wowClient.battleMobTime; if (diff < TimeLag.BattleMob * 1000) { let waitSeconds = parseInt(TimeLag.BattleMob - diff / 1000); alert('请勿频繁点击!' + waitSeconds + '秒后可再操作!'); return; } if (mobId === wowClient.battleMobId) { alert("已经在战斗中!请勿重复点击!"); return; } wowClient.battleMobId = mobId; wowClient.battleMobTime = new Date().getTime(); if (!wowClient.isBattle) { wowClient.isBattle = true; wowClient.sendBattleMob(mobId); }}
艾泽拉斯的怪物经验公式是 45+等级*5外域的怪物经验公式是 235+等级*5基础知识魔兽里你选取怪物以后一般名字级别上面有颜色,它指示你和怪物之间的等级差别,骷髅级别 怪物级别大于等于玩家级别的10级红色 怪物级别大于等于玩家级别的5级橙色 怪物级别大于等于玩家级别的3或者4级黄色 怪物级别小于等于玩家级别2级和大于大于等于玩家级别2级之间绿色 怪物级别小于玩家级别3级,但是还未变灰灰色 玩家级别1-5级: 灰色级别小于等于0(没有灰色的怪)玩家级别 6-39级:灰色级别小于等于 玩家级别-(玩家级别÷10取整数上限) -5玩家级别 40-59级:灰色级别小于等于 玩家级别-(玩家级别÷5取整数上限) -1玩家级别 60-70级:灰色级别小于等于 玩家级别-9注:整数上限是指不小于该值的最小整数,比如4.2整数上限是5,3.0整数上限是3单杀怪的经验杀死灰色级别的怪是没有经验的,其他颜色级别的怪单杀的经验值计算如下:(艾泽拉斯)相同级别的怪:经验=(玩家等级×5+45)高等级怪:经验=(玩家等级×5+45)×(1+0.05×(怪物等级-玩家等级) ,当怪物等级大于玩家等级4级以上均按4级计算,哪怕精英怪低等级怪:有一个零差值系数ZD (zero difference value)ZD = 5, when Char Level = 1 - 7ZD = 6, when Char Level = 8 - 9ZD = 7, when Char Level = 10 - 11ZD = 8, when Char Level = 12 - 15ZD = 9, when Char Level = 16 - 19ZD = 11, when Char Level = 20 - 29ZD = 12, when Char Level = 30 - 39ZD = 13, when Char Level = 40 - 44ZD = 14, when Char Level = 45 - 49ZD = 15, when Char Level = 50 - 54ZD = 16, when Char Level = 55 - 59ZD = 17, when Char Level = 60+经验=(玩家等级×5+45)×(1-(玩家等级-怪物等级)÷ 零差值系数)计算的例子如下:假设玩家等级 = 20.那么灰名怪物等级 = 13, 根据以上表格获得.杀掉任何 13 级或者以下的怪得不到经验。同等级基础经验为 (20 * 5 + 45) = 145. 杀掉一个 20 级别的怪将能获得145点经验。对于一个 21级怪, 你将获得 145 * (1 + 0.05 * 1) = 152.2 四舍五入为 152 点经验.根据上面表格ZD值是11。对于18级的怪, 我们将有 145 * (1 - 2/11) = 118.6 四舍五入为 119点经验。对于16级的怪, 我们将有 145 * (1 - 4/11) = 92.3四舍五入为 92点经验.对于14级的怪, 我们将有 145 * (1 - 6/11) = 65.91四舍五入为 66点经验.对于燃烧的远征外域的怪,经验计算较多,笔者根据表格值推论公式如下:相同级别的怪:经验=(玩家等级×5+235)高等级怪:经验=(玩家等级×5+235)×(1+0.05×(怪物等级-玩家等级) ,当怪物等级大于玩家等级4级以上均按4级计算,哪怕精英怪。低等级怪:经验=(玩家等级×5+235)×(1-(玩家等级-怪物等级)÷ 零差值系数)精英怪经验=普通同等级怪经验×2精力充沛时间经验=普通计算经验×2 (耗尽精力充沛点数为止,故而最后一个精力充沛期间杀的怪未必能达到经验×2)影响杀怪经验的因素对于大号带小号或者抢怪的情况,玩家杀怪的经验值就会有变化。一般来说,原则如下:如果你开怪并造成了伤害,那么怪物就是你的;这个时候,如果有别的玩家或者大号来杀了这个怪,那么如果帮助杀怪的人对于这个级别的怪他能够获得经验,则属于抢怪,不会影响你的经验获得;如果帮助你杀怪的人对于这个级别的怪或不得经验,那么就是就属于带小号了,你获得很少很少的经验,非常的不划算。因此,对于一个60级的玩家来带小号,不管什么级别的怪,他都没有经验(TBC以前),所以小号获得的经验非常少!而如果是59的玩家帮忙杀50+的怪,那么经验都是小号的!战斗中如果有别人帮你加血,加血只会扣掉你很少的经验,用大号跟随加血小号练级是不错的办法;别人给你加的伤害护盾(比如说荆棘术什么的)只会影响你非常少的经验,5-10点最坏情况,基本可以无视了,放心的加吧。综上所述,用不满级的相同等级区间里的号带小号效率最高,比如49的带40的,59的带50的…… 但是,大号基本都是60的,没办法,呵呵,只能帮带任务或者副本了。组队经验值根据wiki的资料,这个只是推论,未必精确假设一个队伍中的人都是同等级的,那么每个人的经验=单杀怪的经验÷人数×系数系数是:1人:12人:13人:1.1664人:1.35人:1.4例子如下:杀100经验的怪1人 = 100xp2人 = 50xp 每人.3人 = ~39xp 每人.4人 = ~33xp 每人.5人 = ~28xp 每人.两人队伍计算公式假设 玩家1级别>玩家2级别那么 基础经验按玩家1级别计算最后分得的经验玩家1获得 基础经验×玩家1级别÷(玩家1级别+玩家2级别)玩家1获得 基础经验×玩家2级别÷(玩家1级别+玩家2级别)团队里面经验值要打折(除以2)
转载地址:http://zwmyz.baihongyu.com/