增加辅助机器人
This commit is contained in:
parent
b169103835
commit
4c9e74b571
@ -1,2 +1,2 @@
|
||||
pm2 start npm --name "card" -- run "dev:jc"
|
||||
pm2 start npm --name "robot" -- run "dev:robot"
|
||||
pm2 start npm --name "card" --log-date-format "YYYY-MM-DD HH:MM:ss" -- run "dev:jc"
|
||||
pm2 start npm --name "robot" --log-date-format "YYYY-MM-DD HH:MM:ss" -- run "dev:robot"
|
||||
|
@ -7,3 +7,5 @@ export const error = debug('jc:error');
|
||||
export const msgLog = debug('jc:msg');
|
||||
|
||||
export const robotLog = debug('jc:robot');
|
||||
|
||||
export const assistLog = debug('jc:assist');
|
||||
|
19
src/global.d.ts
vendored
19
src/global.d.ts
vendored
@ -8,6 +8,7 @@ import {RemovePetMsg} from "./message/RemovePetMsg";
|
||||
import {Dispatcher} from "@colyseus/command";
|
||||
import {Delayed} from "@gamestdio/timer/lib/Delayed";
|
||||
import {Player} from "./rooms/schema/Player";
|
||||
import {RobotClient} from "./robot/RobotClient";
|
||||
|
||||
export {};
|
||||
|
||||
@ -34,6 +35,11 @@ declare module "colyseus" {
|
||||
* @param player 玩家id或者玩家的对象
|
||||
*/
|
||||
getClient(player: string | Player): Client;
|
||||
|
||||
/**
|
||||
* 获取当前room的client数量
|
||||
*/
|
||||
clientCount(): number;
|
||||
// >>>>>>>>> Begin of extend send message <<<<<<<<<<<<<
|
||||
/**
|
||||
* 广播玩家加入房间
|
||||
@ -154,6 +160,8 @@ declare module "colyseus" {
|
||||
*/
|
||||
bMsgQueue(datas: IMsg[], options?: any): void;
|
||||
|
||||
send(client: Client, type: string, data?: any): void;
|
||||
|
||||
|
||||
// >>>>>>>>> End of extend send message <<<<<<<<<<<<<
|
||||
|
||||
@ -241,6 +249,17 @@ declare module "colyseus" {
|
||||
*/
|
||||
addRobot(playerId?: string):void;
|
||||
|
||||
/**
|
||||
* 添加一个辅助机器人
|
||||
* @param sessionId
|
||||
*/
|
||||
addAssistClient(sessionId: string): void;
|
||||
/**
|
||||
* 获取当前session的辅助机器人
|
||||
* @param sessionId
|
||||
*/
|
||||
getAssistClient(sessionId: string): RobotClient;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@ import {Player} from "../rooms/schema/Player";
|
||||
import {EffectCardCfg} from "../cfg/parsers/EffectCardCfg";
|
||||
import {SkillTargetType} from "../rooms/logic/skill/SkillConst";
|
||||
import CfgMan from "../rooms/logic/CfgMan";
|
||||
import gameUtil from "../utils/game.util";
|
||||
import assistantUtil from "../utils/assistant.util";
|
||||
|
||||
export class Robot {
|
||||
host: string;
|
||||
@ -37,6 +39,17 @@ export class Robot {
|
||||
}
|
||||
}
|
||||
|
||||
async reConnect(sessionId: string) {
|
||||
try {
|
||||
this.room = await this.client.reconnect(this.roomId, sessionId);
|
||||
this.addListeners();
|
||||
this.sessionId = this.room.sessionId;
|
||||
return this.room.sessionId;
|
||||
} catch (err) {
|
||||
error(`error reConnect room ${this.host}, ${this.roomId}, sessionId: ${sessionId}`);
|
||||
}
|
||||
}
|
||||
|
||||
addListeners() {
|
||||
let self = this;
|
||||
this.room.onMessage("*", (type, data) => {
|
||||
@ -117,129 +130,6 @@ export class Robot {
|
||||
this.room.send(messageType, message);
|
||||
}
|
||||
|
||||
private checkTriple(cardArr: Card[], card?: Card): Card[] {
|
||||
if (card) cardArr.push(card);
|
||||
let pointMap: Map<number, Card[]> = new Map();
|
||||
let cardIdSet: Set<number> = new Set();
|
||||
for (let c of cardArr) {
|
||||
if (c.type !== 1) {
|
||||
continue;
|
||||
}
|
||||
if (pointMap.has(c.number)) {
|
||||
let arr = pointMap.get(c.number);
|
||||
arr.push(c);
|
||||
pointMap.set(c.number, arr);
|
||||
} else {
|
||||
pointMap.set(c.number, [c]);
|
||||
}
|
||||
cardIdSet.add(c.number);
|
||||
}
|
||||
let fetched = false;
|
||||
let result:Card[] = [];
|
||||
// 优先出对子
|
||||
for (let [point, arr] of pointMap) {
|
||||
if (card) {
|
||||
if (point == card.number && arr.length >= 3) {
|
||||
fetched = true;
|
||||
result = arr;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (arr.length >= 3) {
|
||||
fetched = true;
|
||||
result = arr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (fetched) {
|
||||
return result;
|
||||
}
|
||||
|
||||
let cardIds = [...cardIdSet];
|
||||
cardIds.sort((a, b) => a - b);
|
||||
let tmp = [];
|
||||
for (let i = 0, length = cardIds.length; i < length; i++) {
|
||||
let cur = cardIds[i];
|
||||
i == 0 && tmp.push(cur);
|
||||
if (i > 0) {
|
||||
if (cur != tmp[i - 1] + 1) {
|
||||
tmp.length = 0;
|
||||
}
|
||||
tmp.push(cur);
|
||||
}
|
||||
if (card) {
|
||||
if (tmp.indexOf(card.number) >= 0 && tmp.length >=3 ){
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (tmp.length >= 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp.length >= 3) {
|
||||
let subTmp = [];
|
||||
for (let i = tmp[0] - 1; i > 0 ; i -- ) {
|
||||
if (cardIdSet.has(i)) {
|
||||
subTmp.push(i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let i = tmp[tmp.length]; i < cardIdSet.size; i ++) {
|
||||
if (cardIdSet.has(i)) {
|
||||
subTmp.push(i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
tmp = tmp.concat(subTmp);
|
||||
for (let point of tmp) {
|
||||
if (card && point === card.number) {
|
||||
result.push(card);
|
||||
} else {
|
||||
result.push(pointMap.get(point)[0]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return arrUtil.randomGet(cardArr, 1);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 随机获取敌对玩家
|
||||
* @private
|
||||
*/
|
||||
private getEnemyPlayer(): Player {
|
||||
let enemys = [];
|
||||
for (let [,player] of this.room.state.players) {
|
||||
if (player.team !== this.player.team) {
|
||||
enemys.push(player);
|
||||
}
|
||||
}
|
||||
return arrUtil.randomOne(enemys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机获取可用的随从
|
||||
* @param player
|
||||
* @private
|
||||
*/
|
||||
private getRandomPet(player: Player): number {
|
||||
let pets = [];
|
||||
for (let [, pet] of player.pets) {
|
||||
if (pet.ap > 0 && pet.state == 1)
|
||||
pets.push(pet);
|
||||
}
|
||||
let result;
|
||||
if (pets.length > 0) {
|
||||
result = arrUtil.randomOne(pets);
|
||||
}
|
||||
return result ? result.pos : -1;
|
||||
}
|
||||
|
||||
// >>>>>>>>>>>>>>>>>> begin
|
||||
/**
|
||||
@ -247,13 +137,9 @@ export class Robot {
|
||||
* @private
|
||||
*/
|
||||
private async selectHero() {
|
||||
let heroMap: Map<number, HeroCfg> = global.$cfg.get(BaseConst.HERO);
|
||||
let heroArr = [...heroMap.values()];
|
||||
let hero = arrUtil.randomGet(heroArr, 1);
|
||||
await this.delay(2);
|
||||
this.reply('select_hero_c2s', {
|
||||
heroId: hero[0].id
|
||||
});
|
||||
let data = assistantUtil.randomHero();
|
||||
this.reply('select_hero_c2s', data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -284,7 +170,7 @@ export class Robot {
|
||||
await this.delay(3);
|
||||
let self = this;
|
||||
let cardArr = [...self.player.cards.values()];
|
||||
let cards = self.checkTriple(cardArr);
|
||||
let cards = assistantUtil.checkTriple(cardArr);
|
||||
if (!cards) {
|
||||
return;
|
||||
}
|
||||
@ -302,7 +188,7 @@ export class Robot {
|
||||
await this.delay(2);
|
||||
let targetCard = [...this.room.state.cards.values()][0];
|
||||
let cardArr = [...this.player.cards.values()];
|
||||
let tmpCards = this.checkTriple(cardArr, targetCard);
|
||||
let tmpCards = assistantUtil.checkTriple(cardArr, targetCard);
|
||||
let next = this.giveup.bind(this);
|
||||
if (tmpCards.length > 1) {
|
||||
let cardIds: number[] = [];
|
||||
@ -345,66 +231,8 @@ export class Robot {
|
||||
* @private
|
||||
*/
|
||||
private async selectPet() {
|
||||
await this.delay(5, 0.2);
|
||||
let cards = [...this.room.state.cards.values()];
|
||||
let result;
|
||||
let effectMap: Map<number, EffectCardCfg> = global.$cfg.get(BaseConst.EFFECTCARD);
|
||||
for (let card of cards) {
|
||||
let effect = effectMap.get(card.effect);
|
||||
if (effect.type_id == 1) {
|
||||
result = card;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!result) {
|
||||
result = arrUtil.randomGet(cards, 1)[0];
|
||||
}
|
||||
let targetType: SkillTargetType = CfgMan.getTargetByCard(result.id);
|
||||
let targetPlayer;
|
||||
let targetPos;
|
||||
switch (targetType) {
|
||||
case SkillTargetType.ENEMY_PLAYER:
|
||||
targetPlayer = this.getEnemyPlayer();
|
||||
break;
|
||||
case SkillTargetType.ENEMY_PET:
|
||||
for (let [,player] of this.room.state.players) {
|
||||
if (player.team !== this.player.team) {
|
||||
let pos = this.getRandomPet(player);
|
||||
if (pos > - 1) {
|
||||
targetPlayer = player;
|
||||
targetPos = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SkillTargetType.FRIEND_PET:
|
||||
for (let [,player] of this.room.state.players) {
|
||||
if (player.team == this.player.team) {
|
||||
let pos = this.getRandomPet(player);
|
||||
if (pos > - 1) {
|
||||
targetPlayer = player;
|
||||
targetPos = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SkillTargetType.SELF_PET:
|
||||
let pos = this.getRandomPet(this.player);
|
||||
if (pos > - 1) {
|
||||
targetPlayer = this.player;
|
||||
targetPos = pos;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.reply('select_pet_c2s', {
|
||||
card: result.id,
|
||||
player: targetPlayer?.id,
|
||||
pos: targetPos,
|
||||
effCards: []
|
||||
})
|
||||
let data = await assistantUtil.selectPet(this.player, this.room.state);
|
||||
this.reply('select_pet_c2s', data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,19 +1,12 @@
|
||||
import {Client, Room} from "colyseus";
|
||||
import {ClientState, ISendOptions} from "colyseus/lib/transport/Transport";
|
||||
import {EventEmitter} from 'events';
|
||||
import {robotLog as log} from '../common/Debug';
|
||||
import {assistLog as log} from '../common/Debug';
|
||||
import {CardGameState} from "../rooms/schema/CardGameState";
|
||||
import Clock from "@gamestdio/timer";
|
||||
import {GameStateConst} from "../constants/GameStateConst";
|
||||
import {Card} from "../rooms/schema/Card";
|
||||
import {BaseConst} from "../constants/BaseConst";
|
||||
import arrUtil from "../utils/array.util";
|
||||
import {HeroCfg} from "../cfg/parsers/HeroCfg";
|
||||
import {EffectCardCfg} from "../cfg/parsers/EffectCardCfg";
|
||||
import CfgMan from '../rooms/logic/CfgMan';
|
||||
import {SkillTargetType} from "../rooms/logic/skill/SkillConst";
|
||||
import {Player} from "../rooms/schema/Player";
|
||||
import gameUtil from "../utils/game.util";
|
||||
import assistantUtil from "../utils/assistant.util";
|
||||
|
||||
export class RobotClient implements Client {
|
||||
id: string;
|
||||
@ -23,26 +16,19 @@ export class RobotClient implements Client {
|
||||
selfPlayer: Player;
|
||||
state: ClientState;
|
||||
svrstate: CardGameState;
|
||||
room: Room;
|
||||
clock: Clock;
|
||||
myTurn: boolean = false;
|
||||
cards: Map<String, Card>;
|
||||
onMessageHandlers: {[id: string]: (client: Client, message: any) => void} = {};
|
||||
listenerState: any;
|
||||
listenerTurn: any;
|
||||
active: boolean = false;
|
||||
|
||||
constructor(sessionId: string, state: CardGameState, clock: Clock, onMessageHandlers: {[id: string]: (client: Client, message: any) => void}) {
|
||||
constructor(sessionId: string, state: CardGameState, onMessageHandlers: {[id: string]: (client: Client, message: any) => void}) {
|
||||
this.sessionId = sessionId;
|
||||
this.svrstate = state;
|
||||
this.selfPlayer = this.svrstate.players.get(sessionId);
|
||||
this.clock = clock;
|
||||
this.ref = new EventEmitter();
|
||||
this.onMessageHandlers = onMessageHandlers;
|
||||
let self = this;
|
||||
let time = Math.random() * 2500 | 0;
|
||||
this.clock.setTimeout(function (){
|
||||
self.reply('play_ready_c2s', '');
|
||||
}, time);
|
||||
this.addListeners();
|
||||
|
||||
log(`new robot with session: ${sessionId}`);
|
||||
@ -74,13 +60,15 @@ export class RobotClient implements Client {
|
||||
|
||||
private gameSateUpdate(currentValue: number, previousValue: number) {
|
||||
let self = this;
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
log(`server game state change: ${currentValue}, pre value: ${previousValue}`);
|
||||
switch (currentValue) {
|
||||
case GameStateConst.CHANGE_HERO:
|
||||
self.selectHero();
|
||||
break;
|
||||
case GameStateConst.STATE_CHANGE_CARD:
|
||||
self.cards = self.svrstate.players.get(self.sessionId).cards;
|
||||
self.changeCard();
|
||||
break;
|
||||
case GameStateConst.STATE_BEGIN_EAT:
|
||||
@ -94,8 +82,11 @@ export class RobotClient implements Client {
|
||||
}
|
||||
private gameTurnUpdate(currentValue: string, previousValue: string) {
|
||||
let self = this;
|
||||
log(`server turn change: ${currentValue}, pre value: ${previousValue}`);
|
||||
self.myTurn = currentValue === self.sessionId;
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
log(`server turn change: ${currentValue}, pre value: ${previousValue}`);
|
||||
if (self.myTurn) {
|
||||
self.discard();
|
||||
}
|
||||
@ -104,6 +95,9 @@ export class RobotClient implements Client {
|
||||
public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {
|
||||
log(`receive server msg: ${messageOrType}, ${messageOrOptions}`);
|
||||
let self = this;
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
let data = messageOrOptions;
|
||||
switch (messageOrType) {
|
||||
case 'draw_card_s2c':
|
||||
@ -127,99 +121,34 @@ export class RobotClient implements Client {
|
||||
(this.onMessageHandlers['*'] as any)(this, messageType, message);
|
||||
}
|
||||
}
|
||||
|
||||
private checkTriple(cardArr: Card[], card?: Card): Card[] {
|
||||
if (card) cardArr.push(card);
|
||||
let cards = cardArr.filter(o => o.type == 1);
|
||||
cards.sort((a, b) => a.number - b.number);
|
||||
let result = [];
|
||||
for (let i = 0, length = cards.length; i < length; i ++) {
|
||||
let cur = cards[i];
|
||||
i == 0 && result.push(cur);
|
||||
if (i > 0) {
|
||||
let isSame = false;
|
||||
if (result.length > 1) {
|
||||
if (result[result.length - 1].number == result[result.length - 2].number) {
|
||||
isSame = true;
|
||||
}
|
||||
}
|
||||
if ((result[result.length - 1].number == cur.number) && (isSame || result.length == 1)) {
|
||||
result.push(cur);
|
||||
} else if ((result[result.length - 1].number + 1 == cur.number) && (!isSame || result.length == 1)) {
|
||||
result.push(cur);
|
||||
} else {
|
||||
result.length = 0;
|
||||
result.push(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.length < 3) {
|
||||
return [cards[0]];
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 随机获取敌对玩家
|
||||
* @private
|
||||
*/
|
||||
private getEnemyPlayer(): Player {
|
||||
let enemys = [];
|
||||
for (let [,player] of this.svrstate.players) {
|
||||
if (player.team !== this.selfPlayer.team) {
|
||||
enemys.push(player);
|
||||
}
|
||||
}
|
||||
return arrUtil.randomOne(enemys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机获取可用的随从
|
||||
* @param player
|
||||
* @private
|
||||
*/
|
||||
private getRandomPet(player: Player): number {
|
||||
let pets = [];
|
||||
for (let [, pet] of player.pets) {
|
||||
if (pet.ap > 0 && pet.state == 1)
|
||||
pets.push(pet);
|
||||
}
|
||||
let result;
|
||||
if (pets.length > 0) {
|
||||
result = arrUtil.randomOne(pets);
|
||||
}
|
||||
return result ? result.pos : -1;
|
||||
}
|
||||
// >>>>>>>>>>>>>>>>>> begin
|
||||
/**
|
||||
* 出牌
|
||||
* @private
|
||||
*/
|
||||
private discard() {
|
||||
private async discard() {
|
||||
await assistantUtil.delay(3);
|
||||
let self = this;
|
||||
let next = function () {
|
||||
let cardArr = [...self.cards.values()];
|
||||
// cardArr.sort((a, b) => a.number - b.number);
|
||||
let cards = self.checkTriple(cardArr);
|
||||
if (!cards) {
|
||||
return;
|
||||
}
|
||||
let cardIds = cards.map(o => o.id);
|
||||
self.reply('discard_card_c2s', {
|
||||
cards: cardIds
|
||||
});
|
||||
let cardArr = [...self.selfPlayer.cards.values()];
|
||||
let cards = assistantUtil.checkTriple(cardArr);
|
||||
if (!cards) {
|
||||
return;
|
||||
}
|
||||
this.clock.setTimeout(next, 1500);
|
||||
let cardIds = cards.map(o => o.id);
|
||||
self.reply('discard_card_c2s', {
|
||||
cards: cardIds
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 吃牌或者放弃
|
||||
* @private
|
||||
*/
|
||||
private eatOrGiveUp() {
|
||||
private async eatOrGiveUp() {
|
||||
await assistantUtil.delay(2);
|
||||
let targetCard = [...this.svrstate.cards.values()][0];
|
||||
let cardArr = [...this.cards.values()];
|
||||
let tmpCards = this.checkTriple(cardArr, targetCard);
|
||||
let cardArr = [...this.selfPlayer.cards.values()];
|
||||
let tmpCards = assistantUtil.checkTriple(cardArr, targetCard);
|
||||
let next = this.giveup.bind(this);
|
||||
if (tmpCards.length > 1) {
|
||||
let cardIds: number[] = [];
|
||||
@ -230,8 +159,7 @@ export class RobotClient implements Client {
|
||||
}
|
||||
next = this.eatCard.bind(this, cardIds, targetCard.id);
|
||||
}
|
||||
|
||||
this.clock.setTimeout(next, 1500);
|
||||
next.apply(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,17 +184,23 @@ export class RobotClient implements Client {
|
||||
this.reply('give_up_eat_c2s', {});
|
||||
}
|
||||
|
||||
/**
|
||||
* 开局装备
|
||||
* @private
|
||||
*/
|
||||
private async setReady() {
|
||||
await assistantUtil.delay(2.5);
|
||||
this.reply('play_ready_c2s', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* 开局选择英雄
|
||||
* @private
|
||||
*/
|
||||
private selectHero() {
|
||||
let heroMap: Map<number, HeroCfg> = global.$cfg.get(BaseConst.HERO);
|
||||
let heroArr = [...heroMap.values()];
|
||||
let hero = arrUtil.randomGet(heroArr, 1);
|
||||
this.reply('select_hero_c2s', {
|
||||
heroId: hero[0].id
|
||||
});
|
||||
private async selectHero() {
|
||||
await assistantUtil.delay(2);
|
||||
let data = assistantUtil.randomHero();
|
||||
this.reply('select_hero_c2s', data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -286,66 +220,9 @@ export class RobotClient implements Client {
|
||||
* 选择一个法术或者一个随从
|
||||
* @private
|
||||
*/
|
||||
private selectPet() {
|
||||
let cards = [...this.svrstate.cards.values()];
|
||||
let result;
|
||||
let effectMap: Map<number, EffectCardCfg> = global.$cfg.get(BaseConst.EFFECTCARD);
|
||||
for (let card of cards) {
|
||||
let effect = effectMap.get(card.effect);
|
||||
if (effect.type_id == 1) {
|
||||
result = card;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!result) {
|
||||
result = arrUtil.randomGet(cards, 1)[0];
|
||||
}
|
||||
let targetType: SkillTargetType = CfgMan.getTargetByCard(result.id);
|
||||
let targetPlayer;
|
||||
let targetPos;
|
||||
switch (targetType) {
|
||||
case SkillTargetType.ENEMY_PLAYER:
|
||||
targetPlayer = this.getEnemyPlayer();
|
||||
break;
|
||||
case SkillTargetType.ENEMY_PET:
|
||||
for (let [,player] of this.svrstate.players) {
|
||||
if (player.team !== this.selfPlayer.team) {
|
||||
let pos = this.getRandomPet(player);
|
||||
if (pos > - 1) {
|
||||
targetPlayer = player;
|
||||
targetPos = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SkillTargetType.FRIEND_PET:
|
||||
for (let [,player] of this.svrstate.players) {
|
||||
if (player.team == this.selfPlayer.team) {
|
||||
let pos = this.getRandomPet(player);
|
||||
if (pos > - 1) {
|
||||
targetPlayer = player;
|
||||
targetPos = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SkillTargetType.SELF_PET:
|
||||
let pos = this.getRandomPet(this.selfPlayer);
|
||||
if (pos > - 1) {
|
||||
targetPlayer = this.selfPlayer;
|
||||
targetPos = pos;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.reply('select_pet_c2s', {
|
||||
card: result.id,
|
||||
player: targetPlayer?.id,
|
||||
pos: targetPos,
|
||||
effCards: []
|
||||
})
|
||||
private async selectPet() {
|
||||
let data = await assistantUtil.selectPet(this.selfPlayer, this.svrstate);
|
||||
this.reply('select_pet_c2s', data)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,4 +6,9 @@ export class RobotManage {
|
||||
let robot = new Robot(host, room);
|
||||
let sessionId = await robot.connect();
|
||||
}
|
||||
|
||||
async reConnect({host, room, sessionId}: { host: string, room: string, sessionId: string }) {
|
||||
let robot = new Robot(host, room);
|
||||
await robot.reConnect(sessionId);
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,20 @@ const router = express.Router();
|
||||
|
||||
router.get('/create', async (req, res, next) => {
|
||||
let query = req.query;
|
||||
let {host, room } = query;
|
||||
let {host, room, sessionId } = query;
|
||||
host = host as string;
|
||||
room = room as string;
|
||||
debug(`receive create robot msg: ${host}, ${room}`);
|
||||
|
||||
let manage = singleton(RobotManage);
|
||||
try {
|
||||
await manage.addOne({host, room});
|
||||
if (sessionId) {
|
||||
sessionId = sessionId as string;
|
||||
debug(`receive reconnect msg: ${host}, ${room}, ${sessionId}`);
|
||||
await manage.reConnect({host, room, sessionId})
|
||||
} else {
|
||||
debug(`receive create robot msg: ${host}, ${room}`);
|
||||
await manage.addOne({host, room});
|
||||
}
|
||||
res.json({errcode: 0});
|
||||
} catch (err) {
|
||||
res.json({errcode: 1})
|
||||
|
@ -27,6 +27,9 @@ export class GeneralRoom extends Room {
|
||||
battleMan = new BattleHandler();
|
||||
// 用于游戏过程中各种计时器, 使用该计时器的前提是, 只针对当前操作玩家
|
||||
gameClock: Map<string, Delayed> = new Map();
|
||||
|
||||
assistMap: Map<String, RobotClient> = new Map();
|
||||
|
||||
async onAuth (client:Client, options: any, request: IncomingMessage) {
|
||||
console.log(options);
|
||||
// TODO: 验证用户信息
|
||||
@ -102,19 +105,24 @@ export class GeneralRoom extends Room {
|
||||
async onLeave (client: Client, consented: boolean) {
|
||||
if (this.state.gameState === GameStateConst.STATE_GAME_OVER || this.state.gameState === GameStateConst.STATE_WAIT_JOIN) {
|
||||
this.state.players.delete(client.sessionId);
|
||||
this.assistMap.delete(client.sessionId);
|
||||
this.bUserLeft(client.sessionId);
|
||||
} else {
|
||||
this.state.players.get(client.sessionId).state = PlayerStateConst.PLAYER_OFFLINE;
|
||||
let assistClient = this.getAssistClient(client.sessionId);
|
||||
assistClient.active = true;
|
||||
try {
|
||||
if (consented) {
|
||||
throw new Error("consented leave");
|
||||
} else {
|
||||
await this.allowReconnection(client, 60);
|
||||
debugRoom(`${client.sessionId} 重连`);
|
||||
assistClient.active = false;
|
||||
this.state.players.get(client.sessionId).state = PlayerStateConst.PLAYER_NORMAL;
|
||||
}
|
||||
await this.allowReconnection(client, 60);
|
||||
this.state.players.get(client.sessionId).state = PlayerStateConst.PLAYER_NORMAL;
|
||||
|
||||
} catch (e) {
|
||||
debugRoom(`player realy level :${client.sessionId}`);
|
||||
this.state.players.delete(client.sessionId);
|
||||
debugRoom(`player realy level :${client.sessionId}, try add robot`);
|
||||
// this.state.players.delete(client.sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -125,17 +133,26 @@ export class GeneralRoom extends Room {
|
||||
|
||||
getClient(player: string | Player): Client {
|
||||
let result: Client;
|
||||
let sessionId;
|
||||
if (typeof player == 'string') {
|
||||
sessionId = player;
|
||||
result = this.clients.find(client => client.sessionId == player );
|
||||
} else {
|
||||
sessionId = player.id;
|
||||
result = this.clients.find(client => client.sessionId == player.id );
|
||||
}
|
||||
if (!result) {
|
||||
error(`无法获取id为: ${typeof player == 'string' ? player : player.id} 的客户端`)
|
||||
error(`无法获取id为: ${typeof player == 'string' ? player : player.id} 的客户端`);
|
||||
result = this.getAssistClient(sessionId);
|
||||
debugRoom(`启用辅助机器人, 当前机器人状态: ${(result as RobotClient).active}`)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
clientCount(): number {
|
||||
return this.clients.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给room.gameClock设定任务
|
||||
* gameClock任何时候只有一个可执行的任务
|
||||
@ -213,7 +230,9 @@ export class GeneralRoom extends Room {
|
||||
let data = {
|
||||
host: 'ws://127.0.0.1:2567',
|
||||
room: this.roomId,
|
||||
sessionId: playerId
|
||||
}
|
||||
|
||||
axios.get('http://127.0.0.1:2500/robot/create', {
|
||||
params: data
|
||||
}).then((res) => {
|
||||
@ -247,4 +266,13 @@ export class GeneralRoom extends Room {
|
||||
// }
|
||||
// this._events.emit('join', client);
|
||||
}
|
||||
|
||||
addAssistClient(sessionId: string) {
|
||||
let client = new RobotClient(sessionId, this.state, this['onMessageHandlers']);
|
||||
this.assistMap.set(sessionId, client);
|
||||
}
|
||||
|
||||
getAssistClient(sessionId: string): RobotClient {
|
||||
return this.assistMap.get(sessionId);
|
||||
}
|
||||
}
|
||||
|
@ -215,6 +215,17 @@ Object.defineProperties(Room.prototype, {
|
||||
value: function (client: Client, data?: any) {
|
||||
client && client.send("change_card_s2c", data);
|
||||
}
|
||||
},
|
||||
|
||||
send: {
|
||||
value: function (client: Client, type: string, data?: any) {
|
||||
if (client) {
|
||||
client.send(type, data);
|
||||
} else {
|
||||
let assistClient = this.getAssistClient(client.sessionId);
|
||||
assistClient && assistClient.send(type, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -21,8 +21,8 @@ export class BeginGameCommand extends Command<CardGameState, {}> {
|
||||
let cardAll = card0.concat(card1);
|
||||
arrUtil.randomSort(cardAll);
|
||||
this.state.cardQueue = cardAll;
|
||||
for (let client of this.room.clients) {
|
||||
this.room.addCard(client.sessionId, singleton(GameEnv).initCardNum, 0);
|
||||
for (let [id] of this.state.players) {
|
||||
this.room.addCard(id, singleton(GameEnv).initCardNum, 0);
|
||||
}
|
||||
this.state.updateGameState(GameStateConst.STATE_CHANGE_CARD);
|
||||
// 超时后结束换卡, 进入下一轮
|
||||
|
@ -24,15 +24,15 @@ export class DiscardCommand extends Command<CardGameState, { client: Client, car
|
||||
execute({ client, cards , dtype} = this.payload) {
|
||||
const player = this.state.players.get(client.sessionId);
|
||||
if (!player) {
|
||||
client && client.send('discard_card_s2c', {errcode: 1, errmsg: 'player不存在'});
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 1, errmsg: 'player不存在'});
|
||||
return;
|
||||
}
|
||||
if (!gameUtil.checkCardsExists(player.cards, cards)) {
|
||||
client && client.send('discard_card_s2c', {errcode: 2, errmsg: '要出的牌在手牌中不存在'});
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 2, errmsg: '要出的牌在手牌中不存在'});
|
||||
return;
|
||||
}
|
||||
if (this.state.currentTurn != client.sessionId) {
|
||||
client && client.send('discard_card_s2c', {errcode: 3, errmsg: '不是当前轮'});
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 3, errmsg: '不是当前轮'});
|
||||
return;
|
||||
}
|
||||
let tmpCards = [];
|
||||
@ -40,7 +40,7 @@ export class DiscardCommand extends Command<CardGameState, { client: Client, car
|
||||
tmpCards.push(player.cards.get(id + ''));
|
||||
}
|
||||
if (!gameUtil.checkDiscard(tmpCards)) {
|
||||
client && client.send('discard_card_s2c', {errcode: 4, errmsg: '出牌不符合规则'});
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 4, errmsg: '出牌不符合规则'});
|
||||
return;
|
||||
}
|
||||
for (let [key, val] of this.state.cards) {
|
||||
@ -65,7 +65,7 @@ export class DiscardCommand extends Command<CardGameState, { client: Client, car
|
||||
* 如果出一张牌的话, 进入胡牌轮
|
||||
* 否则直接进入选随从轮
|
||||
*/
|
||||
client && client.send('discard_card_s2c', {errcode: 0, cards: cards, type: dtype})
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 0, cards: cards, type: dtype})
|
||||
if (cards.length === 1) {
|
||||
let cardArr: Card[] = [...this.state.cards.values()];
|
||||
this.room.battleMan.onCardDiscarded(player, cardArr[0])
|
||||
@ -79,7 +79,7 @@ export class DiscardCommand extends Command<CardGameState, { client: Client, car
|
||||
this.room.battleMan.onCardLinkOver(player, cardArr);
|
||||
this.state.updateGameState(GameStateConst.STATE_PICK_PET);
|
||||
let self = this;
|
||||
client && client.send('eat_card_s2c', {player: player.id, errcode: 0, errmsg: ''});
|
||||
this.room.send(client,'eat_card_s2c', {player: player.id, errcode: 0, errmsg: ''});
|
||||
let time = singleton(GameEnv).playerActTime * 1000 + player.extraTime;
|
||||
// 开启选随从计时, 计时结束后结束当前轮
|
||||
let timeOverSelectPet = function () {
|
||||
|
@ -12,19 +12,19 @@ export class EatCardCommand extends Command<CardGameState, { client: Client, car
|
||||
execute({ client, cards, target } = this.payload) {
|
||||
const player = this.state.players.get(client.sessionId);
|
||||
if (!player) {
|
||||
client && client.send('eat_card_s2c', {errcode: 1, errmsg: 'player不存在或者'});
|
||||
this.room.send(client,'eat_card_s2c', {errcode: 1, errmsg: 'player不存在或者'});
|
||||
return;
|
||||
}
|
||||
if (!gameUtil.checkCardsExists(player.cards, cards)) {
|
||||
client && client.send('eat_card_s2c', {errcode: 2, errmsg: '要出的牌在手牌中不存在'});
|
||||
this.room.send(client,'eat_card_s2c', {errcode: 2, errmsg: '要出的牌在手牌中不存在'});
|
||||
return;
|
||||
}
|
||||
if (this.state.currentTurn == client.sessionId) {
|
||||
client && client.send('eat_card_s2c', {errcode: 3, errmsg: '不能吃自己的牌'});
|
||||
this.room.send(client,'eat_card_s2c', {errcode: 3, errmsg: '不能吃自己的牌'});
|
||||
return;
|
||||
}
|
||||
if (!this.state.cards.has(target + '')) {
|
||||
client && client.send('eat_card_s2c', {errcode: 4, errmsg: '找不到要吃的牌'});
|
||||
this.room.send(client,'eat_card_s2c', {errcode: 4, errmsg: '找不到要吃的牌'});
|
||||
return;
|
||||
}
|
||||
let tmpCards = [];
|
||||
@ -33,16 +33,16 @@ export class EatCardCommand extends Command<CardGameState, { client: Client, car
|
||||
}
|
||||
tmpCards.push(this.state.cards.get(target + ''));
|
||||
if (!gameUtil.checkDiscard(tmpCards)) {
|
||||
client && client.send('discard_card_s2c', {errcode: 5, errmsg: '不符合吃牌规则'});
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 5, errmsg: '不符合吃牌规则'});
|
||||
return;
|
||||
}
|
||||
if (this.state.gameState !== GameStateConst.STATE_BEGIN_EAT) {
|
||||
client && client.send('discard_card_s2c', {errcode: 7, errmsg: '不是吃牌轮'});
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 7, errmsg: '不是吃牌轮'});
|
||||
return;
|
||||
}
|
||||
//将吃牌数据临时保存
|
||||
if (this.state.tmpActionMap.has(client.sessionId)) {
|
||||
client && client.send('discard_card_s2c', {errcode: 8, errmsg: '不可更改操作'});
|
||||
this.room.send(client,'discard_card_s2c', {errcode: 8, errmsg: '不可更改操作'});
|
||||
return ;
|
||||
}
|
||||
this.state.tmpActionMap.set(client.sessionId, cards);
|
||||
|
@ -101,12 +101,12 @@ export class EatConfirmCommand extends Command<CardGameState, { timeUp: boolean
|
||||
// 成功后广播吃牌成功消息
|
||||
let client = this.room.getClient(player.id);
|
||||
this.room.broadcast('eat_card_s2c', {player: player.id, errcode: 0, errmsg: ''}, {except: client});
|
||||
client && client.send('eat_card_s2c', {player: player.id, errcode: 0, errmsg: ''});
|
||||
this.room.send(client,'eat_card_s2c', {player: player.id, errcode: 0, errmsg: ''});
|
||||
// 向其他玩家发送吃卡失败的消息
|
||||
for (let [key, val] of tmpActionMap) {
|
||||
if (typeof val != 'number' && key !== player.id) {
|
||||
let client = this.room.getClient(key);
|
||||
client && client.send('eat_card_s2c', {errcode: 9, errmsg: '吃卡失败'});
|
||||
this.room.send(client,'eat_card_s2c', {errcode: 9, errmsg: '吃卡失败'});
|
||||
}
|
||||
}
|
||||
} else if (!player && timeUp) {
|
||||
|
@ -50,7 +50,7 @@ export class GMCommand extends Command<CardGameState, {client: Client, message:
|
||||
str += '更新英雄血量: herohp:玩家index|血量 例: herohp:0|500 \n';
|
||||
str += '生成几张特定效果的卡: addcard:玩家index|效果卡id|数量 例: addcard:0|20011|1\n';
|
||||
str += '将某一队设为赢家: setwin:队伍index 例: setwin:0\n';
|
||||
client && client.send('notice_msg', str);
|
||||
this.room.send(client,'notice_msg', str);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,7 +60,7 @@ export class GMCommand extends Command<CardGameState, {client: Client, message:
|
||||
*/
|
||||
addRobot(msg:string) {
|
||||
let count = msg ? parseInt(msg) : 1;
|
||||
let count2 = this.room.maxClients - this.room.clients.length;
|
||||
let count2 = this.room.maxClients - this.room.clientCount();
|
||||
for (let i = 0; i< Math.min(count, count2); i++) {
|
||||
this.room.addRobot();
|
||||
}
|
||||
@ -84,7 +84,7 @@ export class GMCommand extends Command<CardGameState, {client: Client, message:
|
||||
card.effect = effectId;
|
||||
}
|
||||
let client = this.room.getClient(player.id);
|
||||
client && client.send('sync_card', {}, {afterNextPatch: true});
|
||||
this.room.send(client,'sync_card', {}, {afterNextPatch: true});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,7 +82,7 @@ export class GameResultCommand extends Command<CardGameState, {}> {
|
||||
await self.room.setPrivate(false);
|
||||
//开启匹配定时, 长时间没匹配到人的话, 添加机器人
|
||||
let timeOutWaitingPlayer = function () {
|
||||
let count = self.room.maxClients - self.room.clients.length;
|
||||
let count = self.room.maxClients - self.room.clientCount();
|
||||
if (count > 0) {
|
||||
for (let i = 0; i < count; i++) {
|
||||
self.room.addRobot();
|
||||
|
@ -17,11 +17,12 @@ export class OnJoinCommand extends Command<CardGameState, {
|
||||
// 实际的team会在PlayReadyCommand中设置
|
||||
let player = new Player(client.sessionId, 0, team);
|
||||
this.state.players.set(client.sessionId, player);
|
||||
this.room.addAssistClient(client.sessionId);
|
||||
let self = this;
|
||||
if (this.room.clients.length == 1) {
|
||||
if (this.room.clientCount() == 1) {
|
||||
// 正常的匹配逻辑进入的第一个玩家, 开启定时, 超过设定时间人没齐的话, 添加机器人
|
||||
let timeOutWaitingPlayer = function () {
|
||||
let count = self.room.maxClients - self.room.clients.length;
|
||||
let count = self.room.maxClients - self.room.clientCount();
|
||||
if (count > 0) {
|
||||
for (let i = 0; i < count; i++) {
|
||||
self.room.addRobot();
|
||||
@ -30,7 +31,7 @@ export class OnJoinCommand extends Command<CardGameState, {
|
||||
}
|
||||
let time = singleton(GameEnv).waitingPlayerTime * 1000;
|
||||
self.room.beginSchedule(time, timeOutWaitingPlayer, 'waiting_player');
|
||||
} else if (this.room.clients.length > 1 && this.room.clients.length < this.room.maxClients) {
|
||||
} else if (this.room.clientCount() > 1 && this.room.clientCount() < this.room.maxClients) {
|
||||
let moreTime = singleton(GameEnv).waitingPlayerOnePlus * 1000;
|
||||
self.room.addScheduleTime(moreTime, 'play_join', 'waiting_player')
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ export class PrepareCommand extends Command<CardGameState, {}> {
|
||||
this.state.updateGameState(GameStateConst.DETERMINE_TURN);
|
||||
let time = 3000;
|
||||
//TODO:: 每人发2张牌, 并比较大小, 确定先手
|
||||
for (let client of this.room.clients) {
|
||||
for (let client of this.state.players) {
|
||||
|
||||
// this.room.broadcast();
|
||||
}
|
||||
|
222
src/utils/assistant.util.ts
Normal file
222
src/utils/assistant.util.ts
Normal file
@ -0,0 +1,222 @@
|
||||
import {Card} from "../rooms/schema/Card";
|
||||
import arrUtil from "./array.util";
|
||||
import {EffectCardCfg} from "../cfg/parsers/EffectCardCfg";
|
||||
import {BaseConst} from "../constants/BaseConst";
|
||||
import {SkillTargetType} from "../rooms/logic/skill/SkillConst";
|
||||
import CfgMan from "../rooms/logic/CfgMan";
|
||||
import {CardGameState} from "../rooms/schema/CardGameState";
|
||||
import {Player} from "../rooms/schema/Player";
|
||||
import {HeroCfg} from "../cfg/parsers/HeroCfg";
|
||||
|
||||
let assistantUtil = {
|
||||
delay(max: number, min?: number) {
|
||||
min = min || 0;
|
||||
let milliseconds = (Math.random() * (max - min) + min) * 1000 | 0;
|
||||
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
||||
},
|
||||
/**
|
||||
* 检查是否可以吃牌
|
||||
* @param cardArr 待检查的卡组
|
||||
* @param card 目标牌
|
||||
*/
|
||||
checkTriple(cardArr: Card[], card?: Card): Card[] {
|
||||
if (card) cardArr.push(card);
|
||||
let pointMap: Map<number, Card[]> = new Map();
|
||||
let cardIdSet: Set<number> = new Set();
|
||||
for (let c of cardArr) {
|
||||
if (c.type !== 1) {
|
||||
continue;
|
||||
}
|
||||
if (pointMap.has(c.number)) {
|
||||
let arr = pointMap.get(c.number);
|
||||
arr.push(c);
|
||||
pointMap.set(c.number, arr);
|
||||
} else {
|
||||
pointMap.set(c.number, [c]);
|
||||
}
|
||||
cardIdSet.add(c.number);
|
||||
}
|
||||
let fetched = false;
|
||||
let result: Card[] = [];
|
||||
// 优先出对子
|
||||
for (let [point, arr] of pointMap) {
|
||||
if (card) {
|
||||
if (point == card.number && arr.length >= 3) {
|
||||
fetched = true;
|
||||
result = arr;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (arr.length >= 3) {
|
||||
fetched = true;
|
||||
result = arr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (fetched) {
|
||||
return result;
|
||||
}
|
||||
|
||||
let cardIds = [...cardIdSet];
|
||||
cardIds.sort((a, b) => a - b);
|
||||
let tmp = [];
|
||||
for (let i = 0, length = cardIds.length; i < length; i++) {
|
||||
let cur = cardIds[i];
|
||||
i == 0 && tmp.push(cur);
|
||||
if (i > 0) {
|
||||
if (cur != tmp[i - 1] + 1) {
|
||||
tmp.length = 0;
|
||||
}
|
||||
tmp.push(cur);
|
||||
}
|
||||
if (card) {
|
||||
if (tmp.indexOf(card.number) >= 0 && tmp.length >= 3) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (tmp.length >= 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp.length >= 3) {
|
||||
let subTmp = [];
|
||||
for (let i = tmp[0] - 1; i > 0; i--) {
|
||||
if (cardIdSet.has(i)) {
|
||||
subTmp.push(i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let i = tmp[tmp.length]; i < cardIdSet.size; i++) {
|
||||
if (cardIdSet.has(i)) {
|
||||
subTmp.push(i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
tmp = tmp.concat(subTmp);
|
||||
for (let point of tmp) {
|
||||
if (card && point === card.number) {
|
||||
result.push(card);
|
||||
} else {
|
||||
result.push(pointMap.get(point)[0]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return arrUtil.randomGet(cardArr, 1);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 随机获取敌对玩家
|
||||
* @private
|
||||
*/
|
||||
getEnemyPlayer(dstPlayer: Player, state: CardGameState): Player {
|
||||
let enemys = [];
|
||||
for (let [, player] of state.players) {
|
||||
if (player.team !== dstPlayer.team) {
|
||||
enemys.push(player);
|
||||
}
|
||||
}
|
||||
return arrUtil.randomOne(enemys);
|
||||
},
|
||||
|
||||
/**
|
||||
* 随机获取可用的随从
|
||||
* @param player
|
||||
* @private
|
||||
*/
|
||||
getRandomPet(player: Player): number {
|
||||
let pets = [];
|
||||
for (let [, pet] of player.pets) {
|
||||
if (pet.ap > 0 && pet.state == 1)
|
||||
pets.push(pet);
|
||||
}
|
||||
let result;
|
||||
if (pets.length > 0) {
|
||||
result = arrUtil.randomOne(pets);
|
||||
}
|
||||
return result ? result.pos : -1;
|
||||
},
|
||||
/**
|
||||
* 选择一个法术或者一个随从
|
||||
* @private
|
||||
*/
|
||||
async selectPet(dstPlayer: Player, state: CardGameState) {
|
||||
await this.delay(5, 0.2);
|
||||
let cards = [...state.cards.values()];
|
||||
let result;
|
||||
let effectMap: Map<number, EffectCardCfg> = global.$cfg.get(BaseConst.EFFECTCARD);
|
||||
for (let card of cards) {
|
||||
let effect = effectMap.get(card.effect);
|
||||
if (effect.type_id == 1) {
|
||||
result = card;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!result) {
|
||||
result = arrUtil.randomGet(cards, 1)[0];
|
||||
}
|
||||
let targetType: SkillTargetType = CfgMan.getTargetByCard(result.effect);
|
||||
let targetPlayer;
|
||||
let targetPos;
|
||||
switch (targetType) {
|
||||
case SkillTargetType.ENEMY_PLAYER:
|
||||
targetPlayer = this.getEnemyPlayer(dstPlayer, state);
|
||||
break;
|
||||
case SkillTargetType.ENEMY_PET:
|
||||
for (let [, player] of state.players) {
|
||||
if (player.team !== dstPlayer.team) {
|
||||
let pos = this.getRandomPet(player);
|
||||
if (pos > -1) {
|
||||
targetPlayer = player;
|
||||
targetPos = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SkillTargetType.FRIEND_PET:
|
||||
for (let [, player] of state.players) {
|
||||
if (player.team == dstPlayer.team) {
|
||||
let pos = this.getRandomPet(player);
|
||||
if (pos > -1) {
|
||||
targetPlayer = player;
|
||||
targetPos = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SkillTargetType.SELF_PET:
|
||||
let pos = this.getRandomPet(dstPlayer);
|
||||
if (pos > -1) {
|
||||
targetPlayer = dstPlayer;
|
||||
targetPos = pos;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
//TODO: 增加效果卡
|
||||
let effCards: number[] = [];
|
||||
return {
|
||||
card: result.id,
|
||||
player: targetPlayer?.id,
|
||||
pos: targetPos,
|
||||
effCards
|
||||
}
|
||||
|
||||
},
|
||||
randomHero() {
|
||||
let heroMap: Map<number, HeroCfg> = global.$cfg.get(BaseConst.HERO);
|
||||
let heroArr = [...heroMap.values()];
|
||||
let hero = arrUtil.randomGet(heroArr, 1);
|
||||
return {heroId: hero[0].id}
|
||||
}
|
||||
}
|
||||
|
||||
export default assistantUtil;
|
@ -255,7 +255,8 @@ let gameUtil = {
|
||||
result += pet.ap;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
export default gameUtil;
|
||||
|
Loading…
x
Reference in New Issue
Block a user