| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- import { Random } from "../core/utils/Random";
- export class PVPLogic {
- /**随机数种子(建议使用Date.now()) */
- private seed: number;
- /**基础伤害(配置) */
- private baseHit: number;
- /**第一组武将(前5个为自己的武将,后面放置好友武将,建议设置为进攻方武将,暨:自己的武将) */
- private g1: Array<PVPHeroData> = [];
- /**第二组武将(前5个为自己的武将,后面放置好友武将,建议设置为防守方武将,暨:被切磋玩家的武将) */
- private g2: Array<PVPHeroData> = [];
- /**第一组阵营加成 */
- public g1Camp: { attack: number, cri: number } = { attack: 0, cri: 0 };
- /**第二组阵营加成 */
- public g2Camp: { attack: number, cri: number } = { attack: 0, cri: 0 }
- /**线性随机数对象 */
- private random: Random;
- /**战报 */
- private pvpPages: Array<PVPPage> = [];
- /**胜者ID */
- private winner: number = 0;
- /**当前对战武将 */
- private curBattleHero: Map<number, PVPHeroData> = new Map();
- /**先手ID */
- private fristID: number = 0;
- /**后手ID */
- private lastID: number = 0;
- /**buff配置 */
- private buffConfig: any;
- /**羁绊id */
- public fetterID = 0;
- /**
- * PVP逻辑
- * @param g1 第一组武将(建议设置为进攻方武将,暨:自己的武将)
- * @param g2 第二组武将(建议设置为防守方武将,暨:被切磋玩家的武将)
- * @param seed 随机数种子(建议使用Date.now())
- * @param baseHit 基础伤害(配置)
- * @param buffConfig buff配置(配置)
- */
- constructor(g1: Array<PVPHeroData>, g2: Array<PVPHeroData>, seed: number, baseHit: number, buffConfig: any) {
- this.seed = seed;
- this.random = new Random(this.seed);
- this.g1 = g1.concat();
- this.g2 = g2.concat();
- this.baseHit = baseHit;
- this.buffConfig = buffConfig;
- this.checkCamp();
- }
- /**
- * 战斗开始
- * @returns pages 战报数据
- * @returns winner 胜者数据
- */
- public begin(): { pages: Array<PVPPage>, winner: number } {
- this.log("战斗开始");
- this.battle();
- return { pages: this.pvpPages, winner: this.winner };
- }
- /**战斗流程递归 */
- private battle() {
- if (this.curBattleHero.size < 2) {
- this.intoBattle();
- } else {
- if (this.curBattleHero.get(1)._att_count == 0 && this.curBattleHero.get(2)._att_count == 0) {
- this.fristID = this.checkFristAttack();
- this.lastID = this.fristID == 1 ? 2 : 1;
- this.log(`g${this.fristID}-->武将${this.curBattleHero.get(this.fristID).id},先手攻击`);
- this.attack(this.fristID);
- } else {
- let fromID = this.curBattleHero.get(this.fristID)._att_count > this.curBattleHero.get(this.lastID)._att_count ? this.lastID : this.fristID;
- this.attack(fromID);
- }
- }
- }
- /**武将出阵 */
- private intoBattle(): void {
- if (!this.curBattleHero.has(1)) {
- this.curBattleHero.set(1, this.g1.shift());
- this.pvpPages.push(new PVPPage(PVPPageType.intoBattle, 1, this.curBattleHero.get(1).id));
- this.log(`g1-->出战武将${this.curBattleHero.get(1).id},lv:${this.curBattleHero.get(1).lv},star:${this.curBattleHero.get(1).star},color:${this.curBattleHero.get(1).color},g1剩余武将:${this.g1.length}`);
- }
- if (!this.curBattleHero.has(2)) {
- this.curBattleHero.set(2, this.g2.shift());
- this.pvpPages.push(new PVPPage(PVPPageType.intoBattle, 2, this.curBattleHero.get(2).id));
- this.log(`g2-->出战武将${this.curBattleHero.get(2).id},lv:${this.curBattleHero.get(2).lv},star:${this.curBattleHero.get(2).star},color:${this.curBattleHero.get(2).color},g2剩余武将:${this.g2.length}`);
- }
- this.battle();
- }
- /**
- * 武将攻击
- * @param fromID 发生方ID
- */
- private attack(fromID: number): void {
- let defID = fromID == 1 ? 2 : 1;
- let hit = Math.floor((this.baseHit * (1 + this[`g${fromID}Camp`].attack / 10000)) / Math.pow(2, this.curBattleHero.get(defID).lv - this.curBattleHero.get(fromID).lv));
- let random = this.random.range(0, 10000);
- let isCRI = false;
- if (random <= 500 + this[`g${fromID}Camp`].cri) {
- hit = Math.floor(hit * 1.5);
- isCRI = true;
- }
- this.curBattleHero.get(defID)._hp -= hit;
- this.pvpPages.push(new PVPPage(PVPPageType.attack, fromID, this.curBattleHero.get(fromID).id, hit));
- this.curBattleHero.get(fromID)._att_count++;
- this.log(`g${fromID}-->武将${this.curBattleHero.get(fromID).id},是否暴击:${isCRI},攻击-->${hit},g${defID}-->防守武将剩余生命-->${this.curBattleHero.get(defID)._hp}`);
- if (this.curBattleHero.get(defID)._hp <= 0) {
- this.die(defID);
- return;
- }
- this.battle();
- }
- /**
- * 武将死亡
- * @param fromID 发生方ID
- */
- private die(fromID: number): void {
- this.pvpPages.push(new PVPPage(PVPPageType.die, fromID, this.curBattleHero.get(fromID).id));
- this.curBattleHero.get(fromID == 1 ? 2 : 1)._att_count = 0;
- this.log(`g${fromID}-->武将${this.curBattleHero.get(fromID).id},死亡`);
- this.curBattleHero.delete(fromID);
- if (this['g' + fromID].length == 0) {
- this.pvpPages.push(new PVPPage(PVPPageType.end, 0, 0));
- this.winner = fromID == 1 ? 2 : 1;
- this.log(`战斗结束:胜方:${this.winner}`);
- return;
- }
- this.battle();
- }
- /**检查阵营加成 */
- private checkCamp(): void {
- this.sortCamp(1);
- this.log(`g1阵营加成:${JSON.stringify(this.g1Camp)}`);
- this.sortCamp(2);
- this.log(`g2阵营加成:${JSON.stringify(this.g2Camp)}`);
- }
- /**整理阵营数据 */
- private sortCamp(id: number) {
- let camps = [{ camp: 1, count: 0 }, { camp: 2, count: 0 }, { camp: 3, count: 0 }, { camp: 4, count: 0 }];
- let length = this["g" + id].length >= 5 ? 5 : this["g" + id].length;
- for (let i = 0; i < length; i++) {
- let camp = parseInt(this["g" + id][i].camp);
- camps[camp - 1].count++;
- }
- camps = camps.sort(function (a, b) {
- if (a.count > b.count) {
- return -1;
- } else {
- return 1;
- }
- });
- switch (camps[0].count) {
- case 2:
- this.fetterID = 1;
- this[`g${id}Camp`] = { attack: this.buffConfig["1"].attackPer, cri: 0 };
- break;
- case 3:
- this.fetterID = 2;
- this[`g${id}Camp`] = { attack: this.buffConfig["2"].attackPer, cri: 0 };
- if (camps[1].count == 2) {
- this.fetterID = 3;
- this[`g${id}Camp`] = { attack: this.buffConfig["3"].attackPer, cri: this.buffConfig["6"].cri };
- }
- break;
- case 4:
- this.fetterID = 4;
- this[`g${id}Camp`] = { attack: this.buffConfig["4"].attackPer, cri: this.buffConfig["7"].cri };
- break;
- case 5:
- this.fetterID = 5;
- this[`g${id}Camp`] = { attack: this.buffConfig["5"].attackPer, cri: this.buffConfig["8"].cri };
- break;
- }
- }
- /**检查先手武将 */
- private checkFristAttack(): number {
- this.log("检查先手武将");
- if (this.curBattleHero.get(1).star != this.curBattleHero.get(2).star) {
- return this.curBattleHero.get(1).star > this.curBattleHero.get(2).star ? 1 : 2;
- }
- if (this.curBattleHero.get(1).color != this.curBattleHero.get(2).color) {
- return this.curBattleHero.get(1).color > this.curBattleHero.get(2).color ? 1 : 2;
- }
- return Math.floor(this.random.range(1, 3));
- }
- private useLog = true;
- private log(msg: string): void {
- //服务器可以根据seed写入不同文件文件,方便调试
- if (this.useLog) {
- console.log(msg);
- }
- }
- }
- /**
- * PVP武将数据
- */
- export class PVPHeroData {
- public id: number;
- public lv: number;
- public star: number;
- public color: number;
- public camp: number;
- public _hp: number = 100;
- public _att_count: number = 0;
- constructor(id: number, lv: number, star: number, color: number, camp: number) {
- this.id = id;
- this.lv = lv;
- this.star = star;
- this.color = color;
- this.camp = camp;
- }
- }
- /**
- * PVP战报数据
- */
- export class PVPPage {
- /**战报类型 */
- public type: PVPPageType = PVPPageType.none;
- /**发生事件方ID */
- public formID: number;
- /**如果是类型是攻击,则是伤害值 否则为0*/
- public hit: number = 0;
- /**发生事件的英雄ID */
- public heroID: number;
- constructor(type: PVPPageType, fromID: number, heroID: number, hit: number = 0) {
- this.type = type;
- this.formID = fromID;
- this.heroID = heroID;
- this.hit = hit;
- }
- }
- export enum PVPPageType {
- none,
- intoBattle,
- attack,
- die,
- end
- }
|