2077 lines
55 KiB
C++
2077 lines
55 KiB
C++
#include "StdAfx.h"
|
||
#include "TableFrameSink.h"
|
||
#include "cmath"
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
//静态变量
|
||
const WORD CTableFrameSink::m_wPlayerCount = GAME_PLAYER; //游戏人数
|
||
|
||
// 游戏定时器
|
||
enum tagServerTimerEnum
|
||
{
|
||
IDI_SEND_CARD = 1, //发牌计时器;
|
||
|
||
IDT_SEND_CARD = 5000, //发牌时间;
|
||
|
||
IDI_OUT_CARD = 2, //出牌计时器;
|
||
IDT_OUT_CARD = 2000, //出牌时间;
|
||
};
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
//构造函数
|
||
CTableFrameSink::CTableFrameSink()
|
||
{
|
||
//游戏变量
|
||
m_bNobodyCallScore = false;
|
||
m_wFirstUser = INVALID_CHAIR;
|
||
m_wBankerUser = INVALID_CHAIR;
|
||
m_wCurrentUser = INVALID_CHAIR;
|
||
m_etGameEndType = GAME_END_NULL;
|
||
ZeroMemory(m_bTrustee, sizeof(m_bTrustee));
|
||
|
||
//叫分信息;
|
||
ZeroMemory(m_cbScoreInfo, sizeof(m_cbScoreInfo));
|
||
|
||
//胜利信息
|
||
m_wWinCount = 0;
|
||
ZeroMemory(m_wWinOrder, sizeof(m_wWinOrder));
|
||
ZeroMemory(m_cbGongxian, sizeof(m_cbGongxian));
|
||
ZeroMemory(m_lBombScore, sizeof(m_lBombScore));
|
||
|
||
//出牌信息
|
||
m_wTurnWiner = INVALID_CHAIR;
|
||
ZeroMemory(&m_TurnOutCard, sizeof(m_TurnOutCard));
|
||
|
||
//扑克信息
|
||
ZeroMemory(m_cbHandCardData, sizeof(m_cbHandCardData));
|
||
ZeroMemory(m_cbHandCardCount, sizeof(m_cbHandCardCount));
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
m_wFriendChairID[i] = INVALID_CHAIR;
|
||
}
|
||
|
||
//组件变量
|
||
m_pITableFrame = NULL;
|
||
m_pGameServiceOption = NULL;
|
||
|
||
return;
|
||
}
|
||
|
||
//析构函数
|
||
CTableFrameSink::~CTableFrameSink()
|
||
{
|
||
}
|
||
|
||
//接口查询
|
||
VOID * CTableFrameSink::QueryInterface(REFGUID Guid, DWORD dwQueryVer)
|
||
{
|
||
QUERYINTERFACE(ITableFrameSink, Guid, dwQueryVer);
|
||
QUERYINTERFACE(ITableUserAction, Guid, dwQueryVer);
|
||
QUERYINTERFACE_IUNKNOWNEX(ITableFrameSink, Guid, dwQueryVer);
|
||
return NULL;
|
||
}
|
||
|
||
//初始化
|
||
bool CTableFrameSink::Initialization(IUnknownEx * pIUnknownEx)
|
||
{
|
||
//查询接口
|
||
ASSERT(pIUnknownEx != NULL);
|
||
m_pITableFrame = QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx, ITableFrame);
|
||
if (m_pITableFrame == NULL) return false;
|
||
|
||
//获取参数
|
||
m_pGameServiceOption = m_pITableFrame->GetGameServiceOption();
|
||
ASSERT(m_pGameServiceOption != NULL);
|
||
|
||
//开始模式
|
||
m_pITableFrame->SetStartMode(START_MODE_FULL_READY);
|
||
|
||
//BYTE cbCardData[MAX_COUNT] = {
|
||
// 0x4f, 0x22, 0x02, 0x31, 0x21, 0x01, 0x3d, 0x2d, 0x3c, 0x0c,
|
||
// 0x3b, 0x2b, 0x0b, 0x39, 0x29, 0x19, 0x38, 0x28, 0x07, 0x16,
|
||
// 0x06, 0x15, 0x05, 0x05, 0x33, 0x23, 0x03};
|
||
|
||
//GetBombScore(0, cbCardData, MAX_COUNT);
|
||
|
||
return true;
|
||
}
|
||
|
||
//复位桌子
|
||
VOID CTableFrameSink::RepositionSink()
|
||
{
|
||
|
||
//游戏变量
|
||
m_bNobodyCallScore = false;
|
||
m_wCurrentUser = INVALID_CHAIR;
|
||
m_wBankerUser = INVALID_CHAIR;
|
||
m_etGameEndType = GAME_END_NULL;
|
||
ZeroMemory(m_bTrustee, sizeof(m_bTrustee));
|
||
|
||
//叫分信息;
|
||
ZeroMemory(m_cbScoreInfo, sizeof(m_cbScoreInfo));
|
||
|
||
//胜利信息
|
||
m_wWinCount = 0;
|
||
ZeroMemory(m_wWinOrder, sizeof(m_wWinOrder));
|
||
ZeroMemory(m_cbGongxian, sizeof(m_cbGongxian));
|
||
ZeroMemory(m_lBombScore, sizeof(m_lBombScore));
|
||
|
||
//出牌信息
|
||
m_wTurnWiner = INVALID_CHAIR;
|
||
ZeroMemory(&m_TurnOutCard, sizeof(m_TurnOutCard));
|
||
|
||
//扑克信息
|
||
ZeroMemory(m_cbHandCardData, sizeof(m_cbHandCardData));
|
||
ZeroMemory(m_cbHandCardCount, sizeof(m_cbHandCardCount));
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
m_wFriendChairID[i] = INVALID_CHAIR;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
//游戏开始
|
||
bool CTableFrameSink::OnEventGameStart()
|
||
{
|
||
//混乱扑克
|
||
srand((unsigned)time(NULL));
|
||
|
||
//设置状态;
|
||
m_pITableFrame->SetGameStatus(GAME_SCENE_SEND);
|
||
|
||
BYTE cbRandCard[FULL_COUNT] = {0};
|
||
|
||
if (IsHasGameRule(eDZRuleEnum_NO_JOKER))
|
||
{
|
||
////设置状态;
|
||
//m_pITableFrame->SetGameStatus(GAME_SCENE_CALL_SCORE);
|
||
|
||
m_GameLogic.RandNoJokerCardList(cbRandCard, NO_JOKER_COUNT);
|
||
|
||
//用户扑克
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
m_cbHandCardCount[i] = MAX_NO_JOKER_COUNT;
|
||
CopyMemory(&m_cbHandCardData[i], &cbRandCard[i*m_cbHandCardCount[i]], sizeof(BYTE)*m_cbHandCardCount[i]);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
////设置状态;
|
||
//m_pITableFrame->SetGameStatus(GAME_SCENE_PLAY);
|
||
|
||
m_GameLogic.RandCardList(cbRandCard, FULL_COUNT);
|
||
|
||
//用户扑克
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
m_cbHandCardCount[i] = MAX_COUNT;
|
||
CopyMemory(&m_cbHandCardData[i], &cbRandCard[i*m_cbHandCardCount[i]], sizeof(BYTE)*m_cbHandCardCount[i]);
|
||
}
|
||
}
|
||
|
||
if (m_wFirstUser == INVALID_CHAIR) m_wFirstUser = 0;
|
||
|
||
m_wBankerUser = INVALID_CHAIR;
|
||
m_wTurnWiner = m_wFirstUser;
|
||
m_wCurrentUser = m_wFirstUser;
|
||
|
||
//构造变量
|
||
CMD_S_GameStart GameStart;
|
||
ZeroMemory(&GameStart, sizeof(GameStart));
|
||
|
||
//设置变量
|
||
GameStart.wCurrentUser = m_wCurrentUser;
|
||
GameStart.lCellScore = m_pGameServiceOption->lCellScore;
|
||
GameStart.bHasJoker = !IsHasGameRule(eDZRuleEnum_NO_JOKER);
|
||
CopyMemory(GameStart.cbCardCount, m_cbHandCardCount, sizeof(BYTE)*GAME_PLAYER);
|
||
|
||
//发送数据
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
//构造扑克
|
||
ASSERT(CountArray(GameStart.cbCardData) >= m_cbHandCardCount[i]);
|
||
CopyMemory(GameStart.cbCardData, m_cbHandCardData[i], sizeof(BYTE)*m_cbHandCardCount[i]);
|
||
GameStart.bTrustee[i] = m_bTrustee[i];
|
||
|
||
//发送数据
|
||
m_pITableFrame->SendTableData(i, SUB_S_GAME_START, &GameStart, sizeof(GameStart));
|
||
m_pITableFrame->SendLookonData(i, SUB_S_GAME_START, &GameStart, sizeof(GameStart));
|
||
}
|
||
|
||
// 录像开始;
|
||
starGameRecord();
|
||
|
||
// 记录开始消息;
|
||
CMD_Record_GameStart recordStart;
|
||
recordStart.wStartUser = m_wFirstUser;
|
||
recordStart.wCurrentUser = m_wCurrentUser;
|
||
addGameRecordAction(SUB_S_GAME_START, &recordStart, sizeof(CMD_Record_GameStart));
|
||
|
||
//排列扑克
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
m_GameLogic.SortCardList(m_cbHandCardData[i], m_cbHandCardCount[i], ST_ORDER);
|
||
}
|
||
|
||
//// 带王不打独;
|
||
//if (GameStart.bHasJoker)
|
||
//{
|
||
// m_pITableFrame->SetGameTimer(IDI_SEND_CARD, IDT_SEND_CARD, 1, 0);
|
||
//}
|
||
|
||
// 发牌结束;
|
||
m_pITableFrame->SetGameTimer(IDI_SEND_CARD, IDT_SEND_CARD, 1, 0);
|
||
|
||
return true;
|
||
}
|
||
|
||
//游戏结束
|
||
bool CTableFrameSink::OnEventGameConclude(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason)
|
||
{
|
||
switch (cbReason)
|
||
{
|
||
case GER_BAOZI: // 懒的重新定义,就用这个了;
|
||
{
|
||
//定义变量
|
||
CMD_S_GameEnd GameEnd;
|
||
ZeroMemory(&GameEnd, sizeof(GameEnd));
|
||
GameEnd.iGameEndType = m_etGameEndType;
|
||
|
||
//用户扑克
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
GameEnd.wWinOrder[i] = INVALID_CHAIR;
|
||
GameEnd.wFriendChairID[i] = m_wFriendChairID[i];
|
||
GameEnd.cbCardCount[i] = m_cbHandCardCount[i];
|
||
CopyMemory(GameEnd.cbCardData[i], m_cbHandCardData[i], m_cbHandCardCount[i] * sizeof(BYTE));
|
||
|
||
// 计算头子分;
|
||
if (m_cbHandCardCount[i] > 0)
|
||
{
|
||
GetBombScore(i, m_cbHandCardData[i], m_cbHandCardCount[i]);
|
||
}
|
||
}
|
||
|
||
//积分变量
|
||
tagScoreInfo ScoreInfoArray[GAME_PLAYER];
|
||
ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray));
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
GameEnd.lGameScore[i] = 0; // 游戏得分;
|
||
GameEnd.lBombScore[i] = m_lBombScore[i]; // 炸弹得分;
|
||
GameEnd.lAllScore[i] = m_lBombScore[i] + GameEnd.lGameScore[i]; // 总得分;
|
||
|
||
ScoreInfoArray[i].lScore = GameEnd.lAllScore[i];
|
||
|
||
if (ScoreInfoArray[i].lScore > 0)
|
||
{
|
||
ScoreInfoArray[i].cbType = SCORE_TYPE_WIN;
|
||
}
|
||
else if (ScoreInfoArray[i].lScore < 0)
|
||
{
|
||
ScoreInfoArray[i].cbType = SCORE_TYPE_LOSE;
|
||
}
|
||
else
|
||
{
|
||
ScoreInfoArray[i].cbType = SCORE_TYPE_DRAW;
|
||
}
|
||
}
|
||
|
||
/********************************私人场统计****************************************/
|
||
tagPrivateFrameRecordInfo* pPrivateRecord = m_pITableFrame->GetPrivateFrameRecord();
|
||
BYTE cbFinishCout = pPrivateRecord->cbFinishCout;
|
||
|
||
//统计积分明细
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (cbFinishCout < 16)
|
||
{
|
||
m_PrivateEndInfo.lDetails[i][cbFinishCout] = GameEnd.lAllScore[i];
|
||
}
|
||
}
|
||
|
||
// 完成局数
|
||
m_PrivateEndInfo.cbFinishCout = cbFinishCout + 1;
|
||
|
||
m_pITableFrame->addPrivatePlayCout(1);
|
||
/********************************私人场统计****************************************/
|
||
|
||
//牌局结束后,每8局增加一点经验值;
|
||
if (IsPrivateEnd())
|
||
{
|
||
tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
|
||
SCORE lGrade = pPrivateFrame->dwPlayCost;
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
ScoreInfoArray[i].lGrade = lGrade;
|
||
}
|
||
|
||
GameEnd.isPrivateEnd = true;
|
||
}
|
||
|
||
//发送信息
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
|
||
// 记录游戏结束消息;
|
||
addGameRecordAction(SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
|
||
//写入积分;
|
||
DataStream kDataStream;
|
||
m_kGameRecord.StreamValue(kDataStream, true);
|
||
m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray), kDataStream);
|
||
|
||
//结束游戏
|
||
m_pITableFrame->ConcludeGame(GAME_SCENE_FREE);
|
||
|
||
return true;
|
||
}
|
||
case GER_DISMISS: //游戏解散
|
||
{
|
||
//构造数据
|
||
CMD_S_GameEnd GameEnd;
|
||
memset(&GameEnd, 0, sizeof(GameEnd));
|
||
GameEnd.iGameEndType = GAME_END_DRAW;
|
||
|
||
//用户扑克
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
GameEnd.wFriendChairID[i] = m_wFriendChairID[i];
|
||
GameEnd.cbCardCount[i] = m_cbHandCardCount[i];
|
||
CopyMemory(GameEnd.cbCardData[i], m_cbHandCardData[i], m_cbHandCardCount[i] * sizeof(BYTE));
|
||
|
||
// 计算头子分;
|
||
if (m_cbHandCardCount[i] > 0)
|
||
{
|
||
GetBombScore(i, m_cbHandCardData[i], m_cbHandCardCount[i]);
|
||
}
|
||
}
|
||
|
||
//积分变量
|
||
tagScoreInfo ScoreInfoArray[GAME_PLAYER];
|
||
ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray));
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
GameEnd.lGameScore[i] = 0; // 游戏得分;
|
||
GameEnd.lBombScore[i] = m_lBombScore[i]; // 炸弹得分;
|
||
GameEnd.lAllScore[i] = m_lBombScore[i] + GameEnd.lGameScore[i]; // 总得分;
|
||
|
||
ScoreInfoArray[i].lScore = GameEnd.lAllScore[i];
|
||
|
||
if (ScoreInfoArray[i].lScore > 0)
|
||
{
|
||
ScoreInfoArray[i].cbType = SCORE_TYPE_WIN;
|
||
}
|
||
else if (ScoreInfoArray[i].lScore < 0)
|
||
{
|
||
ScoreInfoArray[i].cbType = SCORE_TYPE_LOSE;
|
||
}
|
||
else
|
||
{
|
||
ScoreInfoArray[i].cbType = SCORE_TYPE_DRAW;
|
||
}
|
||
}
|
||
|
||
/********************************私人场统计****************************************/
|
||
tagPrivateFrameRecordInfo* pPrivateRecord = m_pITableFrame->GetPrivateFrameRecord();
|
||
BYTE cbFinishCout = pPrivateRecord->cbFinishCout;
|
||
|
||
//统计积分明细
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (cbFinishCout < 16)
|
||
{
|
||
m_PrivateEndInfo.lDetails[i][cbFinishCout] = GameEnd.lAllScore[i];
|
||
}
|
||
}
|
||
|
||
// 完成局数
|
||
m_PrivateEndInfo.cbFinishCout = cbFinishCout + 1;
|
||
|
||
m_pITableFrame->addPrivatePlayCout(1);
|
||
/********************************私人场统计****************************************/
|
||
|
||
// 私人场游戏结束预判断;
|
||
if (IsRecordServerType() && IsPrivateEnd())
|
||
{
|
||
GameEnd.isPrivateEnd = true;
|
||
}
|
||
|
||
//发送信息
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
|
||
// 记录游戏结束消息;
|
||
addGameRecordAction(SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
|
||
//写入积分;
|
||
DataStream kDataStream;
|
||
m_kGameRecord.StreamValue(kDataStream, true);
|
||
m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray), kDataStream);
|
||
|
||
//结束游戏
|
||
m_pITableFrame->ConcludeGame(GAME_SCENE_FREE);
|
||
|
||
return true;
|
||
}
|
||
case GER_NORMAL:
|
||
{
|
||
// 只打二游;
|
||
if (IsHasGameRule(eDZRuleEnum_TO_TWO))
|
||
{
|
||
return ToTwoGameConclude(wChairID, pIServerUserItem);
|
||
}
|
||
else
|
||
{
|
||
return NormalGameConclude(wChairID, pIServerUserItem);
|
||
}
|
||
}
|
||
case GER_USER_LEAVE: //用户强退
|
||
case GER_NETWORK_ERROR: //网络中断
|
||
{
|
||
//定义变量
|
||
CMD_S_GameEnd GameEnd;
|
||
memset(&GameEnd, 0, sizeof(GameEnd));
|
||
|
||
//用户扑克
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
GameEnd.wFriendChairID[i] = m_wFriendChairID[i];
|
||
GameEnd.cbCardCount[i] = m_cbHandCardCount[i];
|
||
CopyMemory(GameEnd.cbCardData[i], m_cbHandCardData[i], m_cbHandCardCount[i] * sizeof(BYTE));
|
||
}
|
||
|
||
//发送信息
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
|
||
//积分变量
|
||
tagScoreInfo ScoreInfoArray[GAME_PLAYER];
|
||
ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray));
|
||
|
||
//逃跑罚分
|
||
ScoreInfoArray[wChairID].lScore = GameEnd.lGameScore[wChairID];
|
||
ScoreInfoArray[wChairID].cbType = SCORE_TYPE_FLEE;
|
||
|
||
// 记录游戏结束消息;
|
||
addGameRecordAction(SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
|
||
//写入积分;
|
||
DataStream kDataStream;
|
||
m_kGameRecord.StreamValue(kDataStream, true);
|
||
m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray), kDataStream);
|
||
|
||
//结束游戏
|
||
m_pITableFrame->ConcludeGame(GAME_SCENE_FREE);
|
||
|
||
//切换庄家
|
||
m_wBankerUser = (m_wBankerUser + 1) % GAME_PLAYER;
|
||
|
||
return true;
|
||
}
|
||
}
|
||
|
||
ASSERT(FALSE);
|
||
|
||
return false;
|
||
}
|
||
|
||
// 正常结束;
|
||
bool CTableFrameSink::NormalGameConclude(WORD wChairID, IServerUserItem * pIServerUserItem)
|
||
{
|
||
//定义变量
|
||
CMD_S_GameEnd GameEnd;
|
||
ZeroMemory(&GameEnd, sizeof(GameEnd));
|
||
|
||
tagScoreInfo ScoreInfo[GAME_PLAYER];
|
||
ZeroMemory(&ScoreInfo, sizeof(ScoreInfo));
|
||
|
||
//胜利信息
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (m_cbHandCardCount[i] != 0)
|
||
{
|
||
m_wWinOrder[m_wWinCount++] = i;
|
||
}
|
||
}
|
||
|
||
// 排名;
|
||
CopyMemory(GameEnd.wWinOrder, m_wWinOrder, sizeof(m_wWinOrder));
|
||
|
||
//剩余扑克
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
GameEnd.wFriendChairID[i] = m_wFriendChairID[i];
|
||
GameEnd.cbCardCount[i] = m_cbHandCardCount[i];
|
||
CopyMemory(GameEnd.cbCardData[i], m_cbHandCardData[i], m_cbHandCardCount[i] * sizeof(BYTE));
|
||
}
|
||
|
||
// 有玩家打独;
|
||
if (!m_bNobodyCallScore)
|
||
{
|
||
// 赢积分;
|
||
SCORE lWinCellScore = 2 * m_pGameServiceOption->lCellScore;
|
||
|
||
// 庄家赢;
|
||
if (wChairID == m_wBankerUser)
|
||
{
|
||
ScoreInfo[m_wBankerUser].lScore = 3 * lWinCellScore;
|
||
ScoreInfo[m_wBankerUser].cbType = SCORE_TYPE_WIN;
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (i == m_wBankerUser) continue;
|
||
|
||
ScoreInfo[i].lScore = 0 - lWinCellScore;
|
||
ScoreInfo[i].cbType = SCORE_TYPE_WIN;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ScoreInfo[m_wBankerUser].lScore = 0 - 3 * lWinCellScore;
|
||
ScoreInfo[m_wBankerUser].cbType = SCORE_TYPE_WIN;
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (i == m_wBankerUser) continue;
|
||
|
||
ScoreInfo[i].lScore = lWinCellScore;
|
||
ScoreInfo[i].cbType = SCORE_TYPE_WIN;
|
||
}
|
||
}
|
||
|
||
//切换庄家
|
||
m_wFirstUser = m_wBankerUser;
|
||
GameEnd.iGameEndType = GAME_END_DRAW;
|
||
|
||
// 计算头子分;
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (m_cbHandCardCount[i] <= 0) continue;
|
||
|
||
GetBombScore(i, m_cbHandCardData[i], m_cbHandCardCount[i]);
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
// 带王积分翻倍;
|
||
BYTE cbHasJoker = IsHasGameRule(eDZRuleEnum_NO_JOKER) ? 1 : 2;
|
||
|
||
//单扣判断(第一名和第三名是伙伴)
|
||
//if (m_wWinOrder[0] == (m_wWinOrder[2] + 2) % GAME_PLAYER)
|
||
if (m_wWinOrder[0] == m_wFriendChairID[m_wWinOrder[2]])
|
||
{
|
||
GameEnd.iGameEndType = GAME_END_ONE_WIN;
|
||
|
||
//游戏积分
|
||
ScoreInfo[m_wWinOrder[0]].lScore = 1 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[0]].cbType = SCORE_TYPE_WIN;
|
||
ScoreInfo[m_wWinOrder[2]].lScore = 1 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[2]].cbType = SCORE_TYPE_WIN;
|
||
ScoreInfo[m_wWinOrder[1]].lScore = -1 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[1]].cbType = SCORE_TYPE_LOSE;
|
||
ScoreInfo[m_wWinOrder[3]].lScore = -1 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[3]].cbType = SCORE_TYPE_LOSE;
|
||
|
||
//切换庄家
|
||
m_wFirstUser = m_wWinOrder[0];
|
||
|
||
}
|
||
//双扣判断(第一名和第二名是伙伴)
|
||
//else if (m_wWinOrder[0] == (m_wWinOrder[1] + 2) % GAME_PLAYER)
|
||
else if (m_wWinOrder[0] == m_wFriendChairID[m_wWinOrder[1]])
|
||
{
|
||
GameEnd.iGameEndType = GAME_END_TWO_WIN;
|
||
|
||
//游戏积分
|
||
ScoreInfo[m_wWinOrder[0]].lScore = 2 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[0]].cbType = SCORE_TYPE_WIN;
|
||
ScoreInfo[m_wWinOrder[1]].lScore = 2 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[1]].cbType = SCORE_TYPE_WIN;
|
||
ScoreInfo[m_wWinOrder[2]].lScore = -2 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[2]].cbType = SCORE_TYPE_LOSE;
|
||
ScoreInfo[m_wWinOrder[3]].lScore = -2 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[3]].cbType = SCORE_TYPE_LOSE;
|
||
|
||
////切换庄家
|
||
//m_wFirstUser = m_wWinOrder[0];
|
||
}
|
||
else //平扣判断
|
||
{
|
||
GameEnd.iGameEndType = GAME_END_DRAW;
|
||
|
||
//游戏积分
|
||
ScoreInfo[m_wWinOrder[0]].lScore = 0;
|
||
ScoreInfo[m_wWinOrder[0]].cbType = SCORE_TYPE_DRAW;
|
||
ScoreInfo[m_wWinOrder[2]].lScore = 0;
|
||
ScoreInfo[m_wWinOrder[2]].cbType = SCORE_TYPE_DRAW;
|
||
ScoreInfo[m_wWinOrder[1]].lScore = 0;
|
||
ScoreInfo[m_wWinOrder[1]].cbType = SCORE_TYPE_DRAW;
|
||
ScoreInfo[m_wWinOrder[3]].lScore = 0;
|
||
ScoreInfo[m_wWinOrder[3]].cbType = SCORE_TYPE_DRAW;
|
||
|
||
////切换庄家
|
||
//m_wFirstUser = (m_wFirstUser + 1) % 4;
|
||
}
|
||
|
||
//切换庄家
|
||
m_wFirstUser = m_wWinOrder[0];
|
||
}
|
||
|
||
//游戏积分
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
GameEnd.lGameScore[i] = ScoreInfo[i].lScore; // 游戏得分;
|
||
GameEnd.lBombScore[i] = m_lBombScore[i]; // 炸弹得分;
|
||
GameEnd.lAllScore[i] = GameEnd.lGameScore[i] + m_lBombScore[i]; // 总得分;
|
||
|
||
ScoreInfo[i].lScore = GameEnd.lAllScore[i];
|
||
}
|
||
|
||
/********************************私人场统计****************************************/
|
||
tagPrivateFrameRecordInfo* pPrivateRecord = m_pITableFrame->GetPrivateFrameRecord();
|
||
BYTE cbFinishCout = pPrivateRecord->cbFinishCout;
|
||
|
||
//统计积分明细
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (cbFinishCout < 16)
|
||
{
|
||
m_PrivateEndInfo.lDetails[i][cbFinishCout] = GameEnd.lAllScore[i];
|
||
}
|
||
}
|
||
|
||
// 完成局数
|
||
m_PrivateEndInfo.cbFinishCout = cbFinishCout + 1;
|
||
|
||
m_pITableFrame->addPrivatePlayCout(1);
|
||
/********************************私人场统计****************************************/
|
||
|
||
//牌局结束后,每8局增加一点经验值;
|
||
if (IsPrivateEnd())
|
||
{
|
||
tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
|
||
SCORE lGrade = pPrivateFrame->dwPlayCost;
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
ScoreInfo[i].lGrade = lGrade;
|
||
}
|
||
|
||
GameEnd.isPrivateEnd = true;
|
||
}
|
||
|
||
//发送信息
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
|
||
// 记录游戏结束消息;
|
||
addGameRecordAction(SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
|
||
//写入积分;
|
||
DataStream kDataStream;
|
||
m_kGameRecord.StreamValue(kDataStream, true);
|
||
m_pITableFrame->WriteTableScore(ScoreInfo, CountArray(ScoreInfo), kDataStream);
|
||
|
||
//结束游戏
|
||
m_pITableFrame->ConcludeGame(GAME_SCENE_FREE);
|
||
|
||
return true;
|
||
}
|
||
|
||
// 只打二游;
|
||
bool CTableFrameSink::ToTwoGameConclude(WORD wChairID, IServerUserItem * pIServerUserItem)
|
||
{
|
||
//定义变量
|
||
CMD_S_GameEnd GameEnd;
|
||
ZeroMemory(&GameEnd, sizeof(GameEnd));
|
||
|
||
tagScoreInfo ScoreInfo[GAME_PLAYER];
|
||
ZeroMemory(&ScoreInfo, sizeof(ScoreInfo));
|
||
|
||
//// 排名信息;
|
||
//for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
//{
|
||
// if (m_cbHandCardCount[i] != 0)
|
||
// {
|
||
// m_wWinOrder[m_wWinCount++] = i;
|
||
// }
|
||
//}
|
||
//CopyMemory(GameEnd.wWinOrder, m_wWinOrder, sizeof(m_wWinOrder));
|
||
|
||
//剩余扑克
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
GameEnd.wFriendChairID[i] = m_wFriendChairID[i];
|
||
GameEnd.cbCardCount[i] = m_cbHandCardCount[i];
|
||
CopyMemory(GameEnd.cbCardData[i], m_cbHandCardData[i], m_cbHandCardCount[i] * sizeof(BYTE));
|
||
}
|
||
|
||
// 有玩家打独;
|
||
if (!m_bNobodyCallScore)
|
||
{
|
||
// 排名信息;
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (m_cbHandCardCount[i] != 0)
|
||
{
|
||
m_wWinOrder[m_wWinCount++] = i;
|
||
}
|
||
}
|
||
CopyMemory(GameEnd.wWinOrder, m_wWinOrder, sizeof(m_wWinOrder));
|
||
|
||
// 赢积分;
|
||
SCORE lWinCellScore = 2 * m_pGameServiceOption->lCellScore;
|
||
|
||
// 庄家赢;
|
||
if (wChairID == m_wBankerUser)
|
||
{
|
||
ScoreInfo[m_wBankerUser].lScore = 3 * lWinCellScore;
|
||
ScoreInfo[m_wBankerUser].cbType = SCORE_TYPE_WIN;
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (i == m_wBankerUser) continue;
|
||
|
||
ScoreInfo[i].lScore = 0 - lWinCellScore;
|
||
ScoreInfo[i].cbType = SCORE_TYPE_WIN;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ScoreInfo[m_wBankerUser].lScore = 0 - 3 * lWinCellScore;
|
||
ScoreInfo[m_wBankerUser].cbType = SCORE_TYPE_WIN;
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (i == m_wBankerUser) continue;
|
||
|
||
ScoreInfo[i].lScore = lWinCellScore;
|
||
ScoreInfo[i].cbType = SCORE_TYPE_WIN;
|
||
}
|
||
}
|
||
|
||
//切换庄家
|
||
m_wFirstUser = m_wBankerUser;
|
||
GameEnd.iGameEndType = GAME_END_DRAW;
|
||
|
||
// 计算头子分;
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (m_cbHandCardCount[i] <= 0) continue;
|
||
|
||
GetBombScore(i, m_cbHandCardData[i], m_cbHandCardCount[i]);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 带王积分翻倍;
|
||
BYTE cbHasJoker = IsHasGameRule(eDZRuleEnum_NO_JOKER) ? 1 : 2;
|
||
|
||
//双扣判断(第一名和第二名是伙伴);
|
||
if (m_wWinOrder[0] == m_wFriendChairID[m_wWinOrder[1]])
|
||
{
|
||
GameEnd.iGameEndType = GAME_END_TWO_WIN;
|
||
|
||
// 排名信息;
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (m_cbHandCardCount[i] != 0)
|
||
{
|
||
m_wWinOrder[m_wWinCount++] = i;
|
||
}
|
||
}
|
||
CopyMemory(GameEnd.wWinOrder, m_wWinOrder, sizeof(m_wWinOrder));
|
||
|
||
//游戏积分
|
||
ScoreInfo[m_wWinOrder[0]].lScore = 2 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[0]].cbType = SCORE_TYPE_WIN;
|
||
ScoreInfo[m_wWinOrder[1]].lScore = 2 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[1]].cbType = SCORE_TYPE_WIN;
|
||
ScoreInfo[m_wWinOrder[2]].lScore = -2 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[2]].cbType = SCORE_TYPE_LOSE;
|
||
ScoreInfo[m_wWinOrder[3]].lScore = -2 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[3]].cbType = SCORE_TYPE_LOSE;
|
||
}
|
||
//单扣判断(第一名和第二名不是伙伴);
|
||
else
|
||
{
|
||
GameEnd.iGameEndType = GAME_END_ONE_WIN;
|
||
|
||
//单扣第一名伙伴是第三名;
|
||
m_wWinOrder[m_wWinCount++] = m_wFriendChairID[m_wWinOrder[0]];
|
||
|
||
//单扣第二名伙伴是第四名;
|
||
m_wWinOrder[m_wWinCount++] = m_wFriendChairID[m_wWinOrder[1]];
|
||
|
||
CopyMemory(GameEnd.wWinOrder, m_wWinOrder, sizeof(m_wWinOrder));
|
||
|
||
//游戏积分
|
||
ScoreInfo[m_wWinOrder[0]].lScore = 1 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[0]].cbType = SCORE_TYPE_WIN;
|
||
ScoreInfo[m_wWinOrder[2]].lScore = 1 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[2]].cbType = SCORE_TYPE_WIN;
|
||
ScoreInfo[m_wWinOrder[1]].lScore = -1 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[1]].cbType = SCORE_TYPE_LOSE;
|
||
ScoreInfo[m_wWinOrder[3]].lScore = -1 * m_pGameServiceOption->lCellScore*cbHasJoker;
|
||
ScoreInfo[m_wWinOrder[3]].cbType = SCORE_TYPE_LOSE;
|
||
}
|
||
|
||
//切换庄家
|
||
m_wFirstUser = m_wWinOrder[0];
|
||
}
|
||
|
||
//游戏积分
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
GameEnd.lGameScore[i] = ScoreInfo[i].lScore; // 游戏得分;
|
||
GameEnd.lBombScore[i] = m_lBombScore[i]; // 炸弹得分;
|
||
GameEnd.lAllScore[i] = GameEnd.lGameScore[i] + m_lBombScore[i]; // 总得分;
|
||
|
||
ScoreInfo[i].lScore = GameEnd.lAllScore[i];
|
||
}
|
||
|
||
/********************************私人场统计****************************************/
|
||
tagPrivateFrameRecordInfo* pPrivateRecord = m_pITableFrame->GetPrivateFrameRecord();
|
||
BYTE cbFinishCout = pPrivateRecord->cbFinishCout;
|
||
|
||
//统计积分明细
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (cbFinishCout < 16)
|
||
{
|
||
m_PrivateEndInfo.lDetails[i][cbFinishCout] = GameEnd.lAllScore[i];
|
||
}
|
||
}
|
||
|
||
// 完成局数
|
||
m_PrivateEndInfo.cbFinishCout = cbFinishCout + 1;
|
||
|
||
m_pITableFrame->addPrivatePlayCout(1);
|
||
/********************************私人场统计****************************************/
|
||
|
||
//牌局结束后,每8局增加一点经验值;
|
||
if (IsPrivateEnd())
|
||
{
|
||
tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
|
||
SCORE lGrade = pPrivateFrame->dwPlayCost;
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
ScoreInfo[i].lGrade = lGrade;
|
||
}
|
||
|
||
GameEnd.isPrivateEnd = true;
|
||
}
|
||
|
||
//发送信息
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
|
||
// 记录游戏结束消息;
|
||
addGameRecordAction(SUB_S_GAME_END, &GameEnd, sizeof(GameEnd));
|
||
|
||
//写入积分;
|
||
DataStream kDataStream;
|
||
m_kGameRecord.StreamValue(kDataStream, true);
|
||
m_pITableFrame->WriteTableScore(ScoreInfo, CountArray(ScoreInfo), kDataStream);
|
||
|
||
//结束游戏
|
||
m_pITableFrame->ConcludeGame(GAME_SCENE_FREE);
|
||
|
||
return true;
|
||
}
|
||
|
||
//发送场景
|
||
bool CTableFrameSink::OnEventSendGameScene(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbGameStatus, bool bSendSecret)
|
||
{
|
||
switch (cbGameStatus)
|
||
{
|
||
case GAME_SCENE_FREE: //空闲状态
|
||
{
|
||
//构造数据
|
||
CMD_S_StatusFree StatusFree;
|
||
memset(&StatusFree, 0, sizeof(StatusFree));
|
||
|
||
//游戏变量
|
||
StatusFree.wBankerUser = m_wBankerUser;
|
||
StatusFree.lCellScore = m_pGameServiceOption->lCellScore;
|
||
|
||
//发送场景
|
||
return m_pITableFrame->SendGameScene(pIServerUserItem, &StatusFree, sizeof(StatusFree));
|
||
}
|
||
case GAME_SCENE_SEND:
|
||
{
|
||
//构造数据;
|
||
CMD_S_StatusSendCard StatusSend;
|
||
ZeroMemory(&StatusSend, sizeof(StatusSend));
|
||
|
||
//单元积分;
|
||
StatusSend.lCellScore = m_pITableFrame->GetCellScore();
|
||
|
||
//游戏信息;
|
||
StatusSend.wCurrentUser = m_wCurrentUser;
|
||
CopyMemory(StatusSend.cbHandCardCount, m_cbHandCardCount, sizeof(m_cbHandCardCount));
|
||
CopyMemory(StatusSend.cbHandCardData, m_cbHandCardData[wChairID], m_cbHandCardCount[wChairID] * sizeof(BYTE));
|
||
|
||
return m_pITableFrame->SendGameScene(pIServerUserItem, &StatusSend, sizeof(StatusSend));
|
||
}
|
||
case GAME_SCENE_CALL_SCORE:
|
||
{
|
||
//构造数据;
|
||
CMD_S_StatusCallScore StatusCall;
|
||
ZeroMemory(&StatusCall, sizeof(StatusCall));
|
||
|
||
//单元积分;
|
||
StatusCall.lCellScore = m_pITableFrame->GetCellScore();
|
||
|
||
//游戏信息;
|
||
StatusCall.wCurrentUser = m_wCurrentUser;
|
||
CopyMemory(StatusCall.cbScoreInfo, m_cbScoreInfo, sizeof(m_cbScoreInfo));
|
||
CopyMemory(StatusCall.cbHandCardCount, m_cbHandCardCount, sizeof(m_cbHandCardCount));
|
||
CopyMemory(StatusCall.cbHandCardData, m_cbHandCardData[wChairID], m_cbHandCardCount[wChairID] * sizeof(BYTE));
|
||
|
||
return m_pITableFrame->SendGameScene(pIServerUserItem, &StatusCall, sizeof(StatusCall));
|
||
}
|
||
case GAME_SCENE_PLAY: //游戏状态
|
||
{
|
||
//构造数据
|
||
CMD_S_StatusPlay StatusPlay;
|
||
memset(&StatusPlay, 0, sizeof(StatusPlay));
|
||
|
||
//游戏变量
|
||
StatusPlay.wCurrentUser = m_wCurrentUser;
|
||
StatusPlay.lCellScore = m_pGameServiceOption->lCellScore;
|
||
//StatusPlay.wFriendChairID = m_wFriendChairID[wChairID];
|
||
StatusPlay.wBankerUser = m_wBankerUser;
|
||
StatusPlay.bCallCard = m_bNobodyCallScore;
|
||
|
||
if (IsHasGameRule(eDZRuleEnum_MINGBIAN))
|
||
{
|
||
StatusPlay.wFriendChairID = m_wFriendChairID[wChairID];
|
||
}
|
||
else
|
||
{
|
||
StatusPlay.wFriendChairID = INVALID_CHAIR;
|
||
}
|
||
|
||
//胜利信息
|
||
StatusPlay.wWinCount = m_wWinCount;
|
||
CopyMemory(StatusPlay.wWinOrder, m_wWinOrder, sizeof(StatusPlay.wWinOrder));
|
||
CopyMemory(StatusPlay.bTrustee, m_bTrustee, sizeof(m_bTrustee));
|
||
|
||
//出牌信息
|
||
StatusPlay.wTurnWiner = m_wTurnWiner;
|
||
StatusPlay.cbTurnCardType = m_TurnOutCard.cbCardType;
|
||
StatusPlay.cbTurnCardCount = m_TurnOutCard.cbCardCount;
|
||
StatusPlay.isLastCard = m_TurnOutCard.isLastCard;
|
||
CopyMemory(StatusPlay.cbTurnCardData, m_TurnOutCard.cbCardData, m_TurnOutCard.cbCardCount*sizeof(BYTE));
|
||
|
||
//扑克信息
|
||
CopyMemory(StatusPlay.cbHandCardCount, m_cbHandCardCount, sizeof(m_cbHandCardCount));
|
||
CopyMemory(StatusPlay.cbHandCardData, m_cbHandCardData[wChairID], sizeof(BYTE)*m_cbHandCardCount[wChairID]);
|
||
CopyMemory(StatusPlay.cbPartnerCardData, m_cbHandCardData[(wChairID + 2) % GAME_PLAYER], sizeof(BYTE)*m_cbHandCardCount[(wChairID + 2) % GAME_PLAYER]);
|
||
|
||
//发送场景
|
||
return m_pITableFrame->SendGameScene(pIServerUserItem, &StatusPlay, sizeof(StatusPlay));
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
//定时器事件
|
||
bool CTableFrameSink::OnTimerMessage(DWORD wTimerID, WPARAM wBindParam)
|
||
{
|
||
if (IDI_SEND_CARD == wTimerID)
|
||
{
|
||
// 检测是否解散游戏;
|
||
if (IsHasGameRule(eDZRuleEnum_NO_BOMB))
|
||
{
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (!IsHasBomb(m_cbHandCardData[i], m_cbHandCardCount[i]))
|
||
{
|
||
m_etGameEndType = GAME_END_NO_BOMB;
|
||
return OnEventGameConclude(INVALID_CHAIR, nullptr, GER_BAOZI);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (IsHasGameRule(eDZRuleEnum_EIGHT_BOMB))
|
||
{
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (IsHas8Bomb(m_cbHandCardData[i], m_cbHandCardCount[i]))
|
||
{
|
||
m_etGameEndType = GAME_END_8_BOMB;
|
||
return OnEventGameConclude(INVALID_CHAIR, nullptr, GER_BAOZI);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 有王不打独;
|
||
if (IsHasGameRule(eDZRuleEnum_NO_JOKER))
|
||
{
|
||
//设置状态;
|
||
m_pITableFrame->SetGameStatus(GAME_SCENE_CALL_SCORE);
|
||
|
||
//构造变量;
|
||
CMD_S_CallScore CallScore;
|
||
CallScore.wCallScoreUser = INVALID_CHAIR;
|
||
CallScore.wCurrentUser = m_wCurrentUser;
|
||
CallScore.cbCallScore = 0xff;
|
||
|
||
//发送消息;
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_CALL_SCORE, &CallScore, sizeof(CallScore));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_CALL_SCORE, &CallScore, sizeof(CallScore));
|
||
}
|
||
else
|
||
{
|
||
// 场景状态;
|
||
m_pITableFrame->SetGameStatus(GAME_SCENE_PLAY);
|
||
|
||
//设置用户;
|
||
m_bNobodyCallScore = true;
|
||
m_wBankerUser = m_wFirstUser;
|
||
m_wTurnWiner = m_wBankerUser;
|
||
m_wCurrentUser = m_wBankerUser;
|
||
|
||
//发送消息;
|
||
CMD_S_BankerInfo BankerInfo;
|
||
ZeroMemory(&BankerInfo, sizeof(CMD_S_BankerInfo));
|
||
BankerInfo.wBankerUser = m_wBankerUser;
|
||
BankerInfo.wCurrentUser = m_wCurrentUser;
|
||
BankerInfo.bCallCard = m_bNobodyCallScore;
|
||
BankerInfo.cbFirendCardData = SearchFriendChairID();
|
||
|
||
// 明边;
|
||
if (IsHasGameRule(eDZRuleEnum_MINGBIAN))
|
||
{
|
||
for (WORD i = 0; i < m_wPlayerCount; i++)
|
||
{
|
||
BankerInfo.wFriendChairID[i] = m_wFriendChairID[i];
|
||
}
|
||
}
|
||
else // 暗边;
|
||
{
|
||
for (WORD i = 0; i < m_wPlayerCount; i++)
|
||
{
|
||
BankerInfo.wFriendChairID[i] = INVALID_CHAIR;
|
||
}
|
||
}
|
||
|
||
//发送数据
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_BANKER_INFO, &BankerInfo, sizeof(BankerInfo));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_BANKER_INFO, &BankerInfo, sizeof(BankerInfo));
|
||
|
||
//增加记录;
|
||
addGameRecordAction(SUB_S_BANKER_INFO, &BankerInfo, sizeof(BankerInfo));
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
//数据事件
|
||
bool CTableFrameSink::OnDataBaseMessage(WORD wRequestID, VOID * pData, WORD wDataSize)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
//积分事件
|
||
bool CTableFrameSink::OnUserScroeNotify(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
//游戏消息处理
|
||
bool CTableFrameSink::OnGameMessage(WORD wSubCmdID, VOID * pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem)
|
||
{
|
||
switch (wSubCmdID)
|
||
{
|
||
case SUB_C_CALL_SCORE: //用户叫分;
|
||
{
|
||
//效验数据;
|
||
ASSERT(wDataSize == sizeof(CMD_C_CallScore));
|
||
if (wDataSize != sizeof(CMD_C_CallScore)) return false;
|
||
|
||
//状态效验;
|
||
ASSERT(m_pITableFrame->GetGameStatus()==GAME_SCENE_CALL_SCORE);
|
||
if (m_pITableFrame->GetGameStatus() != GAME_SCENE_CALL_SCORE) return true;
|
||
|
||
//用户效验;
|
||
ASSERT(pIServerUserItem->GetUserStatus()==US_PLAYING);
|
||
if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
|
||
|
||
//变量定义;
|
||
CMD_C_CallScore * pCallScore = (CMD_C_CallScore *)pDataBuffer;
|
||
|
||
//消息处理;
|
||
WORD wChairID = pIServerUserItem->GetChairID();
|
||
return OnUserCallScore(wChairID, pCallScore->cbCallScore);
|
||
}
|
||
case SUB_C_OUT_CARD: //用户出牌
|
||
{
|
||
//变量定义
|
||
CMD_C_OutCard * pOutCard = (CMD_C_OutCard *)pDataBuffer;
|
||
WORD wHeadSize = sizeof(CMD_C_OutCard) - sizeof(pOutCard->cbCardData);
|
||
|
||
//效验数据
|
||
ASSERT(wDataSize >= wHeadSize);
|
||
if (wDataSize < wHeadSize) return false;
|
||
ASSERT(wDataSize == (wHeadSize + pOutCard->cbCardCount*sizeof(pOutCard->cbCardData[0])));
|
||
if (wDataSize != (wHeadSize + pOutCard->cbCardCount*sizeof(pOutCard->cbCardData[0]))) return false;
|
||
|
||
//用户效验
|
||
ASSERT(pIServerUserItem->GetUserStatus() == US_PLAYING);
|
||
if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
|
||
|
||
//消息处理
|
||
WORD wChairID = pIServerUserItem->GetChairID();
|
||
//return OnUserOutCard(wChairID, pOutCard->cbCardData, pOutCard->cbCardType, pOutCard->cbCardCount);
|
||
return OnUserOutCard(wChairID, pOutCard);
|
||
}
|
||
case SUB_C_PASS_CARD:
|
||
{
|
||
//用户效验
|
||
ASSERT(pIServerUserItem->GetUserStatus() == US_PLAYING);
|
||
if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
|
||
|
||
//消息处理
|
||
WORD wChairID = pIServerUserItem->GetChairID();
|
||
return OnUserPassCard(wChairID);
|
||
}
|
||
case SUB_C_TRUSTEE:
|
||
{
|
||
CMD_C_Trustee *pTrustee = (CMD_C_Trustee *)pDataBuffer;
|
||
if (wDataSize != sizeof(CMD_C_Trustee)) return false;
|
||
|
||
//用户效验
|
||
WORD wChairID = pIServerUserItem->GetChairID();
|
||
|
||
m_bTrustee[wChairID] = pTrustee->bTrustee;
|
||
CMD_S_Trustee Trustee;
|
||
Trustee.bTrustee = pTrustee->bTrustee;
|
||
Trustee.wChairID = wChairID;
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_TRUSTEE, &Trustee, sizeof(Trustee));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_TRUSTEE, &Trustee, sizeof(Trustee));
|
||
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
//框架消息
|
||
bool CTableFrameSink::OnFrameMessage(WORD wSubCmdID, VOID * pData, WORD wDataSize, IServerUserItem * pIServerUserItem)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
//重置私人场结束信息
|
||
void CTableFrameSink::ResetPrivateEndInfo()
|
||
{
|
||
ZeroMemory(&m_PrivateEndInfo, sizeof(CMD_S_Private_End_Info));
|
||
}
|
||
|
||
//获得私人场结束信息流
|
||
void CTableFrameSink::GetPrivateEndInfo(DataStream &kDataStream, bool bSend)
|
||
{
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
// 总积分
|
||
IServerUserItem* pServerUserItem = m_pITableFrame->GetTableUserItem(i);
|
||
if (pServerUserItem)
|
||
{
|
||
m_PrivateEndInfo.lAllScore[i] = pServerUserItem->GetUserScore();
|
||
}
|
||
}
|
||
|
||
m_PrivateEndInfo.StreamValue(kDataStream, bSend);
|
||
}
|
||
|
||
//判断私人场是否结束
|
||
bool CTableFrameSink::IsPrivateEnd()
|
||
{
|
||
ASSERT(m_pITableFrame != nullptr);
|
||
if (m_pITableFrame == nullptr) return false;
|
||
|
||
tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
|
||
tagPrivateFrameRecordInfo* pPrivateRecord = m_pITableFrame->GetPrivateFrameRecord();
|
||
|
||
if ((pPrivateFrame == nullptr) || (pPrivateRecord == nullptr)) return false;
|
||
|
||
if (pPrivateFrame->cbGameCout <= pPrivateRecord->cbFinishCout)
|
||
{
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
bool CTableFrameSink::IsHasGameRule(eDZRuleEnum eType)
|
||
{
|
||
ASSERT(m_pITableFrame != nullptr);
|
||
if (m_pITableFrame == nullptr) return false;
|
||
|
||
const tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
|
||
if (nullptr == pPrivateFrame) return false;
|
||
return (pPrivateFrame->dwGameRule & eType) > 0;
|
||
|
||
//DWORD dwGameRule = (eDZRuleEnum_LOTTERY_7 | eDZRuleEnum_LOTTERY_10 | eDZRuleEnum_LOTTERY_J | eDZRuleEnum_LOTTERY_K);
|
||
//return (dwGameRule & eType) > 0;
|
||
}
|
||
|
||
bool CTableFrameSink::IsRecordServerType()
|
||
{
|
||
return ((m_pGameServiceOption->wServerType&GAME_GENRE_EDUCATE) == GAME_GENRE_EDUCATE);
|
||
}
|
||
|
||
//用户坐下
|
||
bool CTableFrameSink::OnActionUserSitDown(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
|
||
{
|
||
//庄家设置
|
||
if ((bLookonUser == false) && (m_wFirstUser == INVALID_CHAIR))
|
||
{
|
||
m_wFirstUser = pIServerUserItem->GetChairID();
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
//用户起来
|
||
bool CTableFrameSink::OnActionUserStandUp(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
|
||
{
|
||
//庄家设置
|
||
if ((bLookonUser == false) && (m_wBankerUser == pIServerUserItem->GetChairID()))
|
||
{
|
||
m_wBankerUser = INVALID_CHAIR;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
//用户叫分;
|
||
bool CTableFrameSink::OnUserCallScore(WORD wChairID, BYTE cbCallScore)
|
||
{
|
||
//效验状态;
|
||
ASSERT(wChairID == m_wCurrentUser);
|
||
if (wChairID != m_wCurrentUser) return true;
|
||
|
||
//设置叫分;
|
||
m_cbScoreInfo[wChairID] = cbCallScore;
|
||
|
||
//设置用户;
|
||
if (cbCallScore != 0xFF)
|
||
{
|
||
m_wBankerUser = wChairID;
|
||
m_wCurrentUser = INVALID_CHAIR;
|
||
}
|
||
else
|
||
{
|
||
WORD wNextUser = (wChairID + 1) % GAME_PLAYER;
|
||
|
||
// 四人都不叫;
|
||
if (m_wFirstUser == wNextUser)
|
||
{
|
||
m_bNobodyCallScore = true;
|
||
m_wBankerUser = m_wFirstUser;
|
||
m_wCurrentUser = INVALID_CHAIR;
|
||
}
|
||
else
|
||
{
|
||
m_wCurrentUser = wNextUser;
|
||
}
|
||
}
|
||
|
||
//构造变量;
|
||
CMD_S_CallScore CallScore;
|
||
CallScore.wCallScoreUser = wChairID;
|
||
CallScore.wCurrentUser = m_wCurrentUser;
|
||
CallScore.cbCallScore = cbCallScore;
|
||
|
||
//发送消息;
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_CALL_SCORE, &CallScore, sizeof(CallScore));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_CALL_SCORE, &CallScore, sizeof(CallScore));
|
||
|
||
//增加记录;
|
||
addGameRecordAction(SUB_S_CALL_SCORE, &CallScore, sizeof(CallScore));
|
||
|
||
//开始判断;
|
||
if (m_wBankerUser != INVALID_CHAIR)
|
||
{
|
||
//设置状态;
|
||
m_pITableFrame->SetGameStatus(GAME_SCENE_PLAY);
|
||
|
||
//设置用户;
|
||
m_wTurnWiner = m_wBankerUser;
|
||
m_wCurrentUser = m_wBankerUser;
|
||
|
||
//发送消息;
|
||
CMD_S_BankerInfo BankerInfo;
|
||
ZeroMemory(&BankerInfo, sizeof(CMD_S_BankerInfo));
|
||
BankerInfo.wBankerUser = m_wBankerUser;
|
||
BankerInfo.wCurrentUser = m_wCurrentUser;
|
||
BankerInfo.bCallCard = m_bNobodyCallScore;
|
||
|
||
if (m_bNobodyCallScore)
|
||
{
|
||
BankerInfo.cbFirendCardData = SearchFriendChairID();
|
||
//CopyMemory(BankerInfo.wFriendChairID, m_wFriendChairID, sizeof(WORD)*GAME_PLAYER);
|
||
// 明边;
|
||
if (IsHasGameRule(eDZRuleEnum_MINGBIAN))
|
||
{
|
||
for (WORD i = 0; i < m_wPlayerCount; i++)
|
||
{
|
||
BankerInfo.wFriendChairID[i] = m_wFriendChairID[i];
|
||
}
|
||
}
|
||
else // 暗边;
|
||
{
|
||
for (WORD i = 0; i < m_wPlayerCount; i++)
|
||
{
|
||
BankerInfo.wFriendChairID[i] = INVALID_CHAIR;
|
||
}
|
||
}
|
||
}
|
||
|
||
//发送消息;
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_BANKER_INFO, &BankerInfo, sizeof(BankerInfo));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_BANKER_INFO, &BankerInfo, sizeof(BankerInfo));
|
||
|
||
//增加记录;
|
||
addGameRecordAction(SUB_S_BANKER_INFO, &BankerInfo, sizeof(BankerInfo));
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
//用户出牌
|
||
bool CTableFrameSink::OnUserOutCard(WORD wChairID, CMD_C_OutCard * pOutCard)
|
||
{
|
||
//效验状态
|
||
ASSERT(m_pITableFrame->GetGameStatus() == GAME_SCENE_PLAY);
|
||
if (m_pITableFrame->GetGameStatus() != GAME_SCENE_PLAY) return true;
|
||
|
||
ASSERT(wChairID == m_wCurrentUser);
|
||
if (wChairID != m_wCurrentUser) return false;
|
||
|
||
ASSERT(pOutCard != nullptr);
|
||
if (pOutCard == nullptr) return false;
|
||
|
||
// 牌型校验;
|
||
ASSERT(pOutCard->cbCardType != CT_ERROR);
|
||
|
||
// 是否是最后一手牌;
|
||
bool isLastCard = (pOutCard->cbCardCount == m_cbHandCardCount[wChairID]);
|
||
|
||
// 排序;
|
||
m_GameLogic.SortCardList(pOutCard->cbCardData, pOutCard->cbCardCount, ST_ORDER);
|
||
|
||
//类型判断
|
||
int bCardType = m_GameLogic.GetCardType(pOutCard->cbCardData, pOutCard->cbCardCount, isLastCard);
|
||
if ((bCardType&pOutCard->cbCardType) == CT_ERROR)
|
||
{
|
||
ASSERT(FALSE);
|
||
return false;
|
||
}
|
||
|
||
//更随出牌
|
||
if (m_TurnOutCard.cbCardCount > 0 && m_GameLogic.CompareCard(&m_TurnOutCard, pOutCard) == false)
|
||
{
|
||
ASSERT(FALSE);
|
||
return false;
|
||
}
|
||
|
||
//删除扑克
|
||
if (m_GameLogic.RemoveCard(pOutCard->cbCardData, pOutCard->cbCardCount, m_cbHandCardData[wChairID], m_cbHandCardCount[wChairID]) == false)
|
||
{
|
||
ASSERT(FALSE);
|
||
return false;
|
||
}
|
||
|
||
// 统计炸弹奖分
|
||
if ((bCardType >> CT_BOMB_4) > 0)
|
||
{
|
||
BYTE cbBombCardData = pOutCard->cbCardData[pOutCard->cbCardCount - 1];
|
||
GetBombScore(wChairID, cbBombCardData, bCardType);
|
||
}
|
||
|
||
//设置变量
|
||
m_cbHandCardCount[wChairID] -= pOutCard->cbCardCount;
|
||
|
||
// 保留玩家出牌;
|
||
m_TurnOutCard.cbCardCount = pOutCard->cbCardCount;
|
||
m_TurnOutCard.isLastCard = isLastCard;
|
||
m_TurnOutCard.cbCardType = pOutCard->cbCardType;
|
||
CopyMemory(m_TurnOutCard.cbCardData, pOutCard->cbCardData, sizeof(BYTE)*pOutCard->cbCardCount);
|
||
|
||
//如呆没有玩家包牌;
|
||
if (m_bNobodyCallScore)
|
||
{
|
||
if (m_cbHandCardCount[wChairID] == 0)
|
||
{
|
||
//设置用户
|
||
m_wWinOrder[m_wWinCount++] = wChairID;
|
||
|
||
CMD_S_Ranking mRanking;
|
||
mRanking.wChairID = wChairID;
|
||
mRanking.cbRanking = (BYTE)m_wWinCount;
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_RANKING, &mRanking, sizeof(mRanking));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_RANKING, &mRanking, sizeof(mRanking));
|
||
|
||
//增加记录;
|
||
addGameRecordAction(SUB_S_RANKING, &mRanking, sizeof(mRanking));
|
||
|
||
//用户统计
|
||
WORD wFriendChairID = m_wFriendChairID[wChairID];
|
||
if (m_cbHandCardCount[wFriendChairID] == 0)
|
||
{
|
||
m_wCurrentUser = INVALID_CHAIR;
|
||
}
|
||
|
||
// 只打二游;
|
||
if (IsHasGameRule(eDZRuleEnum_TO_TWO) && (2 == m_wWinCount))
|
||
{
|
||
m_wCurrentUser = INVALID_CHAIR;
|
||
}
|
||
}
|
||
|
||
//切换用户
|
||
if (m_wCurrentUser != INVALID_CHAIR)
|
||
{
|
||
//设置用户
|
||
m_wTurnWiner = wChairID;
|
||
m_wCurrentUser = (wChairID + 1) % GAME_PLAYER;
|
||
|
||
//用户调整
|
||
while (m_cbHandCardCount[m_wCurrentUser] == 0)
|
||
{
|
||
m_wCurrentUser = (m_wCurrentUser + 1) % GAME_PLAYER;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//如果有玩家包牌并且出牌玩家剩余牌数为0则结束游戏;
|
||
if (m_cbHandCardCount[wChairID] != 0)
|
||
{
|
||
//设置用户
|
||
m_wTurnWiner = wChairID;
|
||
m_wCurrentUser = (m_wCurrentUser + 1) % GAME_PLAYER;
|
||
}
|
||
else
|
||
{
|
||
m_wCurrentUser = INVALID_CHAIR;
|
||
}
|
||
}
|
||
|
||
//构造数据
|
||
CMD_S_OutCard OutCard;
|
||
ZeroMemory(&OutCard, sizeof(OutCard));
|
||
OutCard.isLastCard = isLastCard;
|
||
OutCard.cbCardType = pOutCard->cbCardType;
|
||
OutCard.wOutCardUser = wChairID;
|
||
OutCard.cbCardCount = pOutCard->cbCardCount;
|
||
OutCard.wCurrentUser = m_wCurrentUser;
|
||
CopyMemory(OutCard.cbCardData, pOutCard->cbCardData, pOutCard->cbCardCount*sizeof(BYTE));
|
||
|
||
//发送数据
|
||
WORD wHeadSize = sizeof(OutCard) - sizeof(OutCard.cbCardData);
|
||
WORD wSendSize = wHeadSize + OutCard.cbCardCount*sizeof(BYTE);
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OUT_CARD, &OutCard, wSendSize);
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OUT_CARD, &OutCard, wSendSize);
|
||
|
||
//增加记录;
|
||
addGameRecordAction(SUB_S_OUT_CARD, &OutCard, wSendSize);
|
||
|
||
//结束判断(出牌玩家不是打独玩家时候结束游戏)
|
||
if (m_wCurrentUser == INVALID_CHAIR)
|
||
{
|
||
OnEventGameConclude(wChairID, NULL, GER_NORMAL);
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
//用户放弃
|
||
bool CTableFrameSink::OnUserPassCard(WORD wChairID)
|
||
{
|
||
//效验状态
|
||
if (m_pITableFrame->GetGameStatus() != GAME_SCENE_PLAY) return true;
|
||
if ((wChairID != m_wCurrentUser) || (m_TurnOutCard.cbCardCount == 0)) return false;
|
||
|
||
//用户切换
|
||
do
|
||
{
|
||
//设置用户
|
||
m_wCurrentUser = (m_wCurrentUser + 1) % GAME_PLAYER;
|
||
|
||
//完成判断
|
||
if (m_wCurrentUser == m_wTurnWiner)
|
||
{
|
||
//设置变量
|
||
m_TurnOutCard.cbCardCount = 0;
|
||
|
||
//接风处理
|
||
if (m_cbHandCardCount[m_wTurnWiner] == 0)
|
||
{
|
||
//m_wCurrentUser = (m_wTurnWiner + 2) % GAME_PLAYER;
|
||
m_wCurrentUser = m_wFriendChairID[m_wTurnWiner];
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
//继续处理
|
||
if (m_cbHandCardCount[m_wCurrentUser] != 0) break;
|
||
|
||
} while (true);
|
||
|
||
//构造消息
|
||
CMD_S_PassCard PassCard;
|
||
PassCard.wPassCardUser = wChairID;
|
||
PassCard.wCurrentUser = m_wCurrentUser;
|
||
PassCard.cbTurnOver = (m_TurnOutCard.cbCardCount == 0) ? TRUE : FALSE;
|
||
|
||
//发送数据
|
||
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_PASS_CARD, &PassCard, sizeof(PassCard));
|
||
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_PASS_CARD, &PassCard, sizeof(PassCard));
|
||
|
||
//增加记录;
|
||
addGameRecordAction(SUB_S_PASS_CARD, &PassCard, sizeof(CMD_S_PassCard));
|
||
|
||
return true;
|
||
}
|
||
|
||
//搜索伙伴;
|
||
BYTE CTableFrameSink::SearchFriendChairID()
|
||
{
|
||
static BYTE cbFriendCard[13] = { 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x21, 0x22 };
|
||
|
||
// 搜索伙伴;
|
||
BYTE cbTmpCardData = 0x0;
|
||
BYTE cbTmpCardCount = 0;
|
||
WORD wFirstChairID = INVALID_CHAIR;
|
||
WORD wNextChairID = INVALID_CHAIR;
|
||
|
||
for (BYTE i = 0; i < 13; i++)
|
||
{
|
||
cbTmpCardData = cbFriendCard[i];
|
||
|
||
// 查找指定牌在谁手里;
|
||
for (BYTE j = 0; j < GAME_PLAYER; j++)
|
||
{
|
||
for (BYTE k = 0; k < m_cbHandCardCount[j];k++)
|
||
{
|
||
// 找到确定牌;
|
||
if (cbTmpCardData == m_cbHandCardData[j][k])
|
||
{
|
||
cbTmpCardCount++;
|
||
|
||
// 一张牌最多2张;
|
||
if (cbTmpCardCount >= 2) break;
|
||
}
|
||
}
|
||
|
||
// 两张牌在同一人手里;
|
||
if ((cbTmpCardCount >= 2) && (wFirstChairID == INVALID_CHAIR))
|
||
{
|
||
cbTmpCardCount = 0;
|
||
wFirstChairID = INVALID_CHAIR;
|
||
wNextChairID = INVALID_CHAIR;
|
||
break;
|
||
}
|
||
// 找到第一个人;
|
||
if ((cbTmpCardCount == 1) && (wFirstChairID == INVALID_CHAIR))
|
||
{
|
||
wFirstChairID = j;
|
||
}
|
||
// 找到第二个人;
|
||
else if ((cbTmpCardCount == 2) && (wFirstChairID != INVALID_CHAIR))
|
||
{
|
||
wNextChairID = j;
|
||
}
|
||
|
||
// 找到2个人了;
|
||
if ((cbTmpCardCount == 2) && (wFirstChairID != INVALID_CHAIR) && (wNextChairID != INVALID_CHAIR))
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 找到2个人了;
|
||
if ((cbTmpCardCount == 2) && (wFirstChairID != INVALID_CHAIR) && (wNextChairID != INVALID_CHAIR))
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 找到2个人了;
|
||
if ((cbTmpCardCount == 2) && (wFirstChairID != INVALID_CHAIR) && (wNextChairID != INVALID_CHAIR))
|
||
{
|
||
m_wFriendChairID[wFirstChairID] = wNextChairID;
|
||
m_wFriendChairID[wNextChairID] = wFirstChairID;
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if ((i == wFirstChairID) || (i == wNextChairID)) continue;
|
||
|
||
for (WORD j = 0; j < GAME_PLAYER; j++)
|
||
{
|
||
if ((j == wFirstChairID) || (j == wNextChairID) || (j == i)) continue;
|
||
|
||
m_wFriendChairID[i] = j;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 没找到同伴,默认对家同伴;
|
||
for (WORD i = 0; i < m_wPlayerCount; i++)
|
||
{
|
||
m_wFriendChairID[i] = (i + 2) % GAME_PLAYER;
|
||
}
|
||
}
|
||
|
||
return cbTmpCardData;
|
||
}
|
||
|
||
//炸弹升级;
|
||
int CTableFrameSink::AddBombScore(int nCardType, bool bList /*= true*/)
|
||
{
|
||
int nTmpCardType = 0;
|
||
|
||
// 炸弹分级,2炸加一级;
|
||
if (m_GameLogic.IsHasCardType(nCardType, CT_BOMB_4))
|
||
{
|
||
nTmpCardType = (bList ? m_GameLogic.TransListToInt(0, CT_BOMB_5) : CT_BOMB_5);
|
||
}
|
||
else if (m_GameLogic.IsHasCardType(nCardType, CT_BOMB_5))
|
||
{
|
||
//nTmpCardType = m_GameLogic.TransListToInt(0, CT_BOMB_6);
|
||
nTmpCardType = (bList ? m_GameLogic.TransListToInt(0, CT_BOMB_6) : CT_BOMB_6);
|
||
}
|
||
else if (m_GameLogic.IsHasCardType(nCardType, CT_BOMB_6))
|
||
{
|
||
//nTmpCardType = m_GameLogic.TransListToInt(0, CT_BOMB_7);
|
||
nTmpCardType = (bList ? m_GameLogic.TransListToInt(0, CT_BOMB_7) : CT_BOMB_7);
|
||
}
|
||
else if (m_GameLogic.IsHasCardType(nCardType, CT_BOMB_7))
|
||
{
|
||
//nTmpCardType = m_GameLogic.TransListToInt(0, CT_BOMB_8);
|
||
nTmpCardType = (bList ? m_GameLogic.TransListToInt(0, CT_BOMB_8) : CT_BOMB_8);
|
||
}
|
||
else if (m_GameLogic.IsHasCardType(nCardType, CT_BOMB_8))
|
||
{
|
||
//nTmpCardType = m_GameLogic.TransListToInt(0, CT_BOMB_9);
|
||
nTmpCardType = (bList ? m_GameLogic.TransListToInt(0, CT_BOMB_9) : CT_BOMB_9);
|
||
}
|
||
else if (m_GameLogic.IsHasCardType(nCardType, CT_BOMB_9))
|
||
{
|
||
//nTmpCardType = m_GameLogic.TransListToInt(0, CT_BOMB_10);
|
||
nTmpCardType = (bList ? m_GameLogic.TransListToInt(0, CT_BOMB_10) : CT_BOMB_10);
|
||
}
|
||
else
|
||
{
|
||
nTmpCardType = nCardType;
|
||
}
|
||
|
||
return nTmpCardType;
|
||
}
|
||
|
||
//计算炸弹积分;
|
||
void CTableFrameSink::GetBombScore(WORD wChairID, BYTE cbCardData, int nCardType)
|
||
{
|
||
if ((nCardType >> CT_BOMB_4) > 0)
|
||
{
|
||
SCORE lBombScore = 0; // 炸弹分;
|
||
int nTmpCardType = CT_ERROR;
|
||
if ((m_GameLogic.GetCardValue(cbCardData) == m_GameLogic.GetCardValue(0x02)))
|
||
{
|
||
nTmpCardType = AddBombScore(nCardType);
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_7) && (m_GameLogic.GetCardValue(cbCardData) == m_GameLogic.GetCardValue(0x07)))
|
||
{
|
||
nTmpCardType = AddBombScore(nCardType);
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_10) && (m_GameLogic.GetCardValue(cbCardData) == m_GameLogic.GetCardValue(0x0A)))
|
||
{
|
||
nTmpCardType = AddBombScore(nCardType);
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_J) && (m_GameLogic.GetCardValue(cbCardData) == m_GameLogic.GetCardValue(0x0B)))
|
||
{
|
||
nTmpCardType = AddBombScore(nCardType);
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_K) && (m_GameLogic.GetCardValue(cbCardData) == m_GameLogic.GetCardValue(0x0D)))
|
||
{
|
||
nTmpCardType = AddBombScore(nCardType);
|
||
}
|
||
else
|
||
{
|
||
nTmpCardType = nCardType;
|
||
}
|
||
|
||
// 炸弹分级,2炸加一级;
|
||
if (m_GameLogic.IsHasCardType(nTmpCardType, CT_BOMB_5))
|
||
{
|
||
lBombScore = 1;
|
||
}
|
||
else if (m_GameLogic.IsHasCardType(nTmpCardType, CT_BOMB_6))
|
||
{
|
||
lBombScore = 2;
|
||
}
|
||
else if (m_GameLogic.IsHasCardType(nTmpCardType, CT_BOMB_7))
|
||
{
|
||
lBombScore = 4;
|
||
}
|
||
else if (m_GameLogic.IsHasCardType(nTmpCardType, CT_BOMB_8))
|
||
{
|
||
lBombScore = 8;
|
||
}
|
||
else if (m_GameLogic.IsHasCardType(nTmpCardType, CT_BOMB_9))
|
||
{
|
||
lBombScore = 16;
|
||
}
|
||
else if (m_GameLogic.IsHasCardType(nTmpCardType, CT_BOMB_10))
|
||
{
|
||
lBombScore = 32;
|
||
}
|
||
|
||
// 分数统计;
|
||
if (lBombScore > 0)
|
||
{
|
||
// 记录日志;
|
||
MyLog("wChairID=%d, cbCardData=0x%x, nCardType=%d, lBombScore=%ld", wChairID, cbCardData, nTmpCardType, lBombScore);
|
||
|
||
m_lBombScore[wChairID] += lBombScore * (GAME_PLAYER - 1);
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
if (i != wChairID)
|
||
{
|
||
m_lBombScore[i] -= lBombScore;
|
||
}
|
||
|
||
MyLog("m_lBombScore[%d] = %ld", i, m_lBombScore[i]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void CTableFrameSink::GetBombScore(WORD wChairID, BYTE cbHandCardData[], BYTE cbHandCardCount)
|
||
{
|
||
BYTE bCardDataTemp[MAX_COUNT] = { 0 };
|
||
|
||
BYTE cbJokerCount = 0;
|
||
BYTE cbCardTempCount = 0;
|
||
|
||
// 拷贝牌列表,不拷贝王;
|
||
for (BYTE i = 0; i < cbHandCardCount; i++)
|
||
{
|
||
if (m_GameLogic.IsLaiZiCard(cbHandCardData[i]))
|
||
{
|
||
cbJokerCount++;
|
||
}
|
||
else
|
||
{
|
||
bCardDataTemp[cbCardTempCount++] = cbHandCardData[i];
|
||
}
|
||
}
|
||
|
||
//分析扑克
|
||
tagAnalyseResult AnalyseResult;
|
||
ZeroMemory(&AnalyseResult, sizeof(AnalyseResult));
|
||
m_GameLogic.AnalysebCardData(bCardDataTemp, cbCardTempCount, AnalyseResult);
|
||
|
||
BYTE cbMaxCardType = 0;
|
||
BYTE cbMaxCardValue = 0;
|
||
|
||
// 找到最大的炸(先找普通最大牌型,再找开奖最大牌型,然后将两个牌型比较);
|
||
if (cbJokerCount > 0)
|
||
{
|
||
// 倒着找;
|
||
for (int i = BLOCK_EIGHT; i >= 0; i--)
|
||
{
|
||
// 找到数量最多的手牌;
|
||
if (AnalyseResult.cbBlockCount[i] > 0)
|
||
{
|
||
BYTE cbCardCount = i + 1; // 牌数量;
|
||
|
||
// 算上癞子数量;
|
||
BYTE nCardType = CT_BOMB_4 + cbJokerCount + cbCardCount - 4;
|
||
nCardType = (nCardType > CT_BOMB_10) ? CT_BOMB_10 : nCardType;
|
||
|
||
// 不是炸弹不管;
|
||
if (nCardType < CT_BOMB_4) break;
|
||
|
||
for (BYTE j = 0; j < AnalyseResult.cbBlockCount[i]; j++)
|
||
{
|
||
BYTE nTmpCardType = 0;
|
||
BYTE cbBombCard = AnalyseResult.cbCardData[i][j*cbCardCount];
|
||
|
||
// 2也算开奖;
|
||
if ((m_GameLogic.GetCardValue(cbBombCard) == m_GameLogic.GetCardValue(0x02)))
|
||
{
|
||
nTmpCardType = nCardType + 1;
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_7) && (m_GameLogic.GetCardValue(cbBombCard) == m_GameLogic.GetCardValue(0x07)))
|
||
{
|
||
nTmpCardType = nCardType + 1;
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_10) && (m_GameLogic.GetCardValue(cbBombCard) == m_GameLogic.GetCardValue(0x0A)))
|
||
{
|
||
nTmpCardType = nCardType + 1;
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_J) && (m_GameLogic.GetCardValue(cbBombCard) == m_GameLogic.GetCardValue(0x0B)))
|
||
{
|
||
nTmpCardType = nCardType + 1;
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_K) && (m_GameLogic.GetCardValue(cbBombCard) == m_GameLogic.GetCardValue(0x0D)))
|
||
{
|
||
nTmpCardType = nCardType + 1;
|
||
}
|
||
else
|
||
{
|
||
nTmpCardType = nCardType;
|
||
}
|
||
|
||
// 最大10炸;
|
||
nTmpCardType = (nTmpCardType > CT_BOMB_10) ? CT_BOMB_10 : nTmpCardType;
|
||
|
||
if (nTmpCardType > cbMaxCardType)
|
||
{
|
||
cbMaxCardValue = m_GameLogic.GetCardLogicValue(cbBombCard);
|
||
cbMaxCardType = nTmpCardType;
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 手里有四个王,并且最大炸弹类型小于八炸,就直接用四个王算八炸;
|
||
if ((4 == cbJokerCount) && (cbMaxCardType < CT_BOMB_8))
|
||
{
|
||
int nCardType = m_GameLogic.TransListToInt(0, CT_BOMB_8);
|
||
GetBombScore(wChairID, 0x4F, nCardType);
|
||
|
||
cbJokerCount = 0;
|
||
}
|
||
|
||
// 倒着找;
|
||
for (int i = BLOCK_EIGHT; i >= 0; i--)
|
||
{
|
||
if (AnalyseResult.cbBlockCount[i] <= 0) continue;
|
||
|
||
BYTE cbCardCount = i + 1; // 牌数量;
|
||
|
||
for (BYTE j = 0; j < AnalyseResult.cbBlockCount[i]; j++)
|
||
{
|
||
BYTE cbBombCard = AnalyseResult.cbCardData[i][j*cbCardCount];
|
||
|
||
BYTE cbCardType = CT_BOMB_4 + cbCardCount - 4;
|
||
|
||
// 癞子直接和最大的炸弹组合算头子分;
|
||
if ((cbJokerCount > 0) && (m_GameLogic.GetCardLogicValue(cbBombCard) == cbMaxCardValue))
|
||
{
|
||
cbCardType += cbJokerCount;
|
||
cbJokerCount = 0;
|
||
}
|
||
|
||
cbCardType = (cbCardType > CT_BOMB_10) ? CT_BOMB_10 : cbCardType;
|
||
if (cbCardType < CT_BOMB_4) continue;
|
||
|
||
// 统计炸弹;
|
||
int nCardType = m_GameLogic.TransListToInt(0, cbCardType);
|
||
GetBombScore(wChairID, cbBombCard, nCardType);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
//是否有炸弹(不算王);
|
||
bool CTableFrameSink::IsHasBomb(BYTE cbHandCardData[], BYTE cbHandCardCount)
|
||
{
|
||
bool bHasBomb = false;
|
||
|
||
BYTE bCardDataTemp[MAX_COUNT] = { 0 };
|
||
|
||
BYTE cbCardTempCount = 0;
|
||
|
||
// 拷贝牌列表,不拷贝王;
|
||
for (BYTE i = 0; i < cbHandCardCount; i++)
|
||
{
|
||
if (!m_GameLogic.IsLaiZiCard(cbHandCardData[i]))
|
||
{
|
||
bCardDataTemp[cbCardTempCount++] = cbHandCardData[i];
|
||
}
|
||
}
|
||
|
||
//分析扑克
|
||
tagAnalyseResult AnalyseResult;
|
||
ZeroMemory(&AnalyseResult, sizeof(AnalyseResult));
|
||
m_GameLogic.AnalysebCardData(bCardDataTemp, cbCardTempCount, AnalyseResult);
|
||
|
||
for (int i = BLOCK_FOUR; i <= BLOCK_EIGHT; i++)
|
||
{
|
||
if (AnalyseResult.cbBlockCount[i] > 0)
|
||
{
|
||
bHasBomb = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return bHasBomb;
|
||
}
|
||
|
||
//是否8炸弹;
|
||
bool CTableFrameSink::IsHas8Bomb(BYTE cbHandCardData[], BYTE cbHandCardCount)
|
||
{
|
||
bool bHas8Bomb = false;
|
||
|
||
BYTE bCardDataTemp[MAX_COUNT] = { 0 };
|
||
|
||
BYTE cbJokerCount = 0;
|
||
BYTE cbCardTempCount = 0;
|
||
|
||
// 拷贝牌列表,不拷贝王;
|
||
for (BYTE i = 0; i < cbHandCardCount; i++)
|
||
{
|
||
if (m_GameLogic.IsLaiZiCard(cbHandCardData[i]))
|
||
{
|
||
cbJokerCount++;
|
||
}
|
||
else
|
||
{
|
||
bCardDataTemp[cbCardTempCount++] = cbHandCardData[i];
|
||
}
|
||
}
|
||
|
||
// 四张王就是八炸;
|
||
if (cbJokerCount >= 4) return true;
|
||
|
||
//分析扑克
|
||
tagAnalyseResult AnalyseResult;
|
||
ZeroMemory(&AnalyseResult, sizeof(AnalyseResult));
|
||
m_GameLogic.AnalysebCardData(bCardDataTemp, cbCardTempCount, AnalyseResult);
|
||
|
||
// 最小八炸就是4炸加4王;
|
||
for (int i = BLOCK_FOUR; i <= BLOCK_EIGHT; i++)
|
||
{
|
||
// 有炸弹;
|
||
if (AnalyseResult.cbBlockCount[i] > 0)
|
||
{
|
||
if ((i + cbJokerCount) >= BLOCK_EIGHT)
|
||
{
|
||
bHas8Bomb = true;
|
||
break;
|
||
}
|
||
else if ((i + cbJokerCount) == BLOCK_SEVEN)
|
||
{
|
||
// 找最大牌值;
|
||
BYTE cbCardCount = i + 1; // 牌数量;
|
||
for (BYTE j = 0; j < AnalyseResult.cbBlockCount[i]; j++)
|
||
{
|
||
BYTE cbCardData = AnalyseResult.cbCardData[i][j*cbCardCount];
|
||
|
||
if ((m_GameLogic.GetCardValue(cbCardData) == m_GameLogic.GetCardValue(0x02)))
|
||
{
|
||
bHas8Bomb = true;
|
||
break;
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_7) && (m_GameLogic.GetCardValue(cbCardData) == m_GameLogic.GetCardValue(0x07)))
|
||
{
|
||
bHas8Bomb = true;
|
||
break;
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_10) && (m_GameLogic.GetCardValue(cbCardData) == m_GameLogic.GetCardValue(0x0A)))
|
||
{
|
||
bHas8Bomb = true;
|
||
break;
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_J) && (m_GameLogic.GetCardValue(cbCardData) == m_GameLogic.GetCardValue(0x0B)))
|
||
{
|
||
bHas8Bomb = true;
|
||
break;
|
||
}
|
||
else if (IsHasGameRule(eDZRuleEnum_LOTTERY_K) && (m_GameLogic.GetCardValue(cbCardData) == m_GameLogic.GetCardValue(0x0D)))
|
||
{
|
||
bHas8Bomb = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return bHas8Bomb;
|
||
}
|
||
|
||
/////////////////////////////// 游戏录像 ///////////////////////////////////////////
|
||
void CTableFrameSink::addGameRecordAction(WORD wSubCmdID, void* pSubMessage, int nMessageSize)
|
||
{
|
||
tagGameRecordOperateResult kOperateRecord;
|
||
kOperateRecord.wSubCmdID = wSubCmdID;
|
||
kOperateRecord.subMessageData.pushValue(pSubMessage, nMessageSize);
|
||
m_kGameRecord.actionVec.push_back(kOperateRecord);
|
||
}
|
||
|
||
void CTableFrameSink::starGameRecord()
|
||
{
|
||
m_kGameRecord = tagGameRecord();
|
||
|
||
m_kGameRecord.wBankerUser = m_wBankerUser;
|
||
m_kGameRecord.wEastUser = 0;
|
||
|
||
for (WORD i = 0; i < GAME_PLAYER; i++)
|
||
{
|
||
IServerUserItem* pUserItem = m_pITableFrame->GetTableUserItem(i);
|
||
tagUserInfo* pUserInfo = pUserItem->GetUserInfo();
|
||
if (pUserItem == NULL || NULL == pUserInfo)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
tagGameRecordPlayer kReocrdPlayer;
|
||
kReocrdPlayer.dwUserID = pUserItem->GetUserID();
|
||
kReocrdPlayer.dwGameID = pUserItem->GetGameID();
|
||
kReocrdPlayer.wChairID = pUserItem->GetChairID();
|
||
kReocrdPlayer.cbSex = pUserItem->GetGender();
|
||
kReocrdPlayer.lScore = pUserItem->GetUserScore();
|
||
kReocrdPlayer.strHead = pUserInfo->szHeadHttp;
|
||
kReocrdPlayer.strNickName = pUserItem->GetNickName();
|
||
|
||
for (BYTE j = 0; j < m_cbHandCardCount[i]; j++)
|
||
{
|
||
kReocrdPlayer.cbCardData.push_back(m_cbHandCardData[i][j]);
|
||
}
|
||
m_kGameRecord.playersVec.push_back(kReocrdPlayer);
|
||
}
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
|
||
void CTableFrameSink::MyLog(TCHAR *szLog, ...)
|
||
{
|
||
CString strLog = "";
|
||
va_list ap;
|
||
va_start(ap, szLog);
|
||
strLog.FormatV(szLog, ap);
|
||
va_end(ap);
|
||
|
||
CString strTmpLog = "";
|
||
strTmpLog.Format("TableID = %d, %s.\n", m_pITableFrame->GetTableID(), strLog);
|
||
|
||
::OutputDebugString(strTmpLog.GetBuffer());
|
||
} |