Files
wnmj/Servers/游戏组件/跑的快/服务器组件/TableFrameSink.cpp
2026-02-13 14:34:15 +08:00

1645 lines
43 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "StdAfx.h"
#include "TableFrameSink.h"
//////////////////////////////////////////////////////////////////////////////////
#define IDI_CHECK_TABLE 1 //检查桌子
#define IDI_USER_OUT_TIME 6 //玩家超时
// 游戏定时器
enum tagServerTimerEnum
{
IDI_SEND_CARD = 1, //发牌计时器;
IDI_OUT_CARD = 2, //出牌计时器;
IDT_SEND_CARD = 3000, //发牌时间;
IDT_OUT_CARD = 2000, //出牌时间;
};
//构造函数
CTableFrameSink::CTableFrameSink()
{
//组件变量
m_pITableFrame=NULL;
m_pGameCustomRule=NULL;
m_pGameServiceOption=NULL;
m_pGameServiceAttrib=NULL;
m_bOffLineTrustee = false;
ZeroMemory(m_bActiveUser, sizeof(m_bActiveUser));
//炸弹变量
m_wFirstUser=INVALID_CHAIR;
m_wBankerUser=INVALID_CHAIR;
m_wCurrentUser=INVALID_CHAIR;
ZeroMemory(m_cbOutCardCount,sizeof(m_cbOutCardCount));
for (byte i = 0; i < GAME_PLAYER; i++)
{
m_bUserTrustee[i] = false;
}
//游戏变量
m_wTimerControl=0;
//m_cbBombCount=0;
ZeroMemory(m_lBombScore, sizeof(m_lBombScore));
ZeroMemory(m_aryOverTime, sizeof(m_aryOverTime));
//叫分信息
//m_cbBankerScore=0;
ZeroMemory(m_bScoreInfo,sizeof(m_bScoreInfo));
ZeroMemory(m_bScoreActive, sizeof(m_bScoreActive));
m_cbCallScoreCount=0;
m_cbMustOutCardData = 0x0;
//出牌信息
m_cbTurnCardCount=0;
m_wTurnWiner=INVALID_CHAIR;
ZeroMemory(m_cbTurnCardData,sizeof(m_cbTurnCardData));
//扑克信息
//ZeroMemory(m_cbBankerCard,sizeof(m_cbBankerCard));
ZeroMemory(m_cbHandCardData,sizeof(m_cbHandCardData));
ZeroMemory(m_cbHandCardCount,sizeof(m_cbHandCardCount));
//服务控制
m_hControlInst = NULL;
m_pServerControl = NULL;
m_hControlInst = LoadLibrary(TEXT("LandServerControl.dll"));
if ( m_hControlInst )
{
typedef void * (*CREATE)();
CREATE ServerControl = (CREATE)GetProcAddress(m_hControlInst,"CreateServerControl");
if ( ServerControl )
{
m_pServerControl = static_cast<IServerControl*>(ServerControl());
}
}
ZeroMemory(&m_PrivateEndInfo, sizeof(CMD_S_Private_End_Info));
return;
}
//析构函数
CTableFrameSink::~CTableFrameSink()
{
if( m_pServerControl )
{
delete m_pServerControl;
m_pServerControl = NULL;
}
if( m_hControlInst )
{
FreeLibrary(m_hControlInst);
m_hControlInst = NULL;
}
}
//接口查询
VOID * CTableFrameSink::QueryInterface(REFGUID Guid, DWORD dwQueryVer)
{
QUERYINTERFACE(ITableFrameSink,Guid,dwQueryVer);
QUERYINTERFACE(ITableUserAction,Guid,dwQueryVer);
QUERYINTERFACE_IUNKNOWNEX(ITableFrameSink,Guid,dwQueryVer);
return NULL;
}
//复位桌子
VOID CTableFrameSink::RepositionSink()
{
ZeroMemory(m_bActiveUser, sizeof(m_bActiveUser));
//游戏变量
m_wBankerUser=INVALID_CHAIR;
m_wCurrentUser=INVALID_CHAIR;
ZeroMemory(m_cbOutCardCount,sizeof(m_cbOutCardCount));
ZeroMemory(m_lBombScore, sizeof(m_lBombScore));
ZeroMemory(m_aryOverTime, sizeof(m_aryOverTime));
for (byte i = 0; i < GAME_PLAYER; i++)
{
m_bUserTrustee[i] = false;
}
//叫分信息
ZeroMemory(m_bScoreInfo, sizeof(m_bScoreInfo));
ZeroMemory(m_bScoreActive, sizeof(m_bScoreActive));
m_cbMustOutCardData = 0x0;
m_cbCallScoreCount = 0;
//出牌信息
m_cbTurnCardCount=0;
m_wTurnWiner=INVALID_CHAIR;
ZeroMemory(m_cbTurnCardData,sizeof(m_cbTurnCardData));
//扑克信息
ZeroMemory(m_cbHandCardData,sizeof(m_cbHandCardData));
ZeroMemory(m_cbHandCardCount,sizeof(m_cbHandCardCount));
m_pITableFrame->KillGameTimer(IDI_SEND_CARD);
return;
}
//配置桌子
bool CTableFrameSink::Initialization(IUnknownEx * pIUnknownEx)
{
//查询接口
m_pITableFrame=QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx,ITableFrame);
//错误判断
if (m_pITableFrame==NULL)
{
CTraceService::TraceString(TEXT("游戏桌子 CTableFrameSink 查询 ITableFrame 接口失败"),TraceLevel_Exception);
return false;
}
//开始模式
m_pITableFrame->SetStartMode(START_MODE_FULL_READY);
//游戏配置
m_pGameServiceAttrib=m_pITableFrame->GetGameServiceAttrib();
m_pGameServiceOption=m_pITableFrame->GetGameServiceOption();
//自定规则
ASSERT(m_pITableFrame->GetCustomRule()!=NULL);
m_pGameCustomRule=(tagCustomRule *)m_pITableFrame->GetCustomRule();
m_bOffLineTrustee = CServerRule::IsAllowOffLineTrustee(m_pGameServiceOption->dwServerRule);
////////////////////////////////////////////////////////////////////////////
////搜索出牌;
//tagSearchCardResult mCardResult;
//BYTE cbHandCardData[16] = {0};
//BYTE cbTurnCardData[16] = {0};
//cbHandCardData[0] = 0x01;
//cbHandCardData[1] = 0x3c;
//cbHandCardData[2] = 0x1c;
//cbHandCardData[3] = 0x0c;
//cbHandCardData[4] = 0x17;
//cbHandCardData[5] = 0x03;
//cbTurnCardData[0] = 0x3a;
//cbTurnCardData[1] = 0x2a;
//cbTurnCardData[2] = 0x1a;
//cbTurnCardData[3] = 0x15;
//cbTurnCardData[4] = 0x14;
//BYTE cbResultCount = m_GameLogic.SearchOutCard(cbHandCardData, 6,
// cbTurnCardData, 5, &mCardResult);
//if (cbResultCount > 0)
//{
// return true;
//}
////////////////////////////////////////////////////////////////////////////
return true;
}
//消费能力
SCORE CTableFrameSink::QueryConsumeQuota(IServerUserItem * pIServerUserItem)
{
return 0L;
}
//最少积分
SCORE CTableFrameSink::QueryLessEnterScore(WORD wChairID, IServerUserItem * pIServerUserItem)
{
return 0L;
}
//游戏开始
bool CTableFrameSink::OnEventGameStart()
{
//设置状态
m_pITableFrame->SetGameStatus(GAME_SCENE_SEND);
const tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
ASSERT(nullptr != pPrivateFrame);
m_GameLogic.SetCardRule(pPrivateFrame->dwGameRule);
//出牌信息
m_cbTurnCardCount=0;
m_wTurnWiner=INVALID_CHAIR;
ZeroMemory(m_cbTurnCardData,sizeof(m_cbTurnCardData));
// 设置种子;
srand(GetTickCount() + m_pITableFrame->GetTableID());
// 统计在线玩家;
for (WORD i = 0; i < GAME_PLAYER; ++i)
{
IServerUserItem * pIServerUserItem = m_pITableFrame->GetTableUserItem(i);
if (nullptr == pIServerUserItem) continue;
BYTE cbUserStatus = pIServerUserItem->GetUserStatus();
BYTE cbReUserStatus = pIServerUserItem->GetReUserStatus();
if (cbUserStatus == US_PLAYING || (US_OFFLINE == cbUserStatus && cbReUserStatus == US_PLAYING))
{
m_bActiveUser[i] = true;
}
}
// 结束统计;
for (WORD i = 0; i < GAME_PLAYER; ++i)
{
m_PrivateEndInfo.aryActiveStatus[i] = m_bActiveUser[i];
}
// 16张牌;
if (IsHasGameRule(ePDKRuleEnum_HandCardCount))
{
//混乱扑克
BYTE cbRandCard[FULL_COUNT] = { 0 };
m_GameLogic.RandCard16List(cbRandCard, FULL_COUNT);
//用户扑克
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (m_bActiveUser[i])
{
m_cbHandCardCount[i] = MAX_COUNT;
CopyMemory(&m_cbHandCardData[i], &cbRandCard[i*m_cbHandCardCount[i]], sizeof(BYTE)*m_cbHandCardCount[i]);
}
}
}
else
{
BYTE cbRandCard[FULL_COUNT_15] = { 0 };
m_GameLogic.RandCard15List(cbRandCard, FULL_COUNT_15);
//用户扑克
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (m_bActiveUser[i])
{
m_cbHandCardCount[i] = MAX_COUNT - 1;
CopyMemory(&m_cbHandCardData[i], &cbRandCard[i*m_cbHandCardCount[i]], sizeof(BYTE)*m_cbHandCardCount[i]);
}
}
}
//构造变量
CMD_S_GameStart GameStart;
ZeroMemory(&GameStart, sizeof(CMD_S_GameStart));
GameStart.dwGameRule = pPrivateFrame->dwGameRule;
CopyMemory(GameStart.cbCardCount, m_cbHandCardCount, sizeof(BYTE)*GAME_PLAYER);
CopyMemory(GameStart.bActiveStatus, m_bActiveUser, sizeof(bool)*GAME_PLAYER);
//发送数据
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (m_bActiveUser[i] == false) continue;
//构造扑克
ASSERT(CountArray(GameStart.cbCardData) >= m_cbHandCardCount[i]);
CopyMemory(GameStart.cbCardData, m_cbHandCardData[i], sizeof(BYTE)*m_cbHandCardCount[i]);
m_pITableFrame->SendTableData(i, SUB_S_GAME_START, &GameStart, sizeof(GameStart));
m_pITableFrame->SendLookonData(i, SUB_S_GAME_START, &GameStart, sizeof(GameStart));
}
// 录像开始;
starGameRecord();
// 记录开始消息;
addGameRecordAction(SUB_S_GAME_START, &GameStart, sizeof(CMD_S_GameStart));
//排列扑克
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (!m_bActiveUser[i]) continue;
m_GameLogic.SortCardList(m_cbHandCardData[i], m_cbHandCardCount[i], ST_ORDER);
}
// 发牌定时器;
m_pITableFrame->SetGameTimer(IDI_SEND_CARD, IDT_SEND_CARD, 1, 0);
return true;
}
//游戏结束
bool CTableFrameSink::OnEventGameConclude(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason)
{
//删除超时定时器;
m_pITableFrame->KillGameTimer(IDI_USER_OUT_TIME);
switch (cbReason)
{
case GER_NORMAL: //常规结束
{
//变量定义
CMD_S_GameConclude GameConclude;
ZeroMemory(&GameConclude,sizeof(GameConclude));
//设置变量
GameConclude.lCellScore=m_pITableFrame->GetCellScore();
CopyMemory(GameConclude.bActiveStatus, m_bActiveUser, sizeof(m_bActiveUser));
//用户扑克
BYTE cbCardIndex=0;
for (WORD i=0;i<GAME_PLAYER;i++)
{
if (!m_bActiveUser[i]) continue;
//拷贝扑克
GameConclude.cbCardCount[i]=m_cbHandCardCount[i];
CopyMemory(&GameConclude.cbHandCardData[cbCardIndex],m_cbHandCardData[i],m_cbHandCardCount[i]*sizeof(BYTE));
//设置索引
cbCardIndex+=m_cbHandCardCount[i];
}
//积分变量
tagScoreInfo ScoreInfoArray[GAME_PLAYER];
ZeroMemory(&ScoreInfoArray,sizeof(ScoreInfoArray));
// 初始手牌数量;
BYTE cbInitHandCount = IsHasGameRule(ePDKRuleEnum_HandCardCount) ? NORMAL_COUNT : (NORMAL_COUNT - 1);
// 打独;
if (m_wBankerUser != INVALID_CHAIR)
{
SCORE lScore = cbInitHandCount * 2;
SCORE lBankScore = 0;
// 打独成功;
if (wChairID == m_wBankerUser)
{
//统计积分
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (!m_bActiveUser[i])continue;
if (i == m_wBankerUser) continue;
//计算积分
ScoreInfoArray[i].lScore = 0 - lScore;
ScoreInfoArray[i].cbType = (ScoreInfoArray[i].lScore >= 0L) ? SCORE_TYPE_WIN : SCORE_TYPE_LOSE;
lBankScore += lScore;
}
}
else
{
//统计积分
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (!m_bActiveUser[i])continue;
if (i == m_wBankerUser) continue;
// 统计炸弹分;
GetBombScore(i, m_cbHandCardData[i], m_cbHandCardCount[i]);
//计算积分
ScoreInfoArray[i].lScore = lScore;
ScoreInfoArray[i].cbType = (ScoreInfoArray[i].lScore >= 0L) ? SCORE_TYPE_WIN : SCORE_TYPE_LOSE;
lBankScore -= lScore;
}
// 统计炸弹分;
GetBombScore(m_wBankerUser, m_cbHandCardData[m_wBankerUser], m_cbHandCardCount[m_wBankerUser]);
}
//庄家得分;
ScoreInfoArray[m_wBankerUser].lScore = lBankScore;
ScoreInfoArray[m_wBankerUser].cbType = (lBankScore >= 0L) ? SCORE_TYPE_WIN : SCORE_TYPE_LOSE;
}
else
{
ASSERT(m_cbHandCardCount[wChairID] == 0);
// 赢分;
SCORE lWinScore = 0;
//统计积分
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (i == wChairID) continue;
if (!m_bActiveUser[i])continue;
SCORE lUserScore = 0;
// 两倍积分(关张);
if (m_cbHandCardCount[i] >= cbInitHandCount)
{
lUserScore = m_cbHandCardCount[i] * 2;
}
// 正常积分;
else if (m_cbHandCardCount[i] > 1)
{
lUserScore = m_cbHandCardCount[i];
}
else
{
lUserScore = 0;
}
//计算积分
ScoreInfoArray[i].lScore = 0 - lUserScore;
ScoreInfoArray[i].cbType = (ScoreInfoArray[i].lScore >= 0L) ? SCORE_TYPE_WIN : SCORE_TYPE_LOSE;
//统计胜利者得分;
lWinScore += lUserScore;
}
//统计胜利者得分
ScoreInfoArray[wChairID].lScore = lWinScore;
ScoreInfoArray[wChairID].cbType = (lWinScore >= 0L) ? SCORE_TYPE_WIN : SCORE_TYPE_LOSE;
}
//游戏积分
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (!m_bActiveUser[i]) continue;
GameConclude.lGameScore[i] = ScoreInfoArray[i].lScore; // 游戏得分;
GameConclude.lBombScore[i] = m_lBombScore[i]; // 炸弹得分;
GameConclude.lAllScore[i] = GameConclude.lGameScore[i] + m_lBombScore[i];// 总得分;
ScoreInfoArray[i].lScore = GameConclude.lAllScore[i];
}
//发送数据
m_pITableFrame->SendTableData(INVALID_CHAIR,SUB_S_GAME_CONCLUDE,&GameConclude,sizeof(GameConclude));
m_pITableFrame->SendLookonData(INVALID_CHAIR,SUB_S_GAME_CONCLUDE,&GameConclude,sizeof(GameConclude));
// 记录游戏结束消息;
addGameRecordAction(SUB_S_GAME_CONCLUDE, &GameConclude, sizeof(GameConclude));
/********************************私人场统计****************************************/
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] = GameConclude.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++)
{
if (!m_bActiveUser[i]) continue;
ScoreInfoArray[i].lGrade = lGrade;
}
}
//写入积分;
DataStream kDataStream;
m_kGameRecord.StreamValue(kDataStream, true);
m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray), kDataStream);
//上局胜利玩家,即下局第一个出牌玩家;
m_wFirstUser=wChairID;
//结束游戏
m_pITableFrame->ConcludeGame(GAME_SCENE_FREE);
return true;
}
case GER_DISMISS: //游戏解散
{
//变量定义
CMD_S_GameConclude GameConclude;
ZeroMemory(&GameConclude,sizeof(GameConclude));
CopyMemory(GameConclude.bActiveStatus, m_bActiveUser, sizeof(m_bActiveUser));
//用户扑克
BYTE cbCardIndex=0;
for (WORD i=0;i<GAME_PLAYER;i++)
{
if (!m_bActiveUser[i]) continue;
//拷贝扑克
GameConclude.cbCardCount[i]=m_cbHandCardCount[i];
CopyMemory(&GameConclude.cbHandCardData[cbCardIndex],m_cbHandCardData[i],m_cbHandCardCount[i]*sizeof(BYTE));
//设置索引
cbCardIndex+=m_cbHandCardCount[i];
// 统计炸弹分;
GetBombScore(i, m_cbHandCardData[i], m_cbHandCardCount[i]);
}
//积分变量
tagScoreInfo ScoreInfoArray[GAME_PLAYER];
ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray));
// 初始手牌数量;
BYTE cbInitHandCount = IsHasGameRule(ePDKRuleEnum_HandCardCount) ? NORMAL_COUNT : (NORMAL_COUNT - 1);
// 打独解散打独者胜利;
if (m_wBankerUser != INVALID_CHAIR)
{
SCORE lScore = cbInitHandCount * 2;
SCORE lBankScore = 0;
//统计积分
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (!m_bActiveUser[i])continue;
if (i == m_wBankerUser) continue;
//计算积分
ScoreInfoArray[i].lScore = 0 - lScore;
ScoreInfoArray[i].cbType = (ScoreInfoArray[i].lScore >= 0L) ? SCORE_TYPE_WIN : SCORE_TYPE_LOSE;
lBankScore += lScore;
}
//庄家得分;
ScoreInfoArray[m_wBankerUser].lScore = lBankScore;
ScoreInfoArray[m_wBankerUser].cbType = (lBankScore >= 0L) ? SCORE_TYPE_WIN : SCORE_TYPE_LOSE;
}
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (!m_bActiveUser[i]) continue;
//GameConclude.lGameScore[i] = 0; // 游戏得分;
GameConclude.lGameScore[i] = ScoreInfoArray[i].lScore; // 游戏得分;
GameConclude.lBombScore[i] = m_lBombScore[i]; // 炸弹得分;
GameConclude.lAllScore[i] = m_lBombScore[i] + GameConclude.lGameScore[i]; // 总得分;
ScoreInfoArray[i].lScore = GameConclude.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] = GameConclude.lAllScore[i];
}
}
// 完成局数
m_PrivateEndInfo.cbFinishCout = cbFinishCout + 1;
m_pITableFrame->addPrivatePlayCout(1);
/********************************私人场统计****************************************/
//发送信息
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_CONCLUDE, &GameConclude, sizeof(GameConclude));
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_CONCLUDE, &GameConclude, sizeof(GameConclude));
// 记录游戏结束消息;
addGameRecordAction(SUB_S_GAME_CONCLUDE, &GameConclude, sizeof(GameConclude));
//写入积分;
DataStream kDataStream;
m_kGameRecord.StreamValue(kDataStream, true);
m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray), kDataStream);
//结束游戏
m_pITableFrame->ConcludeGame(GAME_SCENE_FREE);
return true;
}
}
//错误断言
ASSERT(FALSE);
return false;
}
//发送场景
bool CTableFrameSink::OnEventSendGameScene(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbGameStatus, bool bSendSecret)
{
switch (cbGameStatus)
{
case GAME_SCENE_FREE: //空闲状态
{
//构造数据
CMD_S_StatusFree StatusFree;
ZeroMemory(&StatusFree,sizeof(StatusFree));
//自定规则
StatusFree.cbTimeOutCard=m_pGameCustomRule->cbTimeOutCard;
StatusFree.cbTimeCallScore=m_pGameCustomRule->cbTimeCallScore;
StatusFree.cbTimeStartGame=m_pGameCustomRule->cbTimeStartGame;
StatusFree.cbTimeHeadOutCard=m_pGameCustomRule->cbTimeHeadOutCard;
//发送场景
return m_pITableFrame->SendGameScene(pIServerUserItem,&StatusFree,sizeof(StatusFree));
}
case GAME_SCENE_SEND:
{
//构造数据
CMD_S_StatusSend StatusSend;
ZeroMemory(&StatusSend, sizeof(StatusSend));
//自定规则
StatusSend.cbTimeOutCard = m_pGameCustomRule->cbTimeOutCard;
StatusSend.cbTimeCallScore = m_pGameCustomRule->cbTimeCallScore;
StatusSend.cbTimeStartGame = m_pGameCustomRule->cbTimeStartGame;
StatusSend.cbTimeHeadOutCard = m_pGameCustomRule->cbTimeHeadOutCard;
const tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
ASSERT(nullptr != pPrivateFrame);
StatusSend.dwGameRule = pPrivateFrame->dwGameRule;
CopyMemory(StatusSend.bActiveStatus, m_bActiveUser, sizeof(bool)*GAME_PLAYER);
//游戏信息
CopyMemory(StatusSend.cbHandCardCount, m_cbHandCardCount, sizeof(BYTE)*GAME_PLAYER);
CopyMemory(StatusSend.cbHandCardData, m_cbHandCardData[wChairID], m_cbHandCardCount[wChairID] * sizeof(BYTE));
//发送场景
bool bSendResult = m_pITableFrame->SendGameScene(pIServerUserItem, &StatusSend, sizeof(StatusSend));
return bSendResult;
}
case GAME_SCENE_CALL: //叫分状态
{
//构造数据
CMD_S_StatusCall StatusCall;
ZeroMemory(&StatusCall,sizeof(StatusCall));
//自定规则
StatusCall.cbTimeOutCard=m_pGameCustomRule->cbTimeOutCard;
StatusCall.cbTimeCallScore=m_pGameCustomRule->cbTimeCallScore;
StatusCall.cbTimeStartGame=m_pGameCustomRule->cbTimeStartGame;
StatusCall.cbTimeHeadOutCard=m_pGameCustomRule->cbTimeHeadOutCard;
const tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
ASSERT(nullptr != pPrivateFrame);
StatusCall.dwGameRule = pPrivateFrame->dwGameRule;
CopyMemory(StatusCall.bActiveStatus, m_bActiveUser, sizeof(m_bActiveUser));
StatusCall.wCurrentUser = m_wCurrentUser;
StatusCall.cbMustOutCard = m_cbMustOutCardData;
//游戏信息
CopyMemory(StatusCall.bScoreInfo,m_bScoreInfo,sizeof(m_bScoreInfo));
CopyMemory(StatusCall.bScoreActive, m_bScoreActive, sizeof(m_bScoreActive));
CopyMemory(StatusCall.cbHandCardCount, m_cbHandCardCount, sizeof(m_cbHandCardCount));
CopyMemory(StatusCall.cbHandCardData,m_cbHandCardData[wChairID],m_cbHandCardCount[wChairID]*sizeof(BYTE));
//发送场景
bool bSendResult = m_pITableFrame->SendGameScene(pIServerUserItem,&StatusCall,sizeof(StatusCall));
return bSendResult;
}
case GAME_SCENE_PLAY: //游戏状态
{
//构造数据
CMD_S_StatusPlay StatusPlay;
ZeroMemory(&StatusPlay,sizeof(StatusPlay));
//游戏变量
StatusPlay.wBankerUser=m_wBankerUser;
StatusPlay.wCurrentUser=m_wCurrentUser;
StatusPlay.cbMustOutCard = m_cbMustOutCardData;
//自定规则
StatusPlay.cbTimeOutCard=m_pGameCustomRule->cbTimeOutCard;
StatusPlay.cbTimeCallScore=m_pGameCustomRule->cbTimeCallScore;
StatusPlay.cbTimeStartGame=m_pGameCustomRule->cbTimeStartGame;
StatusPlay.cbTimeHeadOutCard=m_pGameCustomRule->cbTimeHeadOutCard;
const tagPrivateFrameParameter* pPrivateFrame = m_pITableFrame->GetPrivateFrameInfo();
ASSERT(nullptr != pPrivateFrame);
StatusPlay.dwGameRule = pPrivateFrame->dwGameRule;
CopyMemory(StatusPlay.bActiveStatus, m_bActiveUser, sizeof(m_bActiveUser));
//出牌信息
StatusPlay.wTurnWiner=m_wTurnWiner;
StatusPlay.cbTurnCardCount=m_cbTurnCardCount;
CopyMemory(StatusPlay.cbTurnCardData,m_cbTurnCardData,m_cbTurnCardCount*sizeof(BYTE));
//扑克信息
CopyMemory(StatusPlay.cbHandCardCount,m_cbHandCardCount,sizeof(m_cbHandCardCount));
CopyMemory(StatusPlay.cbHandCardData,m_cbHandCardData[wChairID],sizeof(BYTE)*m_cbHandCardCount[wChairID]);
//发送场景
bool bSendResult = m_pITableFrame->SendGameScene(pIServerUserItem,&StatusPlay,sizeof(StatusPlay));
return bSendResult;
}
}
//错误断言
ASSERT(FALSE);
return false;
}
//时间事件
bool CTableFrameSink::OnTimerMessage(DWORD wTimerID, WPARAM wBindParam)
{
if (wTimerID == IDI_SEND_CARD)
{
m_pITableFrame->KillGameTimer(IDI_SEND_CARD);
// 获取出牌玩家;
WORD wCurrentUser = INVALID_CHAIR;
m_cbMustOutCardData = 0x0;
// 红桃三出牌;
if (IsHasGameRule(ePDKRuleEnum_OutCardRule) || (INVALID_CHAIR == m_wFirstUser))
{
// 比出牌;
static BYTE g_MustOutCard[MAX_MUSTCARD_COUT] = { 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D };
for (WORD k = 0; k < MAX_MUSTCARD_COUT; k++)
{
BYTE cbMustOutCard = g_MustOutCard[k];
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (m_bActiveUser[i] == false) continue;
for (BYTE j = 0; j < m_cbHandCardCount[i]; j++)
{
if (m_cbHandCardData[i][j] == cbMustOutCard)
{
wCurrentUser = i;
m_cbMustOutCardData = cbMustOutCard;
break;
}
}
// 已经找到出牌玩家;
if (wCurrentUser != INVALID_CHAIR && m_cbMustOutCardData != 0x0) break;
}
// 已经找到出牌玩家;
if (wCurrentUser != INVALID_CHAIR && m_cbMustOutCardData != 0x0) break;
}
// 2个玩家手里都没红桃3;
if (wCurrentUser == INVALID_CHAIR && 0x0 == m_cbMustOutCardData)
{
RepositionSink();
OnEventGameStart();
return true;
}
}
else
{
wCurrentUser = m_wFirstUser;
}
// 必须有当前玩家;
ASSERT(INVALID_CHAIR != wCurrentUser);
if (INVALID_CHAIR != wCurrentUser)
{
//设置用户
m_wFirstUser = wCurrentUser;
m_wCurrentUser = wCurrentUser;
// 打独;
if (IsHasGameRule(ePDKRuleEnum_DADU))
{
//设置状态
m_pITableFrame->SetGameStatus(GAME_SCENE_CALL);
//发送消息;
CMD_S_SendCallScore SendCallScore;
ZeroMemory(&SendCallScore, sizeof(CMD_S_SendCallScore));
SendCallScore.wBankerUser = m_wCurrentUser;
SendCallScore.cbMustOutCard = m_cbMustOutCardData;
//发送数据
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_START_SCORE, &SendCallScore, sizeof(SendCallScore));
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_START_SCORE, &SendCallScore, sizeof(SendCallScore));
}
else
{
//设置状态;
m_pITableFrame->SetGameStatus(GAME_SCENE_PLAY);
//发送消息;
CMD_S_BankerInfo BankerInfo;
ZeroMemory(&BankerInfo, sizeof(CMD_S_BankerInfo));
BankerInfo.wBankerUser = INVALID_CHAIR;
BankerInfo.wCurrentUser = m_wCurrentUser;
BankerInfo.bShowMustOutCard = true;
BankerInfo.cbMustOutCard = m_cbMustOutCardData;
//发送数据
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_BANKER_INFO, &BankerInfo, sizeof(BankerInfo));
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_BANKER_INFO, &BankerInfo, sizeof(BankerInfo));
}
}
return true;
}
else if (wTimerID == IDI_OUT_CARD)
{
m_pITableFrame->KillGameTimer(IDI_OUT_CARD);
//状态效验;
ASSERT(m_pITableFrame->GetGameStatus() == GAME_SCENE_PLAY);
if (m_pITableFrame->GetGameStatus() != GAME_SCENE_PLAY) return true;
//当前玩家校验;
ASSERT(m_wCurrentUser < GAME_PLAYER && m_wCurrentUser >= 0);
if (m_wCurrentUser > GAME_PLAYER || m_wCurrentUser < 0) return true;
//用户效验;
IServerUserItem* pServerUserItem = m_pITableFrame->GetTableUserItem(m_wCurrentUser);
ASSERT(pServerUserItem != nullptr && pServerUserItem->GetUserStatus() == US_PLAYING);
if (pServerUserItem && pServerUserItem->GetUserStatus() != US_PLAYING) return true;
if (m_bActiveUser[m_wCurrentUser] == false) return true;
//if (m_cbHandCardCount[m_wCurrentUser] != 1) return true;
// 只有一张手牌;
if (m_cbHandCardCount[m_wCurrentUser] == 1)
{
BYTE cbCardData[MAX_COUNT] = { 0 };
BYTE cbCardCount = 0;
for (BYTE i = 0; i < m_cbHandCardCount[m_wCurrentUser]; i++)
{
if (m_cbHandCardData[m_wCurrentUser][i] == 0) break;
cbCardData[cbCardCount++] = m_cbHandCardData[m_wCurrentUser][i];
}
// 1. 轮到自己出牌;
if (m_cbTurnCardCount == 0)
{
return OnUserOutCard(m_wCurrentUser, cbCardData, cbCardCount);
}
// 2. 押上家牌;
else
{
//对比扑克
if (m_GameLogic.CompareCard(m_cbTurnCardData, cbCardData, m_cbTurnCardCount, cbCardCount, true))
{
return OnUserOutCard(m_wCurrentUser, cbCardData, cbCardCount);
}
else
{
return OnUserPassCard(m_wCurrentUser);
}
}
}
else
{
//搜索出牌;
tagSearchCardResult mCardResult;
BYTE cbResultCount = m_GameLogic.SearchOutCard(m_cbHandCardData[m_wCurrentUser], m_cbHandCardCount[m_wCurrentUser],
m_cbTurnCardData, m_cbTurnCardCount, &mCardResult);
// 没有大过的牌;
if (cbResultCount <= 0)
{
OnUserPassCard(m_wCurrentUser);
}
}
return true;
}
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 * pData, WORD wDataSize, IServerUserItem * pIServerUserItem)
{
m_cbWaitTime=0;
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);
if (m_pITableFrame->GetGameStatus()!=GAME_SCENE_CALL) return true;
//用户效验
ASSERT(pIServerUserItem->GetUserStatus()==US_PLAYING);
if (pIServerUserItem->GetUserStatus()!=US_PLAYING) return true;
//变量定义
CMD_C_CallScore * pCallScore=(CMD_C_CallScore *)pData;
//消息处理
WORD wChairID=pIServerUserItem->GetChairID();
return OnUserCallScore(wChairID,pCallScore->bCallScore);
}
case SUB_C_OUT_CARD: //用户出牌
{
//变量定义
CMD_C_OutCard * pOutCard=(CMD_C_OutCard *)pData;
WORD wHeadSize=sizeof(CMD_C_OutCard)-sizeof(pOutCard->cbCardData);
//效验数据
ASSERT((wDataSize>=wHeadSize)&&(wDataSize==(wHeadSize+pOutCard->cbCardCount*sizeof(BYTE))));
if ((wDataSize<wHeadSize)||(wDataSize!=(wHeadSize+pOutCard->cbCardCount*sizeof(BYTE)))) return false;
//状态效验
ASSERT(m_pITableFrame->GetGameStatus()==GAME_SCENE_PLAY);
if (m_pITableFrame->GetGameStatus()!=GAME_SCENE_PLAY) return true;
//用户效验
ASSERT(pIServerUserItem->GetUserStatus()==US_PLAYING);
if (pIServerUserItem->GetUserStatus()!=US_PLAYING) return true;
//消息处理
WORD wChairID=pIServerUserItem->GetChairID();
return OnUserOutCard(wChairID,pOutCard->cbCardData,pOutCard->cbCardCount);
}
case SUB_C_PASS_CARD: //用户放弃
{
//状态效验
ASSERT(m_pITableFrame->GetGameStatus()==GAME_SCENE_PLAY);
if (m_pITableFrame->GetGameStatus()!=GAME_SCENE_PLAY) return true;
//用户效验
ASSERT(pIServerUserItem->GetUserStatus()==US_PLAYING);
if (pIServerUserItem->GetUserStatus()!=US_PLAYING) return true;
//消息处理
return OnUserPassCard(pIServerUserItem->GetChairID());
}
//case SUB_C_TRUSTEE:
// {
// //效验数据
// ASSERT(wDataSize==sizeof(CMD_C_TRUSTEE));
// if (wDataSize!=sizeof(CMD_C_TRUSTEE)) return false;
// CMD_C_TRUSTEE* pCTrustee = (CMD_C_TRUSTEE*)pData;
// WORD wChairID = pIServerUserItem->GetChairID();
// if (!pCTrustee->bTrustee)
// {
// m_aryOverTime[wChairID] = 0;
// }
// return OnUserTrustee(wChairID, pCTrustee->bTrustee);
// }
}
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));
m_wFirstUser = INVALID_CHAIR;
}
//获得私人场结束信息流
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;
}
// 真实椅子数量
WORD CTableFrameSink::GetRealChairCount()
{
if (IsHasGameRule(ePDKRuleEnum_PlayCount))
{
return GAME_PLAYER;
}
return GAME_PLAYER_2;
}
bool CTableFrameSink::IsHasGameRule(ePDKRuleEnum 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;
}
//用户断线
bool CTableFrameSink::OnActionUserOffLine(WORD wChairID, IServerUserItem * pIServerUserItem)
{
if(m_bOffLineTrustee && wChairID == m_wCurrentUser)
{
//IsOfflineTrustee();
}
return true;
}
//用户重入
bool CTableFrameSink::OnActionUserConnect(WORD wChairID, IServerUserItem * pIServerUserItem)
{
if(m_bOffLineTrustee)
{
if (((m_pGameServiceOption->wServerType&GAME_GENRE_MATCH)!=0)&&(pIServerUserItem->GetChairID()==m_wCurrentUser))
{
m_pITableFrame->KillGameTimer(IDI_USER_OUT_TIME);
}
}
return true;
}
//用户坐下
bool CTableFrameSink::OnActionUserSitDown(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
{
//历史积分
if (bLookonUser==false)
{
ASSERT(wChairID!=INVALID_CHAIR);
m_HistoryScore.OnEventUserEnter(wChairID);
}
return true;
}
//用户起立
bool CTableFrameSink::OnActionUserStandUp(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
{
//历史积分
if (bLookonUser==false)
{
ASSERT(wChairID!=INVALID_CHAIR);
m_HistoryScore.OnEventUserLeave(wChairID);
}
m_bUserTrustee[wChairID] = false;
return true;
}
//用户托管;
bool CTableFrameSink::OnUserTrustee(WORD wChairID, bool bTrustee)
{
CMD_S_TRUSTEE pSTrustee;
pSTrustee.wTrusteeUser = wChairID;
pSTrustee.bTrustee = bTrustee;
m_bUserTrustee[wChairID] = bTrustee;
m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_TRUSTEE, &pSTrustee, sizeof(CMD_S_TRUSTEE));
m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_TRUSTEE, &pSTrustee, sizeof(CMD_S_TRUSTEE));
return true;
}
//用户放弃
bool CTableFrameSink::OnUserPassCard(WORD wChairID)
{
//效验状态
ASSERT((wChairID==m_wCurrentUser)&&(m_cbTurnCardCount!=0));
if ((wChairID!=m_wCurrentUser)||(m_cbTurnCardCount==0)) return true;
// 有牌必押, 有没有可以押到的牌;
if (IsHasGameRule(ePDKRuleEnum_MustOutCard) && (m_cbTurnCardCount > 0))
{
//搜索出牌;
tagSearchCardResult mCardResult;
BYTE cbResultCount = m_GameLogic.SearchOutCard(m_cbHandCardData[wChairID], m_cbHandCardCount[wChairID],
m_cbTurnCardData, m_cbTurnCardCount, &mCardResult);
if (cbResultCount > 0)
{
return true;
}
}
m_pITableFrame->KillGameTimer(IDI_OUT_CARD);
//设置变量
m_wCurrentUser = getNextChairID(m_wCurrentUser);
// 一轮出牌结束;
if (m_wCurrentUser == m_wTurnWiner)
{
// 炸弹类型;
BYTE cbCardType = m_GameLogic.GetCardType(m_cbTurnCardData, m_cbTurnCardCount, false);
if (cbCardType >= CT_BOMB_CARD)
{
CalcBombScore(m_wTurnWiner);
}
m_cbTurnCardCount = 0;
}
//构造消息
CMD_S_PassCard PassCard;
PassCard.wPassCardUser=wChairID;
PassCard.wCurrentUser=m_wCurrentUser;
PassCard.cbTurnOver=(m_cbTurnCardCount==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(PassCard));
// 当前玩家只有一张牌的时候,自动操作;
if (m_cbHandCardCount[m_wCurrentUser] == 1)
{
m_pITableFrame->SetGameTimer(IDI_OUT_CARD, IDT_OUT_CARD, 1, 0);
}
return true;
}
//用户叫分
bool CTableFrameSink::OnUserCallScore(WORD wChairID, bool bCallScore)
{
//效验状态
ASSERT(m_bScoreActive[wChairID] == FALSE);
if (m_bScoreActive[wChairID]) return true;
//设置叫分
m_bScoreInfo[wChairID] = bCallScore;
m_bScoreActive[wChairID] = true;
// 统计叫分人数;
if (bCallScore) m_cbCallScoreCount++;
//构造变量
CMD_S_CallScore CallScore;
CallScore.wCallScoreUser=wChairID;
CallScore.bCurrentScore = bCallScore;
//发送消息
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));
bool bStartGame = true;
// 是否还有人没操作;
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (m_bActiveUser[i] == FALSE) continue;
// 还有人没操作;
if (m_bScoreActive[i] == false)
{
bStartGame = false;
break;
}
}
//开始判断
if (bStartGame)
{
// 两个人叫分;
if (m_cbCallScoreCount > 1)
{
WORD wRandUser = rand() % GAME_PLAYER;
for (WORD i = 0; i < GAME_PLAYER; i++)
{
// 位置转换;
WORD j = (wRandUser + i) % GAME_PLAYER;
if (m_bActiveUser[j] == FALSE) continue;
// 叫了分;
if (m_bScoreInfo[j])
{
m_wBankerUser = j;
m_wCurrentUser = m_wBankerUser;
break;
}
}
}
// 一个人叫分;
else if (m_cbCallScoreCount == 1)
{
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (m_bActiveUser[i] == FALSE) continue;
// 叫了分;
if (m_bScoreInfo[i])
{
m_wBankerUser = i;
m_wCurrentUser = m_wBankerUser;
break;
}
}
}
// 没人叫分;
else
{
m_wBankerUser = INVALID_CHAIR;
}
//设置状态
m_pITableFrame->SetGameStatus(GAME_SCENE_PLAY);
//设置用户
m_wTurnWiner = m_wCurrentUser;
// 有人打独不存在必打牌;
if (m_wBankerUser != INVALID_CHAIR)
{
m_cbMustOutCardData = 0x0;
}
//发送消息
CMD_S_BankerInfo BankerInfo;
ZeroMemory(&BankerInfo, sizeof(BankerInfo));
BankerInfo.wBankerUser = m_wBankerUser;
BankerInfo.wCurrentUser = m_wCurrentUser;
BankerInfo.bShowMustOutCard = false;
BankerInfo.cbMustOutCard = m_cbMustOutCardData;
//发送消息
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, BYTE cbCardData[], BYTE cbCardCount)
{
//效验状态
ASSERT(wChairID==m_wCurrentUser);
if (wChairID!=m_wCurrentUser) return true;
// 是否是最后一手牌;
bool isLastCard = (cbCardCount == m_cbHandCardCount[wChairID]);
BYTE cbCardType = m_GameLogic.GetCardType(cbCardData, cbCardCount, isLastCard);
//类型判断
if (cbCardType==CT_ERROR)
{
ASSERT(FALSE);
return false;
}
//出牌判断
if (m_cbTurnCardCount!=0)
{
//对比扑克
if (m_GameLogic.CompareCard(m_cbTurnCardData,cbCardData,m_cbTurnCardCount,cbCardCount, isLastCard)==false)
{
ASSERT(FALSE);
return false;
}
}
// 是否需要出红桃3;
if (m_cbMustOutCardData != 0x0 && !m_GameLogic.SearchMustOutCard(cbCardData, cbCardCount, m_cbMustOutCardData))
{
return false;
}
//下家剩余一张牌的情况下,出单牌必须是手牌最大的一张;
WORD wNextChairID = getNextChairID(m_wCurrentUser);
if (cbCardType == CT_SINGLE && (m_cbHandCardCount[wNextChairID] == 1))
{
if (m_GameLogic.GetCardLogicValue(cbCardData[0]) != m_GameLogic.GetMaxLogicValue(m_cbHandCardData[wChairID], m_cbHandCardCount[wChairID]))
{
return false;
}
}
//删除扑克
if (m_GameLogic.RemoveCardList(cbCardData,cbCardCount,m_cbHandCardData[wChairID],m_cbHandCardCount[wChairID])==false)
{
ASSERT(FALSE);
return false;
}
m_pITableFrame->KillGameTimer(IDI_OUT_CARD);
//出牌变量
m_cbOutCardCount[wChairID]++;
// 只第一次出牌有效;
if (m_cbMustOutCardData != 0x0) m_cbMustOutCardData = 0x0;
//设置变量
m_cbTurnCardCount = cbCardCount;
m_cbHandCardCount[wChairID] -= cbCardCount;
CopyMemory(m_cbTurnCardData, cbCardData, sizeof(BYTE)*cbCardCount);
//切换用户
m_wTurnWiner = wChairID;
// 打独失败;
if (IsHasGameRule(ePDKRuleEnum_DADU) && (m_wBankerUser != INVALID_CHAIR) && (wChairID != m_wBankerUser))
{
m_wCurrentUser = INVALID_CHAIR;
}
else
{
if (m_cbHandCardCount[wChairID] != 0)
{
if (cbCardType != CT_3A_BOMB_CARD)
{
m_wCurrentUser = getNextChairID(m_wCurrentUser);
}
}
else
{
m_wCurrentUser = INVALID_CHAIR;
}
}
//构造数据
CMD_S_OutCard OutCard;
ZeroMemory(&OutCard, sizeof(CMD_S_OutCard));
OutCard.wOutCardUser=wChairID;
OutCard.cbCardCount=cbCardCount;
OutCard.wCurrentUser=m_wCurrentUser;
OutCard.bLastCard = isLastCard;
CopyMemory(OutCard.cbCardData,m_cbTurnCardData,m_cbTurnCardCount*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 (cbCardType == CT_3A_BOMB_CARD)
{
m_cbTurnCardCount = 0;
if (m_wCurrentUser == wChairID)
{
CalcBombScore(wChairID);
}
}
//结束判断
if (m_wCurrentUser == INVALID_CHAIR)
{
// 炸弹类型;
if (cbCardType >= CT_BOMB_CARD)
{
CalcBombScore(wChairID);
}
OnEventGameConclude(wChairID, NULL, GER_NORMAL);
}
else
{
// 当前玩家只有一张牌的时候,自动操作;
if (m_cbHandCardCount[m_wCurrentUser] == 1)
{
m_pITableFrame->SetGameTimer(IDI_OUT_CARD, IDT_OUT_CARD, 1, 0);
}
else
{
// 有牌必押, 有没有可以押到的牌;
if (m_cbTurnCardCount > 0)
{
//搜索出牌;
tagSearchCardResult mCardResult;
BYTE cbResultCount = m_GameLogic.SearchOutCard(m_cbHandCardData[m_wCurrentUser], m_cbHandCardCount[m_wCurrentUser],
m_cbTurnCardData, m_cbTurnCardCount, &mCardResult);
// 没有大过的牌;
if (cbResultCount <= 0)
{
m_pITableFrame->SetGameTimer(IDI_OUT_CARD, IDT_OUT_CARD, 1, 0);
}
}
}
}
return true;
}
//设置基数
void CTableFrameSink::SetGameBaseScore(LONG lBaseScore)
{
//发送数据
m_pITableFrame->SendTableData(INVALID_CHAIR,SUB_S_SET_BASESCORE,&lBaseScore,sizeof(lBaseScore));
m_pITableFrame->SendLookonData(INVALID_CHAIR,SUB_S_SET_BASESCORE,&lBaseScore,sizeof(lBaseScore));
}
// 计算炸弹分;
void CTableFrameSink::CalcBombScore(WORD wChairID)
{
// 校验椅子号;
ASSERT((wChairID >= 0) && (wChairID < GAME_PLAYER));
if (wChairID < 0 || wChairID >= GAME_PLAYER) return;
if (!IsHasGameRule(ePDKRuleEnum_Bomb_Score)) return;
for (WORD i = 0; i < GAME_PLAYER; i++)
{
if (i == wChairID) continue;
if (!m_bActiveUser[i]) continue;
m_lBombScore[i] -= 10;
m_lBombScore[wChairID] += 10;
}
}
void CTableFrameSink::GetBombScore(WORD wChairID, BYTE cbHandCardData[], BYTE cbHandCardCount)
{
if (!IsHasGameRule(ePDKRuleEnum_Bomb_Score)) return;
if (cbHandCardCount <= 0) return;
// 大小排序;
m_GameLogic.SortCardList(cbHandCardData, cbHandCardCount, ST_ORDER);
//分析扑克
tagAnalyseResult AnalyseResult;
ZeroMemory(&AnalyseResult, sizeof(AnalyseResult));
m_GameLogic.AnalysebCardData(cbHandCardData, cbHandCardCount, AnalyseResult);
// 3个A
if (IsHasGameRule(ePDKRuleEnum_3ABomb) && AnalyseResult.cbBlockCount[2] > 0)
{
BYTE cbACardValue = m_GameLogic.GetCardLogicValue(0x01);
for (BYTE j = 0; j < AnalyseResult.cbBlockCount[2]; j++)
{
ASSERT((j * 3) < MAX_COUNT);
BYTE cbCardData = AnalyseResult.cbCardData[2][j * 3];
BYTE cbCardValue = m_GameLogic.GetCardLogicValue(cbCardData);
// 是不是A
if (cbCardValue == cbACardValue)
{
// 统计炸弹;
CalcBombScore(wChairID);
break;
}
}
}
// 四张炸弹;
if (AnalyseResult.cbBlockCount[3] > 0)
{
for (BYTE j = 0; j < AnalyseResult.cbBlockCount[3]; j++)
{
ASSERT((j * 4) < MAX_COUNT);
BYTE cbCardData = AnalyseResult.cbCardData[3][j * 4];
if (m_GameLogic.IsValidCard(cbCardData))
{
// 统计炸弹;
CalcBombScore(wChairID);
}
}
}
}
// 获取下家椅子号;
WORD CTableFrameSink::getNextChairID(WORD wChairID)
{
//下家剩余一张牌的情况下,出单牌必须是手牌最大的一张;
WORD wNextChairID = (wChairID + 1) % GAME_PLAYER;
// 如果当前玩家为空,继续下一个玩家(一共3个位置最少2个人打牌不可能存在连续两个为空只判断一次就好了);
if (!m_bActiveUser[wNextChairID])
{
wNextChairID = (wNextChairID + 1) % GAME_PLAYER;
}
return wNextChairID;
}
/////////////////////////////// 游戏录像 ///////////////////////////////////////////
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);
if (pUserItem == nullptr) continue;
tagUserInfo* pUserInfo = pUserItem->GetUserInfo();
if (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 < NORMAL_COUNT; j++)
{
kReocrdPlayer.cbCardData.push_back(m_cbHandCardData[i][j]);
}
m_kGameRecord.playersVec.push_back(kReocrdPlayer);
}
}
//////////////////////////////////////////////////////////////////////////