Merge branch 'second' of http://git.kingsome.cn/node/card_svr into second
This commit is contained in:
commit
82f0a7d79e
@ -7,6 +7,7 @@ import {SystemCardCfg} from "../cfg/parsers/SystemCardCfg";
|
|||||||
import {UnitCfg} from "../cfg/parsers/UnitCfg";
|
import {UnitCfg} from "../cfg/parsers/UnitCfg";
|
||||||
import {BaseConst} from "../constants/BaseConst";
|
import {BaseConst} from "../constants/BaseConst";
|
||||||
import SkillMan from "../rooms/logic/skill/SkillMan";
|
import SkillMan from "../rooms/logic/skill/SkillMan";
|
||||||
|
import {FormulaCfg} from "../cfg/parsers/FormulaCfg";
|
||||||
|
|
||||||
|
|
||||||
export function initData() {
|
export function initData() {
|
||||||
@ -17,6 +18,7 @@ export function initData() {
|
|||||||
rP(BaseConst.SKILL, SkillCfg);
|
rP(BaseConst.SKILL, SkillCfg);
|
||||||
rP(BaseConst.SYSTEMCARD, SystemCardCfg);
|
rP(BaseConst.SYSTEMCARD, SystemCardCfg);
|
||||||
rP(BaseConst.UNIT, UnitCfg);
|
rP(BaseConst.UNIT, UnitCfg);
|
||||||
|
rP(BaseConst.FORMULA, FormulaCfg);
|
||||||
DataParser.loadAll();
|
DataParser.loadAll();
|
||||||
|
|
||||||
let map = global.$cfg.get(BaseConst.SKILL);
|
let map = global.$cfg.get(BaseConst.SKILL);
|
||||||
|
@ -67,4 +67,5 @@ export class BaseConst {
|
|||||||
public static readonly SKILL = "skill";
|
public static readonly SKILL = "skill";
|
||||||
public static readonly SYSTEMCARD = "systemcard";
|
public static readonly SYSTEMCARD = "systemcard";
|
||||||
public static readonly UNIT = "unit";
|
public static readonly UNIT = "unit";
|
||||||
|
public static readonly FORMULA = "formula"
|
||||||
}
|
}
|
||||||
|
1
src/global.d.ts
vendored
1
src/global.d.ts
vendored
@ -32,6 +32,7 @@ declare module "colyseus" {
|
|||||||
mainClock: Delayed;
|
mainClock: Delayed;
|
||||||
robotCount: number;
|
robotCount: number;
|
||||||
match: boolean;
|
match: boolean;
|
||||||
|
score: number;
|
||||||
/**
|
/**
|
||||||
* 根据sessionId获取client
|
* 根据sessionId获取client
|
||||||
* @param player 玩家id或者玩家的对象
|
* @param player 玩家id或者玩家的对象
|
||||||
|
@ -25,6 +25,7 @@ import {createRobot} from "../common/WebApi";
|
|||||||
export class GeneralRoom extends Room {
|
export class GeneralRoom extends Room {
|
||||||
dispatcher = new Dispatcher(this);
|
dispatcher = new Dispatcher(this);
|
||||||
maxClients = 4;
|
maxClients = 4;
|
||||||
|
score = 0;
|
||||||
battleMan = new BattleHandler();
|
battleMan = new BattleHandler();
|
||||||
// 用于游戏过程中各种计时器, 使用该计时器的前提是, 只针对当前操作玩家
|
// 用于游戏过程中各种计时器, 使用该计时器的前提是, 只针对当前操作玩家
|
||||||
gameClock: Map<string, Delayed> = new Map();
|
gameClock: Map<string, Delayed> = new Map();
|
||||||
@ -50,6 +51,9 @@ export class GeneralRoom extends Room {
|
|||||||
if (options.match) {
|
if (options.match) {
|
||||||
this.match = options.match;
|
this.match = options.match;
|
||||||
}
|
}
|
||||||
|
if (options.score) {
|
||||||
|
this.score = options.score;
|
||||||
|
}
|
||||||
this.battleMan.init(cs, this);
|
this.battleMan.init(cs, this);
|
||||||
this.clock.start();
|
this.clock.start();
|
||||||
this.state.gameState = GameStateConst.STATE_WAIT_JOIN;
|
this.state.gameState = GameStateConst.STATE_WAIT_JOIN;
|
||||||
@ -113,7 +117,8 @@ export class GeneralRoom extends Room {
|
|||||||
let data = {
|
let data = {
|
||||||
client: client,
|
client: client,
|
||||||
accountId: options.accountid,
|
accountId: options.accountid,
|
||||||
seat: options.seat
|
seat: options.seat,
|
||||||
|
score: options.score,
|
||||||
};
|
};
|
||||||
this.dispatcher.dispatch(new OnJoinCommand(), data);
|
this.dispatcher.dispatch(new OnJoinCommand(), data);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import {Client, generateId, matchMaker, Room} from "colyseus";
|
import {Client, generateId, matchMaker, Room} from "colyseus";
|
||||||
|
import {BaseConst} from "../constants/BaseConst";
|
||||||
|
|
||||||
interface MatchmakingGroup {
|
interface MatchmakingGroup {
|
||||||
averageRank: number;
|
averageRank: number;
|
||||||
@ -109,6 +110,7 @@ export class RankedLobbyRoom extends Room {
|
|||||||
* 如果找到的记录, clients已经查过2条, 则也插入一条记录
|
* 如果找到的记录, clients已经查过2条, 则也插入一条记录
|
||||||
* 如果找到的记录, clients是1, 则把当前client添加到该记录中, 同时更新rank
|
* 如果找到的记录, clients是1, 则把当前client添加到该记录中, 同时更新rank
|
||||||
*/
|
*/
|
||||||
|
const fc = global.$cfg.get(BaseConst.FORMULA);
|
||||||
if (options.group) {
|
if (options.group) {
|
||||||
let length = this.stats.length;
|
let length = this.stats.length;
|
||||||
let groupData;
|
let groupData;
|
||||||
@ -142,7 +144,7 @@ export class RankedLobbyRoom extends Room {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
groupData.clients.set(client.sessionId, {client, options});
|
groupData.clients.set(client.sessionId, {client, options});
|
||||||
groupData.rank = (groupData.rank + options.rank) / 2
|
groupData.rank = (groupData.rank + options.rank) / 2 * (1 + fc.get(70027).number / 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
client.send("clients", groupData.clients.size);
|
client.send("clients", groupData.clients.size);
|
||||||
@ -299,11 +301,24 @@ export class RankedLobbyRoom extends Room {
|
|||||||
.map(async (group) => {
|
.map(async (group) => {
|
||||||
if (group.ready) {
|
if (group.ready) {
|
||||||
group.confirmed = 0;
|
group.confirmed = 0;
|
||||||
|
let score = 0;
|
||||||
|
let count = 0;
|
||||||
|
group.clients.map(client => {
|
||||||
|
for (let [,data] of client.clients) {
|
||||||
|
score += (data.options?.score || 0);
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let avaScore = score / count;
|
||||||
/**
|
/**
|
||||||
* Create room instance in the server.
|
* Create room instance in the server.
|
||||||
*/
|
*/
|
||||||
const room = await matchMaker.createRoom(this.roomToCreate, {rank: true, count: this.numClientsToMatch - group.count});
|
const room = await matchMaker.createRoom(this.roomToCreate, {
|
||||||
|
match: true,
|
||||||
|
rank: group.averageRank,
|
||||||
|
score: avaScore,
|
||||||
|
count: this.numClientsToMatch - group.count
|
||||||
|
});
|
||||||
// TODO: 预处理数据, 确定座次
|
// TODO: 预处理数据, 确定座次
|
||||||
let hasGroup = false;
|
let hasGroup = false;
|
||||||
for (let client of group.clients) {
|
for (let client of group.clients) {
|
||||||
|
@ -10,8 +10,28 @@ import {Card} from "../schema/Card";
|
|||||||
import {MapSchema, SetSchema} from "@colyseus/schema";
|
import {MapSchema, SetSchema} from "@colyseus/schema";
|
||||||
import {StateTypeEnum} from "../enums/StateTypeEnum";
|
import {StateTypeEnum} from "../enums/StateTypeEnum";
|
||||||
import {reportGameResult} from "../../common/WebApi";
|
import {reportGameResult} from "../../common/WebApi";
|
||||||
|
import {BaseConst} from "../../constants/BaseConst";
|
||||||
|
import {Player} from "../schema/Player";
|
||||||
|
|
||||||
|
class GameResult{
|
||||||
|
public id: string
|
||||||
|
public team: number
|
||||||
|
public hp: number
|
||||||
|
public alive: boolean
|
||||||
|
public ap: number
|
||||||
|
public mvpScore: number
|
||||||
|
public scoreChange: number
|
||||||
|
public scoreOld: number
|
||||||
|
|
||||||
|
constructor(player: Player) {
|
||||||
|
this.id = player.id;
|
||||||
|
this.team = player.team;
|
||||||
|
this.hp = player.hp;
|
||||||
|
this.alive = player.state != PlayerStateConst.PLAYER_DEAD;
|
||||||
|
this.ap = gameUtil.calcTotalAp(player);
|
||||||
|
this.scoreOld = player.score;
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 游戏结束
|
* 游戏结束
|
||||||
*/
|
*/
|
||||||
@ -19,67 +39,80 @@ export class GameResultCommand extends Command<CardGameState, {}> {
|
|||||||
|
|
||||||
async execute() {
|
async execute() {
|
||||||
// 计算最终结果
|
// 计算最终结果
|
||||||
let hp0 = 0;
|
let hp: number[] = [0, 0];
|
||||||
let hp1 = 0;
|
let ap: number[] = [0, 0];
|
||||||
let ap0 = 0;
|
let petAp: number[] = [0, 0];
|
||||||
let ap1 = 0;
|
let score: number[] = [0, 0];
|
||||||
let petAp0 = 0;
|
let results: Map<Player, GameResult> = new Map();
|
||||||
let petAp1 = 0;
|
const fc = global.$cfg.get(BaseConst.FORMULA);
|
||||||
let resultArr = [];
|
|
||||||
for (let [, player] of this.state.players) {
|
for (let [, player] of this.state.players) {
|
||||||
let data = {
|
let data = new GameResult(player);
|
||||||
id: player.id,
|
results.set(player, data);
|
||||||
team: player.team,
|
score[player.team] += player.score;
|
||||||
hp: player.hp,
|
hp[player.team] += player.hp;
|
||||||
alive: player.state != PlayerStateConst.PLAYER_DEAD,
|
if (player.state != PlayerStateConst.PLAYER_DEAD) {
|
||||||
ap: gameUtil.calcTotalAp(player)
|
ap[player.team] += data.ap;
|
||||||
};
|
for (let [,pet] of player.pets) {
|
||||||
resultArr.push(data);
|
petAp[player.team] += (pet.ap + pet.extAp);
|
||||||
if (player.team == 0) {
|
|
||||||
hp0 += player.hp;
|
|
||||||
if (player.state != PlayerStateConst.PLAYER_DEAD) {
|
|
||||||
ap0 += data.ap;
|
|
||||||
for (let [,pet] of player.pets) {
|
|
||||||
petAp0 += (pet.ap + pet.extAp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (player.team == 1) {
|
|
||||||
hp1 += player.hp;
|
|
||||||
if (player.state != PlayerStateConst.PLAYER_DEAD) {
|
|
||||||
ap1 += data.ap;
|
|
||||||
for (let [,pet] of player.pets) {
|
|
||||||
petAp1 += (pet.ap + pet.extAp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let winner = -1; // 平局
|
/**
|
||||||
if (hp0 > hp1) {
|
* 判断哪队是赢家
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
let winner = 0;
|
||||||
|
if (hp[0] > hp[1]) {
|
||||||
winner = 0;
|
winner = 0;
|
||||||
} else if (hp0 < hp1) {
|
} else if (hp[0] < hp[1]) {
|
||||||
winner = 1;
|
winner = 1;
|
||||||
} else {
|
} else {
|
||||||
if (ap0 > ap1) {
|
if (ap[0] > ap[1]) {
|
||||||
winner = 0;
|
winner = 0;
|
||||||
} else if (ap0 < ap1){
|
} else if (ap[0] < ap[1]){
|
||||||
winner = 1;
|
winner = 1;
|
||||||
} else {
|
} else {
|
||||||
if (petAp0 > petAp1) {
|
if (petAp[0] >= petAp[1]) {
|
||||||
winner = 0;
|
winner = 0;
|
||||||
} else if (petAp0 < petAp1) {
|
} else if (petAp[0] < petAp[1]) {
|
||||||
winner = 1;
|
winner = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let resultData: any = {
|
const scores = [
|
||||||
winner: winner,
|
fc.get(70043).number,
|
||||||
results: resultArr
|
fc.get(70046).number,
|
||||||
};
|
fc.get(70044).number,
|
||||||
|
fc.get(70045).number,
|
||||||
|
fc.get(70047).number,
|
||||||
|
fc.get(70048).number
|
||||||
|
];
|
||||||
let resultMap: Map<StateTypeEnum, [string, number]> = new Map();
|
let resultMap: Map<StateTypeEnum, [string, number]> = new Map();
|
||||||
|
let scoreMap: Map<Player, number> = new Map();
|
||||||
for (let [, player] of this.state.players) {
|
for (let [, player] of this.state.players) {
|
||||||
|
let otherTeam = 1 - player.team;
|
||||||
|
let result = results.get(player);
|
||||||
|
if (winner == player.team) {
|
||||||
|
if (score[player.team] >= score[otherTeam]) {
|
||||||
|
result.scoreChange = 100/(1+Math.pow(10, ((score[player.team]-score[otherTeam])/2500)));
|
||||||
|
} else {
|
||||||
|
result.scoreChange = 100-100/(1+Math.pow(10, ((score[otherTeam]-score[player.team])/2500)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (score[player.team] >= score[otherTeam]) {
|
||||||
|
result.scoreChange = -(80-80/(1+Math.pow(10, ((score[player.team]-score[otherTeam])/2500))));
|
||||||
|
} else {
|
||||||
|
result.scoreChange = -(80/(1+Math.pow(10, ((score[otherTeam]-score[player.team])/2500))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let s = 0;
|
||||||
for (let [type, val] of player.statData) {
|
for (let [type, val] of player.statData) {
|
||||||
|
if (type >= scores.length) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
val = val * scores[type];
|
||||||
|
s += val;
|
||||||
if (resultMap.has(type)) {
|
if (resultMap.has(type)) {
|
||||||
let current = resultMap.get(type);
|
let current = resultMap.get(type);
|
||||||
if (current[1] < val) {
|
if (current[1] < val) {
|
||||||
@ -89,16 +122,31 @@ export class GameResultCommand extends Command<CardGameState, {}> {
|
|||||||
resultMap.set(type, [player.id, val]);
|
resultMap.set(type, [player.id, val]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
scoreMap.set(player, s);
|
||||||
}
|
}
|
||||||
let statics: any = [];
|
let statics: any = [];
|
||||||
|
|
||||||
for (let [type, val] of resultMap) {
|
for (let [type, val] of resultMap) {
|
||||||
statics.push({
|
if (type < scores.length) {
|
||||||
type,
|
statics.push({
|
||||||
player: val[0],
|
type,
|
||||||
val: val[1]
|
player: val[0],
|
||||||
})
|
val: val[1]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
resultData['statics'] = statics;
|
for (let [p, val] of scoreMap) {
|
||||||
|
let mvpRate = p.team == winner ? fc.get(70051).number : fc.get(70052).number;
|
||||||
|
let data = results.get(p);
|
||||||
|
data.mvpScore = val * mvpRate; // mvp分
|
||||||
|
}
|
||||||
|
let resultData: any = {
|
||||||
|
winner: winner,
|
||||||
|
results: [...results.values()],
|
||||||
|
statics: statics
|
||||||
|
};
|
||||||
|
|
||||||
let self = this;
|
let self = this;
|
||||||
this.room.bGameResult(resultData);
|
this.room.bGameResult(resultData);
|
||||||
this.state.updateGameState(GameStateConst.STATE_GAME_OVER);
|
this.state.updateGameState(GameStateConst.STATE_GAME_OVER);
|
||||||
@ -179,6 +227,10 @@ export class GameResultCommand extends Command<CardGameState, {}> {
|
|||||||
pet.extSkills.length = 0;
|
pet.extSkills.length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向info-svr上报游戏结果
|
||||||
|
* @param {number} winner
|
||||||
|
*/
|
||||||
reportGameResult(winner: number) {
|
reportGameResult(winner: number) {
|
||||||
let data: any = {
|
let data: any = {
|
||||||
roomid: this.room.roomId,
|
roomid: this.room.roomId,
|
||||||
@ -201,6 +253,7 @@ export class GameResultCommand extends Command<CardGameState, {}> {
|
|||||||
team: player.team,
|
team: player.team,
|
||||||
heroid: player.heroId,
|
heroid: player.heroId,
|
||||||
statdata: dataObj,
|
statdata: dataObj,
|
||||||
|
score: player.score,
|
||||||
cards: cards
|
cards: cards
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import {Player} from "../schema/Player";
|
|||||||
import {Client} from "colyseus";
|
import {Client} from "colyseus";
|
||||||
import {GameStateConst} from "../../constants/GameStateConst";
|
import {GameStateConst} from "../../constants/GameStateConst";
|
||||||
import {GameEnv} from "../../cfg/GameEnv";
|
import {GameEnv} from "../../cfg/GameEnv";
|
||||||
|
import {BaseConst} from "../../constants/BaseConst";
|
||||||
|
import {getRandom} from "../../utils/number.util";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 玩家成功加入房间
|
* 玩家成功加入房间
|
||||||
@ -12,13 +14,16 @@ export class OnJoinCommand extends Command<CardGameState, {
|
|||||||
client: Client,
|
client: Client,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
seat?: number,
|
seat?: number,
|
||||||
|
score?: number
|
||||||
}> {
|
}> {
|
||||||
execute({client, accountId, seat} = this.payload) {
|
execute({client, accountId, seat, score} = this.payload) {
|
||||||
let count = this.state.players.size;
|
let count = this.state.players.size;
|
||||||
if (count >= this.room.maxClients) {
|
if (count >= this.room.maxClients) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let isRobot = false;
|
||||||
if (accountId && accountId == 'robot') {
|
if (accountId && accountId == 'robot') {
|
||||||
|
isRobot = true;
|
||||||
accountId = `robot_${client.sessionId}`;
|
accountId = `robot_${client.sessionId}`;
|
||||||
} else if (!accountId) {
|
} else if (!accountId) {
|
||||||
accountId = `player_${client.sessionId}`;
|
accountId = `player_${client.sessionId}`;
|
||||||
@ -32,6 +37,15 @@ export class OnJoinCommand extends Command<CardGameState, {
|
|||||||
}
|
}
|
||||||
let player = new Player(client.sessionId, idx, team);
|
let player = new Player(client.sessionId, idx, team);
|
||||||
player.accountId = accountId;
|
player.accountId = accountId;
|
||||||
|
if (isRobot) {
|
||||||
|
const fc = global.$cfg.get(BaseConst.FORMULA);
|
||||||
|
let low = fc.get(70034).number;
|
||||||
|
let high = fc.get(70035).number;
|
||||||
|
let random = getRandom(high, low) / 100 ;
|
||||||
|
player.score = this.room.score * random | 0;
|
||||||
|
} else {
|
||||||
|
player.score = score;
|
||||||
|
}
|
||||||
this.state.players.set(client.sessionId, player);
|
this.state.players.set(client.sessionId, player);
|
||||||
this.room.addAssistClient(client.sessionId);
|
this.room.addAssistClient(client.sessionId);
|
||||||
let self = this;
|
let self = this;
|
||||||
|
@ -18,6 +18,12 @@ export class Player extends Schema {
|
|||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
accountId: string;
|
accountId: string;
|
||||||
|
/**
|
||||||
|
* 用于显示的分
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
@type("number")
|
||||||
|
score: number;
|
||||||
/**
|
/**
|
||||||
* 用于组队匹配时候队伍的标记
|
* 用于组队匹配时候队伍的标记
|
||||||
* @type {string}
|
* @type {string}
|
||||||
|
10
src/utils/number.util.ts
Normal file
10
src/utils/number.util.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* 随机数
|
||||||
|
* @param {number} max
|
||||||
|
* @param {number} min
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
export function getRandom(max: number, min: number): number {
|
||||||
|
min = min || 0;
|
||||||
|
return Math.floor(Math.random()*(max-min)+min);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user