#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(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= 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= 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 ((wDataSizecbCardCount*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); } } //////////////////////////////////////////////////////////////////////////