143 lines
4.9 KiB
TypeScript
143 lines
4.9 KiB
TypeScript
import {Command} from "@colyseus/command";
|
|
import {CardGameState} from "../schema/CardGameState";
|
|
import {GameResultCommand} from "./GameResultCommand";
|
|
import {GameStateConst} from "../../constants/GameStateConst";
|
|
import {singleton} from "../../common/Singleton";
|
|
import {GameEnv} from "../../cfg/GameEnv";
|
|
import {NextTurnCommand} from "./NextTurnCommand";
|
|
import {Wait} from "./Wait";
|
|
import {PlayerStateConst} from "../../constants/PlayerStateConst";
|
|
import {Player} from "../schema/Player";
|
|
import gameUtil from "../../utils/game.util";
|
|
import {PartCompare, PartResultMsg} from "../../message/PartResult";
|
|
import {Room} from "colyseus";
|
|
import {PlayDeadCommand} from "./PlayDeadCommand";
|
|
|
|
/**
|
|
* 游戏中的结算轮
|
|
*/
|
|
|
|
export enum CompareEnum {
|
|
ALLDEAD = 0, // 不用考虑
|
|
P0DEAD = 1,
|
|
P1DEAD = 2,
|
|
P0WIN = 3,
|
|
P1WIN = 4,
|
|
DRAW = 5
|
|
}
|
|
|
|
class CompareResult {
|
|
p0: Player;
|
|
p1: Player;
|
|
result: CompareEnum;
|
|
next: Map<number, Player>;
|
|
val?: number;
|
|
constructor(p0: Player, p1: Player) {
|
|
this.next = new Map();
|
|
this.p0 = p0;
|
|
this.p1 = p1;
|
|
}
|
|
}
|
|
|
|
const comparePlayer = function (room: Room, p0: Player, p1: Player): CompareResult {
|
|
let s0 = gameUtil.calcTotalAp(p0);
|
|
let s1 = gameUtil.calcTotalAp(p1);
|
|
let r: CompareResult = new CompareResult(p0, p1);
|
|
if (p0.state == PlayerStateConst.PLAYER_DEAD) {
|
|
if (p1.state == PlayerStateConst.PLAYER_DEAD) {
|
|
r.result = CompareEnum.ALLDEAD;
|
|
} else {
|
|
r.result = CompareEnum.P0DEAD;
|
|
r.next.set(1, p1);
|
|
}
|
|
} else {
|
|
if (p1.state == PlayerStateConst.PLAYER_DEAD) {
|
|
r.result = CompareEnum.P1DEAD;
|
|
r.next.set(0, p0);
|
|
} else {
|
|
if (s0 > s1) {
|
|
let val = s0 - s1;
|
|
p1.hp -= val;
|
|
r.next.set(0, p0);
|
|
r.val = val;
|
|
if (p1.hp <= 0) {
|
|
p1.hp = 0;
|
|
room.dispatcher.dispatch(new PlayDeadCommand(), {player: p1});
|
|
} else {
|
|
r.next.set(1, p1);
|
|
}
|
|
r.result = CompareEnum.P0WIN
|
|
} else if (s0 < s1) {
|
|
let val = s1 - s0;
|
|
p0.hp -= val;
|
|
r.val = val;
|
|
r.next.set(1, p1);
|
|
if (p0.hp <= 0) {
|
|
p0.hp = 0;
|
|
room.dispatcher.dispatch(new PlayDeadCommand(), {player: p0});
|
|
} else {
|
|
r.next.set(0, p0);
|
|
}
|
|
r.result = CompareEnum.P1WIN
|
|
} else {
|
|
r.result = CompareEnum.DRAW;
|
|
r.next.set(0, p0);
|
|
r.next.set(1, p1);
|
|
}
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
export class PartResultCommand extends Command<CardGameState, {}> {
|
|
|
|
execute() : Array<Command> | void {
|
|
this.state.updateGameState(GameStateConst.STATE_ROUND_RESULT);
|
|
const time = singleton(GameEnv).resultShowTime || 1;
|
|
|
|
let t0 = [];
|
|
let t1 = [];
|
|
for (let [, player] of this.state.players) {
|
|
if (player.team == 0) {
|
|
t0.push(player);
|
|
} else {
|
|
t1.push(player);
|
|
}
|
|
}
|
|
let result = [];
|
|
let r0 = comparePlayer(this.room, t0[0], t1[0]);
|
|
let obj0 = new PartCompare(r0.p0.id, r0.p1.id, r0.result, 0, r0.val);
|
|
result.push(obj0)
|
|
let r1 = comparePlayer(this.room, t0[1], t1[1]);
|
|
let obj1 = new PartCompare(r1.p0.id, r1.p0.id, r1.result, 0, r1.val);
|
|
result.push(obj1)
|
|
if (r0.result == CompareEnum.P0DEAD && r1.next.has(0)) {
|
|
let r2 = comparePlayer(this.room, r0.p1, r1.next.get(0));
|
|
let obj2 = new PartCompare(r2.p0.id, r2.p0.id, r2.result, 0, r2.val);
|
|
result.push(obj2)
|
|
} else if (r0.result == CompareEnum.P1DEAD && r1.next.has(1)) {
|
|
let r2 = comparePlayer(this.room, r0.p0, r1.next.get(1));
|
|
let obj2 = new PartCompare(r2.p0.id, r2.p0.id, r2.result, 0, r2.val);
|
|
result.push(obj2)
|
|
}
|
|
|
|
let deadCount0 = 0;
|
|
let deadCount1 = 0;
|
|
for (let [, player] of this.state.players) {
|
|
if (player.team == 0 && player.state == PlayerStateConst.PLAYER_DEAD ) {
|
|
deadCount0 ++;
|
|
} else if (player.team == 1 && player.state == PlayerStateConst.PLAYER_DEAD ){
|
|
deadCount1 ++;
|
|
}
|
|
}
|
|
const roundNum = singleton(GameEnv).duelRoundNum;
|
|
const totalRound = roundNum * singleton(GameEnv).maxDuelNum;
|
|
if ((deadCount0 == 2 || deadCount1 == 2) || (this.state.round >= totalRound - 1)) { // 游戏结束
|
|
return [new Wait().setPayload(time*1000) ,new GameResultCommand()];
|
|
} else { // 下发消息, 进入正常的下一轮
|
|
this.room.bPartResult(new PartResultMsg(result));
|
|
return [new Wait().setPayload(time*1000) ,new NextTurnCommand()];
|
|
}
|
|
}
|
|
|
|
}
|