诸暨麻将添加redis
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 
 

4279 righe
141 KiB

  1. #include "StdAfx.h"
  2. #include "TableFrameSink_tdh.h"
  3. #include <algorithm>
  4. #include "../俱乐部/Source/MessageDef/Pb_SparrowMaJiang.pb.h"
  5. #include "../俱乐部/Source/MessageDef/Pb_RecordPacket.pb.h"
  6. //#include "../俱乐部/Source/GlobalDef/Util.h"
  7. //构造函数
  8. CTableFrameSink_tdh::CTableFrameSink_tdh() :m_GameLogic(this)
  9. {
  10. //游戏变量
  11. m_startTime = 0;
  12. mPlayGameUserCount = 4;
  13. m_lSiceCount = 0;
  14. m_wBankerUser = INVALID_CHAIR;
  15. ZeroMemory(m_cbCardIndex, sizeof(m_cbCardIndex));
  16. ZeroMemory(m_bTrustee, sizeof(m_bTrustee));
  17. ZeroMemory(m_PaiQuan, sizeof(m_PaiQuan));
  18. ZeroMemory(m_bPlayStatus, sizeof(m_bPlayStatus));
  19. ZeroMemory(m_lGameScore, sizeof(m_lGameScore));
  20. ZeroMemory(m_lGameTatolScore, sizeof(m_lGameTatolScore));
  21. ZeroMemory(m_HuPai, sizeof(m_HuPai));
  22. ZeroMemory(m_TabbOutCardCout, sizeof(m_TabbOutCardCout)); //可以打出的牌就听牌的个数
  23. ZeroMemory(m_TabbOutCardData, sizeof(m_TabbOutCardData)); //具体打哪几张牌
  24. ZeroMemory(m_TabbTingCardCount, sizeof(m_TabbTingCardCount)); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  25. ZeroMemory(m_TabbTingCardData, sizeof(m_TabbTingCardData)); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  26. //出牌信息
  27. m_cbOutCardData = 0;
  28. m_cbOutCardCount = 0;
  29. m_wOutCardUser = INVALID_CHAIR;
  30. ZeroMemory(m_cbDiscardCard, sizeof(m_cbDiscardCard));
  31. ZeroMemory(m_cbDiscardCount, sizeof(m_cbDiscardCount));
  32. ZeroMemory(m_cbLastDisCardData, sizeof(m_cbLastDisCardData));
  33. ZeroMemory(m_cbLastDisCount, sizeof(m_cbLastDisCount));
  34. ZeroMemory(LianXuHuPai, sizeof(LianXuHuPai));
  35. //发牌信息
  36. m_cbSendCardData = 0;
  37. m_cbSendCardCount = 0;
  38. m_cbLeftCardCount = 0;
  39. m_cbShiJiLeftCardCount = 0;
  40. ZeroMemory(m_cbRepertoryCard, sizeof(m_cbRepertoryCard));
  41. m_cbGangCount = 0;//打了几个杠
  42. //运行变量
  43. m_cbProvideCard = 0;
  44. m_wResumeUser = INVALID_CHAIR;
  45. m_wCurrentUser = INVALID_CHAIR;
  46. m_wProvideUser = INVALID_CHAIR;
  47. //状态变量
  48. //m_bSendStatus=false;
  49. //m_bGangStatus = false;
  50. m_GangPrivedUserID = -1;
  51. m_bGangOption = 0;
  52. //m_OutLastLaiZiData = 0; //最后杠牌数据,断线重连用的着
  53. m_bQiangGang = false;
  54. //用户状态
  55. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  56. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  57. ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard));
  58. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  59. ZeroMemory(m_cbOperateCaiCard, sizeof(m_cbOperateCaiCard));
  60. //组合扑克
  61. ZeroMemory(m_WeaveItemArray, sizeof(m_WeaveItemArray));
  62. ZeroMemory(m_cbWeaveItemCount, sizeof(m_cbWeaveItemCount));
  63. //结束信息
  64. ZeroMemory(m_HuPai, sizeof(m_HuPai));
  65. ZeroMemory(m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui));
  66. //组件变量
  67. m_pITableFrame = NULL;
  68. m_pGameServiceOption = NULL;
  69. bIsHuang = false;
  70. mMaxTaiNum = 5;
  71. ZeroMemory(m_cbOptCard, sizeof(m_cbOptCard));
  72. m_cbLastGangCard = 0;
  73. ZeroMemory(m_bUsersGangStatus, GAME_PLAYER);
  74. m_bTwoPlayerFlag = false;
  75. return;
  76. }
  77. //析构函数
  78. CTableFrameSink_tdh::~CTableFrameSink_tdh(void)
  79. {
  80. }
  81. //接口查询
  82. void * CTableFrameSink_tdh::QueryInterface(const IID & Guid, DWORD dwQueryVer)
  83. {
  84. // QUERYINTERFACE(ITableFrameSink, Guid, dwQueryVer);
  85. // QUERYINTERFACE(ITableUserAction, Guid, dwQueryVer);
  86. // QUERYINTERFACE_IUNKNOWNEX(ITableFrameSink, Guid, dwQueryVer);
  87. if ((Guid == IID_ITableFrameSink) && (InterfaceVersionCompare(dwQueryVer, VER_ITableFrameSinkOther)))
  88. return static_cast<ITableFrameSink *>(this);
  89. QUERYINTERFACE(ITableUserAction, Guid, dwQueryVer);
  90. if ((Guid == IID_IUnknownEx) && (InterfaceVersionCompare(dwQueryVer, VER_IUnknownEx)))
  91. return static_cast<IUnknownEx *>(static_cast<ITableFrameSink *>(this));
  92. return NULL;
  93. }
  94. //初始化
  95. bool CTableFrameSink_tdh::Initialization(IUnknownEx * pIUnknownEx)
  96. {
  97. //查询接口
  98. ASSERT(pIUnknownEx != NULL);
  99. m_pITableFrame = QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx, ITableFrame);
  100. if (m_pITableFrame == NULL)
  101. return false;
  102. //获取参数
  103. m_pGameServiceOption = m_pITableFrame->GetGameServiceOption();
  104. ASSERT(m_pGameServiceOption != NULL);
  105. //开始模式
  106. m_pITableFrame->SetStartMode(START_MODE_FULL_READY);
  107. return true;
  108. }
  109. //复位桌子
  110. VOID CTableFrameSink_tdh::RepositionSink()
  111. {
  112. //游戏变量
  113. m_startTime = 0;
  114. ZeroMemory(m_PaiQuan, sizeof(m_PaiQuan));
  115. ZeroMemory(m_cbCardIndex, sizeof(m_cbCardIndex));
  116. ZeroMemory(m_bTrustee, sizeof(m_bTrustee));
  117. //ZeroMemory( m_cbGenCount,sizeof(m_cbGenCount) );
  118. ZeroMemory(m_bPlayStatus, sizeof(m_bPlayStatus));
  119. //m_cbWinCount = 0;
  120. //memset( m_wWinOrder,INVALID_CHAIR,sizeof(m_wWinOrder) );
  121. //ZeroMemory( m_lGameTax,sizeof(m_lGameTax) );
  122. ZeroMemory(m_PaiQuan, sizeof(m_PaiQuan));
  123. ZeroMemory(m_TabbOutCardCout, sizeof(m_TabbOutCardCout)); //可以打出的牌就听牌的个数
  124. ZeroMemory(m_TabbOutCardData, sizeof(m_TabbOutCardData)); //具体打哪几张牌
  125. ZeroMemory(m_TabbTingCardCount, sizeof(m_TabbTingCardCount)); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  126. ZeroMemory(m_TabbTingCardData, sizeof(m_TabbTingCardData)); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  127. //出牌信息
  128. m_cbOutCardData = 0;
  129. m_cbOutCardCount = 0;
  130. m_wOutCardUser = INVALID_CHAIR;
  131. ZeroMemory(m_cbDiscardCard, sizeof(m_cbDiscardCard));
  132. ZeroMemory(m_cbDiscardCount, sizeof(m_cbDiscardCount));
  133. ZeroMemory(m_cbLastDisCardData, sizeof(m_cbLastDisCardData));
  134. ZeroMemory(m_cbLastDisCount, sizeof(m_cbLastDisCount));
  135. //发牌信息
  136. m_cbSendCardData = 0;
  137. m_cbSendCardCount = 0;
  138. m_cbLeftCardCount = 0;
  139. m_cbShiJiLeftCardCount = 0;
  140. ZeroMemory(m_cbRepertoryCard, sizeof(m_cbRepertoryCard));
  141. m_cbGangCount = 0;//打了几个杠
  142. //运行变量
  143. m_cbProvideCard = 0;
  144. m_wResumeUser = INVALID_CHAIR;
  145. m_wCurrentUser = INVALID_CHAIR;
  146. m_wProvideUser = INVALID_CHAIR;
  147. //m_wBankerUser = INVALID_CHAIR;
  148. //状态变量
  149. //m_bSendStatus=false;
  150. //m_bGangStatus = false;
  151. m_GangPrivedUserID = -1;
  152. m_bGangOption = 0;
  153. //m_OutLastLaiZiData = 0; //最后杠牌数据,断线重连用的着
  154. m_bQiangGang = false;
  155. //用户状态
  156. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  157. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  158. ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard));
  159. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  160. ZeroMemory(m_cbOperateCaiCard, sizeof(m_cbOperateCaiCard));
  161. //组合扑克
  162. ZeroMemory(m_WeaveItemArray, sizeof(m_WeaveItemArray));
  163. ZeroMemory(m_cbWeaveItemCount, sizeof(m_cbWeaveItemCount));
  164. //结束信息
  165. m_cbMagicFirstData = 0;
  166. m_cbMagicSecondData = 0;
  167. bIsHuang = false;
  168. ZeroMemory(m_cbOptCard, sizeof(m_cbOptCard));
  169. ZeroMemory(m_bUsersGangStatus, GAME_PLAYER);
  170. return;
  171. }
  172. bool CTableFrameSink_tdh::RepayRecordStart()
  173. {
  174. m_bReplayRecordStart = true;
  175. m_UserReplayRecord.clear();
  176. return true;
  177. }
  178. bool CTableFrameSink_tdh::RepayRecordEnd()
  179. {
  180. if (!m_bReplayRecordStart)
  181. return false;
  182. m_bReplayRecordStart = false;
  183. CMD_GR_ReplayRecordResp urr;
  184. ZeroMemory(&urr, sizeof(CMD_GR_ReplayRecordResp));
  185. urr.m_UUID = 0;
  186. urr.m_UserId = 0;
  187. urr.m_startTime = m_startTime;
  188. urr.m_endTime = time(0);
  189. urr.m_gameconfig = m_gameConfig;
  190. //urr.m_UserId = pIServerUserItem->GetUserID();
  191. for (int j = 0; j < mPlayGameUserCount; ++j)
  192. {
  193. if (m_bTwoPlayerFlag&&j == TowMjNullseat)
  194. {
  195. continue;
  196. }
  197. IServerUserItem * pIServerUserItem = m_pITableFrame->GetTableUserItem(j);
  198. if ((pIServerUserItem == NULL) /*|| (pIServerUserItem->IsClientReady() == false)*/)
  199. continue;
  200. auto& chairInfo = urr.m_chairList[j];
  201. chairInfo.dwUserId = pIServerUserItem->GetUserID();
  202. chairInfo.wChairId = pIServerUserItem->GetChairID();
  203. lstrcpy(chairInfo.userName, pIServerUserItem->GetNickName());
  204. lstrcpy(chairInfo.headUrl, pIServerUserItem->GetUserInfo()->szHeadUrl);
  205. }
  206. urr.m_recordCount = m_UserReplayRecord.size();
  207. RecordPacket::PB_CS_S_ReplayRecordResp RecordResp;
  208. RecordResp.set_m_uuid(urr.m_UUID);
  209. RecordResp.set_m_userid(urr.m_UserId);
  210. RecordResp.set_m_starttime(urr.m_startTime);
  211. RecordResp.set_m_endtime(urr.m_endTime);
  212. RecordResp.mutable_m_gameconfig()->set_bduolai(m_gameConfig.bDuoLai);
  213. RecordResp.mutable_m_gameconfig()->set_isowner(m_gameConfig.IsOwner);
  214. RecordResp.mutable_m_gameconfig()->set_roomid(m_gameConfig.RoomId);
  215. std::string sPrivateTableID = CW2AEX<1024>(m_gameConfig.sPrivateTableID, CP_UTF8).m_psz;
  216. RecordResp.mutable_m_gameconfig()->set_sprivatetableid(sPrivateTableID);
  217. RecordResp.mutable_m_gameconfig()->set_tmp1(m_gameConfig.tmp1);
  218. RecordResp.mutable_m_gameconfig()->set_tmp2(m_gameConfig.tmp2);
  219. RecordResp.mutable_m_gameconfig()->set_wdiscore(m_gameConfig.wDiScore);
  220. RecordResp.mutable_m_gameconfig()->set_wfanfei(m_gameConfig.wFanFei);
  221. RecordResp.mutable_m_gameconfig()->set_wfengding(m_gameConfig.wFengDing);
  222. RecordResp.mutable_m_gameconfig()->set_whadplaycount(m_gameConfig.wHadPlayCount);
  223. RecordResp.mutable_m_gameconfig()->set_wiplimit(m_gameConfig.wIpLimit);
  224. RecordResp.mutable_m_gameconfig()->set_wplaycountrule(m_gameConfig.wPlayCountRule);
  225. RecordResp.mutable_m_gameconfig()->set_wsubgameid(m_gameConfig.wSubGameID);
  226. for (WORD i = 0; i < mPlayGameUserCount; i++)
  227. {
  228. RecordPacket::pb_ChairRecord* Record = RecordResp.add_m_chairlist();
  229. Record->set_wchairid(urr.m_chairList[i].wChairId);
  230. Record->set_dwuserid(urr.m_chairList[i].dwUserId);
  231. std::string userName = CW2AEX<1024>(urr.m_chairList[i].userName, CP_UTF8).m_psz;
  232. std::string headUrl = CW2AEX<1024>(urr.m_chairList[i].headUrl, CP_UTF8).m_psz;
  233. Record->set_username(userName);
  234. Record->set_headurl(headUrl);
  235. }
  236. for (auto& grp : m_UserReplayRecord)
  237. {
  238. RecordPacket::pb_GameRecordPacket* Packet = RecordResp.add_precordpacket();
  239. Packet->set_wchairid(grp.wchairid());
  240. Packet->set_wsubcmdid(grp.wsubcmdid());
  241. Packet->set_wmaincmdid(grp.wmaincmdid());
  242. Packet->set_pdata(grp.pdata());
  243. }
  244. std::string pbresp = RecordResp.SerializePartialAsString();
  245. m_pITableFrame->SaveReplayRecord((void*)pbresp.c_str(), pbresp.length());
  246. //for (GameRecordPacket grp : m_UserReplayRecord)
  247. //{
  248. // if (grp.pData != NULL)
  249. // {
  250. // delete[] grp.pData;
  251. // grp.pData = NULL;
  252. // }
  253. //}
  254. m_UserReplayRecord.clear();
  255. //delete replyRecordData;不能删除,已托管给SaveReplayRecord函数
  256. return true;
  257. }
  258. bool CTableFrameSink_tdh::RepayRecord(WORD wChairID, WORD wSubCmdId, void* pData, WORD wSize)
  259. {
  260. RecordPacket::pb_GameRecordPacket pRecordPacket;
  261. pRecordPacket.set_wchairid(wChairID);
  262. pRecordPacket.set_wsubcmdid(wSubCmdId);
  263. pRecordPacket.set_wmaincmdid(MDM_GF_GAME);
  264. pRecordPacket.set_pdata((char*)pData, wSize);
  265. m_UserReplayRecord.push_back(pRecordPacket);
  266. return true;
  267. }
  268. //游戏开始
  269. bool CTableFrameSink_tdh::OnEventGameStart()
  270. {
  271. m_startTime = time(0);
  272. ZeroMemory(m_lGameScore, sizeof(m_lGameScore));
  273. srand((unsigned)time(NULL)*mGameTableId);
  274. m_cbMagicFirstData = 0;
  275. m_cbMagicSecondData = 0;
  276. //椅子数量
  277. WORD wChairCount = m_pITableFrame->GetChairCount();
  278. //开始记录回放数据
  279. RepayRecordStart();
  280. //重置发牌状态
  281. m_isCanOutCard = false;
  282. //重置掉线玩家列表
  283. m_offlineUsers.clear();
  284. //设置状态
  285. m_pITableFrame->SetGameStatus(GS_MJ_PLAY);
  286. //打印时间
  287. DWORD timet = GetTickCount();
  288. m_gameConfig.wHadPlayCount++;
  289. //混乱扑克,
  290. m_lSiceCount = MAKELONG(MAKEWORD(rand() % 6 + 1, rand() % 6 + 1), MAKEWORD(rand() % 6 + 1, rand() % 6 + 1));
  291. if (m_gameConfig.wHadPlayCount == 1)
  292. {
  293. m_lSiceCountCheckBank = MAKELONG(MAKEWORD(rand() % 6 + 1, rand() % 6 + 1), MAKEWORD(rand() % 6 + 1, rand() % 6 + 1));
  294. }
  295. else
  296. {
  297. m_lSiceCountCheckBank = 0;
  298. }
  299. if (m_bTwoPlayerFlag)
  300. {
  301. m_cbLeftCardCount = m_GameLogic.RandCardData_Two(m_cbRepertoryCard);
  302. }
  303. else
  304. {
  305. m_cbLeftCardCount = m_GameLogic.RandCardData(m_cbRepertoryCard);
  306. }
  307. WritePaiCardData(m_gameConfig.sPrivateTableID, m_gameConfig.wHadPlayCount);
  308. if (1 == m_gameConfig.wHadPlayCount )
  309. {
  310. WORD wSice = WORD(m_lSiceCountCheckBank & 0xffff);
  311. int slice1 = HIBYTE(wSice);
  312. int slice2 = LOBYTE(wSice);
  313. int nAll = slice1 + slice2;
  314. /*
  315. 计算庄家
  316. */
  317. if (m_bTwoPlayerFlag)
  318. {
  319. if (nAll%2==0)
  320. {
  321. m_wBankerUser = 2;
  322. }
  323. else
  324. {
  325. m_wBankerUser = 0;
  326. }
  327. }
  328. else
  329. {
  330. m_wBankerUser = (nAll%mPlayGameUserCount + (mPlayGameUserCount - 1)) % mPlayGameUserCount;
  331. }
  332. /*CString str;
  333. str.Format(_T("num1=%d num2=%d all=%d 方向=%d 庄=%d"), slice1, slice2, nAll, m_wBankerUser);
  334. OutputDebugString(str);*/
  335. }
  336. else
  337. {
  338. if ( m_wNextBankerUser == INVALID_CHAIR)
  339. {
  340. m_wBankerUser = m_wBankerUser;
  341. }
  342. else
  343. {
  344. m_wBankerUser = m_wNextBankerUser;
  345. }
  346. //CString str;
  347. //str.Format(_T("庄=%d"), m_wBankerUser);
  348. //OutputDebugString(str);
  349. }
  350. m_wNextBankerUser = INVALID_CHAIR;
  351. //BYTE byTest[] = {
  352. // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  353. // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  354. // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  355. // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, //万子
  356. // 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  357. // 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  358. // 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  359. // 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, //索子
  360. // 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  361. // 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  362. // 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  363. // 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, //同子
  364. // 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  365. // 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  366. // 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北
  367. // 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, //风东南西北 中发白
  368. //};
  369. //if (m_GameLogic.PeiPai(byTest))
  370. // CopyMemory(m_cbRepertoryCard, byTest, sizeof(byTest));
  371. //配牌状态 默认每次都是东家为装
  372. /* if (ReadGameData())
  373. {
  374. m_wBankerUser = 0;
  375. }*/
  376. ReadGameData();
  377. //////////////////////////////////////////////////////////////////////////
  378. //调试使用
  379. //m_wBankerUser = 0;
  380. //////////////////////////////////////////////////////////////////////////
  381. //分发扑克
  382. for (WORD i = 0; i < mPlayGameUserCount; i++)
  383. {
  384. if (m_bTwoPlayerFlag&&i==TowMjNullseat)
  385. {
  386. continue;
  387. }
  388. m_bPlayStatus[i] = true;
  389. m_cbLeftCardCount -= (MAX_COUNT - 1);//每一个玩家都发出去13张牌,还剩多少
  390. m_cbSendCardCount += (MAX_COUNT - 1);//每个玩家加13张牌
  391. m_GameLogic.SwitchToCardIndex(&m_cbRepertoryCard[m_cbLeftCardCount], MAX_COUNT - 1, m_cbCardIndex[i]);
  392. }
  393. //
  394. m_cbSendCardCount++;
  395. //取一张财神牌
  396. m_cbMagicFirstData = m_cbRepertoryCard[--m_cbLeftCardCount];
  397. //获取下一张财神
  398. m_cbMagicSecondData = GetNextMagicCardData(m_cbMagicFirstData);
  399. //发送扑克,庄家摸牌
  400. m_cbSendCardCount++;//第十四张牌
  401. m_cbSendCardData = m_cbRepertoryCard[--m_cbLeftCardCount];
  402. //设置变量
  403. m_cbProvideCard = 0;
  404. m_wProvideUser = m_wBankerUser & 0x000F;
  405. m_wCurrentUser = m_wBankerUser & 0x000F;
  406. WORD ActionCard[6] = { 0 };
  407. m_GameLogic.SetMagicIndex(m_GameLogic.SwitchToCardIndex(m_cbMagicSecondData), MAX_INDEX);
  408. // 胡牌判断
  409. CChiHuRight chr;
  410. BYTE TaiShu = 0;
  411. m_cbUserAction[m_wCurrentUser] |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[m_wCurrentUser], NULL, 0, m_cbSendCardData, chr, TaiShu);
  412. m_cbCardIndex[m_wCurrentUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;
  413. //if (m_cbUserAction[m_wCurrentUser] & WIK_ZI_MO)
  414. //{
  415. // m_cbUserAction[m_wCurrentUser] = WIK_TIAN_ZI_MO;
  416. //}
  417. //杠牌判断
  418. tagGangCardResult GangCardResult;
  419. ZeroMemory(&GangCardResult, sizeof(GangCardResult));
  420. m_cbUserAction[m_wCurrentUser] |= m_GameLogic.AnalyseGangCard(m_cbCardIndex[m_wCurrentUser], NULL, 0, GangCardResult);
  421. for (BYTE i = 0; i < GangCardResult.cbCardCount; i++)
  422. {
  423. ActionCard[i] = GangCardResult.cbCardData[i];
  424. }
  425. m_cbProvideCard = m_cbSendCardData;
  426. m_wResumeUser = m_wCurrentUser;
  427. //保存实际剩余的牌
  428. m_cbShiJiLeftCardCount = m_cbLeftCardCount;
  429. //牌位第十三顿 截止 倒数第十四牌打完 没人胡牌 流局
  430. //根据这个规则 删除26张牌 剩余的牌出完 没人胡牌 就是 流局
  431. m_cbLeftCardCount -= 26;//
  432. //构造数据
  433. CMD_S_GameStart GameStart;
  434. GameStart.wBankerUser = m_wBankerUser;
  435. GameStart.cbLeftCardCount = m_cbLeftCardCount;
  436. WORD wSice = WORD(m_lSiceCount & 0xffff);
  437. GameStart.cbSiceLaiZi[0] = HIBYTE(wSice);//骰子 第一次
  438. GameStart.cbSiceLaiZi[1] = LOBYTE(wSice);//骰子
  439. GameStart.cbSiceLaiZi[2] = m_cbMagicFirstData;//真实展示的牌
  440. GameStart.cbSiceLaiZi[3] = m_cbMagicSecondData;//财神显示的牌
  441. if (1 == m_gameConfig.wHadPlayCount)
  442. {
  443. WORD wSice = WORD(m_lSiceCountCheckBank & 0xffff);
  444. GameStart.cbSliceCheckBankUser[0] = HIBYTE(wSice);
  445. GameStart.cbSliceCheckBankUser[1] = LOBYTE(wSice);
  446. //////////////////////////////////////////////////////////////////////////
  447. //调试
  448. /*GameStart.cbSliceCheckBankUser[0] = 2;
  449. GameStart.cbSliceCheckBankUser[1] = 3;*/
  450. //////////////////////////////////////////////////////////////////////////
  451. }
  452. else
  453. {
  454. GameStart.cbSliceCheckBankUser[0] = 0;
  455. GameStart.cbSliceCheckBankUser[1] = 0;
  456. }
  457. //设置庄家 相关。
  458. //CString strShaizi;
  459. //strShaizi.Format(_T("[%d %d] , [%d %d]"), GameStart.cbSiceLaiZi[0], GameStart.cbSiceLaiZi[1], GameStart.cbSliceCheckBankUser[0], GameStart.cbSliceCheckBankUser[1]);
  460. //OutputDebugString(strShaizi);
  461. if (m_bTwoPlayerFlag)
  462. {
  463. GameStart.cbTotalCardCount = MAX_REPERTORY_ZJ_Two; //麻将总数
  464. }else
  465. {
  466. GameStart.cbTotalCardCount = MAX_REPERTORY_ZJ; //麻将总数
  467. }
  468. GameStart.cbCurrPlay = m_gameConfig.wHadPlayCount;//当前局数
  469. GameStart.cbOptTime = GAME_TIMEOUT;//出牌超时时间
  470. ZeroMemory(GameStart.ActionCard, sizeof(GameStart.ActionCard));
  471. CopyMemory(GameStart.ActionCard, ActionCard, sizeof(ActionCard));
  472. TingCard(m_wCurrentUser);
  473. //打印时间
  474. //DWORD t2 = GetTickCount();
  475. //DWORD hh = t2 - timet;
  476. //CString csTemp;
  477. //csTemp.Format(L"时间:%d \r\n", hh);
  478. //OutputDebugString(csTemp);
  479. //发送数据
  480. SparrowMaJiang::PB_CS_S_GameStart GameStarts;
  481. GameStarts.set_wbankeruser(GameStart.wBankerUser);
  482. GameStarts.set_cbleftcardcount(GameStart.cbLeftCardCount);
  483. GameStarts.set_cbtotalcardcount(GameStart.cbTotalCardCount);
  484. GameStarts.set_cbopttime(GameStart.cbOptTime);
  485. GameStarts.set_cbcurrplay(GameStart.cbCurrPlay);
  486. for (WORD j = 0; j < 4; j++)
  487. {
  488. GameStarts.add_cbsicelaizi(GameStart.cbSiceLaiZi[j]);
  489. }
  490. for (WORD j = 0; j < 6; j++)
  491. {
  492. GameStarts.add_actioncard(GameStart.ActionCard[j]);
  493. }
  494. for (WORD j = 0; j < 2; j++)
  495. {
  496. GameStarts.add_cbslicecheckbankuser(GameStart.cbSliceCheckBankUser[j]);
  497. }
  498. //发送数据
  499. for (WORD i = 0; i<wChairCount; i++)
  500. {
  501. //设置变量
  502. GameStart.wCurrentUser = i;
  503. GameStart.cbUserAction = m_cbUserAction[i];
  504. //把庄家 刚刚放入手里的牌剪掉 然后统一 发送数据
  505. if (i == m_wCurrentUser)
  506. {
  507. if (m_cbCardIndex[m_wCurrentUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)] > 0 && m_wCurrentUser == i)
  508. {
  509. m_cbCardIndex[m_wCurrentUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]--;//从手上去掉抓的牌
  510. }
  511. else
  512. {
  513. return false;
  514. }
  515. }
  516. ZeroMemory(GameStart.cbCardData, sizeof(GameStart.cbCardData));
  517. m_GameLogic.SwitchToCardData(m_cbCardIndex[i], &GameStart.cbCardData[MAX_COUNT*i]);
  518. if (i == m_wCurrentUser)
  519. {
  520. GameStart.cbCardData[i * 14 + 13] = m_cbSendCardData;//把去掉的牌加到数组末尾,
  521. m_cbCardIndex[m_wCurrentUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;//把去掉的加进来
  522. }
  523. GameStarts.set_wcurrentuser(GameStart.wCurrentUser);
  524. for (WORD j = 0; j < MAX_COUNT * GAME_PLAYER; j++)
  525. {
  526. if (i == 0)
  527. {
  528. GameStarts.add_cbcarddata(GameStart.cbCardData[j]);
  529. }
  530. else
  531. {
  532. GameStarts.set_cbcarddata(j, GameStart.cbCardData[j]);
  533. }
  534. }
  535. GameStarts.set_cbuseraction(GameStart.cbUserAction);
  536. //发送数据
  537. std::string pbdata = GameStarts.SerializePartialAsString();
  538. //发送数据
  539. m_pITableFrame->SendTableData(i, SUB_S_GAME_START, (void*)pbdata.c_str(), pbdata.length());
  540. }
  541. //用户回放
  542. ZeroMemory(GameStart.cbCardData, sizeof(GameStart.cbCardData));
  543. for (WORD i = 0; i < MAX_COUNT * GAME_PLAYER; i++)
  544. {
  545. GameStarts.set_cbcarddata(i, GameStart.cbCardData[i]);
  546. }
  547. //清手牌 旁观只能发一次
  548. std::string pbdata = GameStarts.SerializePartialAsString();
  549. //发送数据
  550. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_START, (void*)pbdata.c_str(), pbdata.length());
  551. for (WORD i = 0; i < wChairCount; i++)
  552. m_GameLogic.SwitchToCardData(m_cbCardIndex[i], &GameStart.cbCardData[MAX_COUNT * i]);
  553. for (WORD i = 0; i < MAX_COUNT * GAME_PLAYER; i++)
  554. {
  555. GameStarts.set_cbcarddata(i, GameStart.cbCardData[i]);
  556. }
  557. std::string pbrecord = GameStarts.SerializePartialAsString();
  558. RepayRecord(INVALID_CHAIR, SUB_S_GAME_START, (void*)pbrecord.c_str(), pbrecord.length());
  559. if (m_TabbOutCardCout[m_wCurrentUser] > 0)
  560. HttpTingCard(m_wCurrentUser);
  561. return true;
  562. return true;
  563. }
  564. void CTableFrameSink_tdh::DeletePrivateTable(bool bSendState)
  565. {
  566. tagScoreInfo ScoreInfoArray[GAME_PLAYER];
  567. ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray));
  568. WORD wChairCount = m_pITableFrame->GetChairCount();
  569. for (int i = 0; i < wChairCount; ++i)
  570. {
  571. IServerUserItem *pIUserItem = m_pITableFrame->GetTableUserItem(i);
  572. if (pIUserItem == NULL)
  573. continue;
  574. ScoreInfoArray[i].cbType = SCORE_TYPE_END;
  575. ScoreInfoArray[i].lScore = 0;// m_lUserTmpScore[i] - TEMP_MAX_SCORE; //记录临时分
  576. }
  577. m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray));
  578. ConcludeGame(GAME_STATUS_DELETE, bSendState);
  579. m_pITableFrame->DeletePrivateTableNow();
  580. }
  581. //游戏结束
  582. bool CTableFrameSink_tdh::OnEventGameConclude(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason, bool bSendState)
  583. {
  584. bool bFinish = (m_gameConfig.wHadPlayCount >= m_gameConfig.wPlayCountRule) ? 1 : 0;
  585. switch (cbReason)
  586. {
  587. case GER_DELETE_PRIVATE:
  588. {
  589. ConcludeGame(GS_MJ_FREE);
  590. DeletePrivateTable(bSendState);
  591. return true;
  592. }
  593. case GER_NORMAL: //常规结束
  594. {
  595. //变量定义
  596. CMD_S_GameEnd GameEnd;
  597. ZeroMemory(&GameEnd, sizeof(GameEnd));
  598. GameEnd.bFinish = bFinish;//1……
  599. if (m_cbLeftCardCount <= 0 && bIsHuang)//荒庄了
  600. {
  601. {
  602. GameEnd.bOptType = 2;
  603. //黄庄了
  604. //积分变动
  605. CMD_S_GangScore gs;
  606. ZeroMemory(&gs, sizeof(gs));
  607. gs.wChairId = WIK_NULL;
  608. gs.cbOperateCode = WIK_NULL;
  609. CaculationHuangZhuang(gs);
  610. SparrowMaJiang::PB_CS_S_GangScore GangScore;
  611. GangScore.set_cboperatecode(gs.cbOperateCode);
  612. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  613. {
  614. GangScore.add_cbwanjiascore(gs.cbWanJiaScore[j]);
  615. GangScore.add_lgangscore(gs.lGangScore[j]);
  616. }
  617. GangScore.set_wchairid(gs.wChairId);
  618. std::string pbscore = GangScore.SerializePartialAsString();
  619. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  620. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  621. //统计玩家积分,牌值
  622. for (WORD i = 0; i < mPlayGameUserCount; i++)
  623. {
  624. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  625. {
  626. continue;
  627. }
  628. GameEnd.cbWanJiaScore[i] = m_lGameTatolScore[i];//各玩家积分4…………
  629. m_GameLogic.SwitchToCardData(m_cbCardIndex[i], GameEnd.cbCardData[i]);
  630. }
  631. //黄装了
  632. if (m_gameConfig.wHadPlayCount > 1)
  633. {
  634. m_wNextBankerUser = m_wBankerUser;
  635. m_wNextBankerUser = m_wNextBankerUser | 0x0100;
  636. int userID;
  637. if (m_wBankerUser > 4)
  638. {
  639. userID = m_wBankerUser & 0x00ff;
  640. }
  641. else
  642. {
  643. userID = m_wBankerUser;
  644. }
  645. LianXuHuPai[userID]++;
  646. }
  647. else
  648. {
  649. LianXuHuPai[m_wBankerUser & 0x00ff]++;
  650. }
  651. }
  652. }
  653. else
  654. {
  655. GameEnd.bOptType = 1;
  656. GameEnd.HuPaiCard = m_cbProvideCard;
  657. GameEnd.wDianpao = m_wProvideUser;
  658. BYTE TempWanJiaCardCount = 0;
  659. m_wNextBankerUser = wChairID; //得到下一个坐庄的玩家
  660. if (LianXuHuPai[wChairID] > 1)
  661. m_wNextBankerUser = m_wNextBankerUser | 0x0100;
  662. //统计积分,胡牌得分,玩家牌值
  663. //保存本局所有用户的积分变动 除了胡牌玩家的
  664. for (WORD i = 0; i < mPlayGameUserCount; i++)
  665. {
  666. //m_lGameTatolScore[i] += m_lGameScore[i];
  667. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  668. {
  669. continue;
  670. }
  671. GameEnd.cbWanJiaScore[i] = m_lGameTatolScore[i];//各玩家积分3…………
  672. if (i == wChairID && m_wProvideUser == wChairID)continue;
  673. m_GameLogic.SwitchToCardData(m_cbCardIndex[i], GameEnd.cbCardData[i]);
  674. }
  675. //
  676. if (m_wProvideUser == wChairID)
  677. {
  678. //先减去 胡的这张牌
  679. m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)]--;
  680. //把剩下的手牌保存到cbCardData
  681. m_GameLogic.SwitchToCardData(m_cbCardIndex[wChairID], GameEnd.cbCardData[wChairID]);
  682. //保存手牌数目
  683. TempWanJiaCardCount = m_GameLogic.GetCardCount(m_cbCardIndex[wChairID]);
  684. //最后一张牌 加上刚刚减去的牌
  685. GameEnd.cbCardData[wChairID][TempWanJiaCardCount] = m_cbProvideCard;//手牌数据4……
  686. //还原减去的牌
  687. m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)]++;
  688. }
  689. }
  690. GameEnd.bWanJiaId = wChairID;//玩家座位号 5……
  691. //保存实际桌子剩下多少能够抓的牌
  692. GameEnd.bLeftCardCount = m_cbShiJiLeftCardCount;//m_cbLeftCardCount + 26 + m_cbGangCount * 6;//剩余牌输量6…………
  693. CopyMemory(GameEnd.bLeftCardDada, m_cbRepertoryCard, GameEnd.bLeftCardCount);//剩余牌值7………………
  694. //保存每个玩家的胡牌次数
  695. CopyMemory(GameEnd.bZimo, m_HuPai, sizeof(m_HuPai));//玩家胡牌次数8…………
  696. //本次胡牌玩家的id
  697. GameEnd.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID();//获取房间ID,9……//胡牌玩家id
  698. GameEnd.playGameNum = m_gameConfig.wHadPlayCount;//得到第几局了,10…………
  699. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  700. {
  701. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  702. {
  703. continue;
  704. }
  705. //保存16局 胡牌积分流水
  706. m_HuPaiLiuShui[(m_gameConfig.wHadPlayCount - 1) * 4 + i] = m_lGameScore[i];
  707. }
  708. CopyMemory(GameEnd.lGameScoreDetail, m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui));//游戏流水,10…………
  709. for (int i = 0; i < m_gameConfig.wHadPlayCount; i++)
  710. {
  711. CString strTmp;
  712. strTmp.Format(_T("胡牌流水->第%d局 %d,%d,%d,%d"), i, m_HuPaiLiuShui[i * 4 + 0], m_HuPaiLiuShui[i * 4 + 1], m_HuPaiLiuShui[i * 4 + 2], m_HuPaiLiuShui[i * 4 + 3]);
  713. //OutputDebugString(strTmp);
  714. }
  715. SparrowMaJiang::PB_CS_S_GameEnd pGameEnd;
  716. pGameEnd.set_bopttype(GameEnd.bOptType);
  717. pGameEnd.set_bwanjiaid(GameEnd.bWanJiaId);
  718. pGameEnd.set_wdianpao(GameEnd.wDianpao);
  719. pGameEnd.set_hupaicard(GameEnd.HuPaiCard);
  720. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  721. {
  722. pGameEnd.add_cbwanjiascore(GameEnd.cbWanJiaScore[i]);
  723. pGameEnd.add_bzimo(GameEnd.bZimo[i]);
  724. }
  725. pGameEnd.set_bfinish(GameEnd.bFinish);
  726. pGameEnd.set_dwownerid(GameEnd.dwOwnerID);
  727. pGameEnd.set_bleftcardcount(GameEnd.bLeftCardCount);
  728. for (BYTE i = 0; i < GameEnd.bLeftCardCount; i++)
  729. {
  730. pGameEnd.add_bleftcarddada(GameEnd.bLeftCardDada[i]);
  731. }
  732. pGameEnd.set_playgamenum(GameEnd.playGameNum);
  733. for (BYTE i = 0; i < mPlayGameUserCount * 16; i++)
  734. {
  735. pGameEnd.add_lgamescoredetail(GameEnd.lGameScoreDetail[i]);
  736. }
  737. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  738. {
  739. SparrowMaJiang::pb_cbCardData* CardData = pGameEnd.add_cbcarddata();
  740. for (BYTE j = 0; j < 14; j++)
  741. {
  742. CardData->add_cbcarddatas(GameEnd.cbCardData[i][j]);
  743. }
  744. }
  745. std::string pbdata = pGameEnd.SerializePartialAsString();
  746. RepayRecord(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  747. //发送结束信息
  748. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  749. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  750. tagScoreInfo ScoreInfoArray[GAME_PLAYER];
  751. ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray));
  752. for (WORD i = 0; i < mPlayGameUserCount; i++)
  753. {
  754. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  755. {
  756. continue;
  757. }
  758. IServerUserItem *pUserItem = m_pITableFrame->GetTableUserItem(i);
  759. if (NULL == pUserItem) continue;
  760. BYTE ScoreKind;
  761. if (m_lGameScore[i] > 0L) ScoreKind = SCORE_TYPE_WIN;
  762. else if (m_lGameScore[i] < 0L) ScoreKind = SCORE_TYPE_LOSE;
  763. else ScoreKind = SCORE_TYPE_DRAW;
  764. ScoreInfoArray[i].lScore = m_lGameScore[i];
  765. ScoreInfoArray[i].cbType = ScoreKind;
  766. //if (i == wChairID)continue;
  767. //m_GameLogic.SwitchToCardData(m_cbCardIndex[i], GameEnd.cbCardData[i]);
  768. }
  769. m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray));
  770. ConcludeGame(GS_MJ_FREE);
  771. if (bFinish)
  772. {
  773. DeletePrivateTable(true);
  774. }
  775. return true;
  776. }
  777. case GER_DISMISS: //游戏解散
  778. {
  779. //变量定义
  780. CMD_S_GameEnd GameEnd;
  781. ZeroMemory(&GameEnd, sizeof(GameEnd));
  782. GameEnd.bFinish = 1;
  783. GameEnd.bOptType = 3;
  784. CopyMemory(GameEnd.cbWanJiaScore, m_lGameTatolScore, sizeof(m_lGameTatolScore));
  785. GameEnd.bWanJiaId = wChairID;//玩家座位号 5……
  786. //保存实际桌子剩下多少能够抓的牌
  787. GameEnd.bLeftCardCount = m_cbShiJiLeftCardCount;//m_cbLeftCardCount + 26 + m_cbGangCount * 6;//剩余牌输量6…………
  788. CopyMemory(GameEnd.bLeftCardDada, m_cbRepertoryCard, GameEnd.bLeftCardCount);//剩余牌值7………………
  789. //保存每个玩家的胡牌次数
  790. CopyMemory(GameEnd.bZimo, m_HuPai, sizeof(m_HuPai));//玩家胡牌次数8…………
  791. //本次胡牌玩家的id
  792. GameEnd.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID();//获取房间ID,9……//胡牌玩家id
  793. GameEnd.playGameNum = m_gameConfig.wHadPlayCount;//得到第几局了,10…………
  794. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  795. {
  796. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  797. {
  798. continue;
  799. }
  800. m_GameLogic.SwitchToCardData(m_cbCardIndex[i], GameEnd.cbCardData[i]);
  801. //保存16局 胡牌积分流水
  802. m_HuPaiLiuShui[(m_gameConfig.wHadPlayCount - 1) * 4 + i] = m_lGameScore[i];
  803. }
  804. CopyMemory(GameEnd.lGameScoreDetail, m_HuPaiLiuShui, sizeof(m_HuPaiLiuShui));//游戏流水,10…………
  805. //统计积分,胡牌得分,玩家牌值
  806. //保存本局所有用户的积分变动 除了胡牌玩家的
  807. for (WORD i = 0; i < mPlayGameUserCount; i++)
  808. {
  809. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  810. {
  811. continue;
  812. }
  813. GameEnd.cbWanJiaScore[i] = m_lGameTatolScore[i];//各玩家积分3…………
  814. }
  815. SparrowMaJiang::PB_CS_S_GameEnd pGameEnd;
  816. pGameEnd.set_bopttype(GameEnd.bOptType);
  817. pGameEnd.set_bwanjiaid(GameEnd.bWanJiaId);
  818. pGameEnd.set_wdianpao(GameEnd.wDianpao);
  819. pGameEnd.set_hupaicard(GameEnd.HuPaiCard);
  820. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  821. {
  822. pGameEnd.add_cbwanjiascore(GameEnd.cbWanJiaScore[i]);
  823. pGameEnd.add_bzimo(GameEnd.bZimo[i]);
  824. }
  825. pGameEnd.set_bfinish(GameEnd.bFinish);
  826. pGameEnd.set_dwownerid(GameEnd.dwOwnerID);
  827. pGameEnd.set_bleftcardcount(GameEnd.bLeftCardCount);
  828. for (BYTE i = 0; i < GameEnd.bLeftCardCount; i++)
  829. {
  830. pGameEnd.add_bleftcarddada(GameEnd.bLeftCardDada[i]);
  831. }
  832. pGameEnd.set_playgamenum(GameEnd.playGameNum);
  833. for (BYTE i = 0; i < mPlayGameUserCount * 16; i++)
  834. {
  835. pGameEnd.add_lgamescoredetail(GameEnd.lGameScoreDetail[i]);
  836. }
  837. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  838. {
  839. SparrowMaJiang::pb_cbCardData* CardData = pGameEnd.add_cbcarddata();
  840. for (BYTE j = 0; j < 14; j++)
  841. {
  842. CardData->add_cbcarddatas(GameEnd.cbCardData[i][j]);
  843. }
  844. }
  845. std::string pbdata = pGameEnd.SerializePartialAsString();
  846. RepayRecord(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  847. //发送结束信息
  848. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  849. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GAME_END, (void*)pbdata.c_str(), pbdata.length());
  850. if (m_pITableFrame->GetGameStatus() == GS_MJ_FREE)
  851. {
  852. DeletePrivateTable(true);
  853. return true;
  854. }
  855. tagScoreInfo ScoreInfoArray[GAME_PLAYER];
  856. ZeroMemory(&ScoreInfoArray, sizeof(ScoreInfoArray));
  857. for (WORD i = 0; i < mPlayGameUserCount; i++)
  858. {
  859. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  860. {
  861. continue;
  862. }
  863. IServerUserItem *pUserItem = m_pITableFrame->GetTableUserItem(i);
  864. if (NULL == pUserItem) continue;
  865. BYTE ScoreKind;
  866. if (m_lGameScore[i] > 0L) ScoreKind = SCORE_TYPE_WIN;
  867. else if (m_lGameScore[i] < 0L) ScoreKind = SCORE_TYPE_LOSE;
  868. else ScoreKind = SCORE_TYPE_DRAW;
  869. ScoreInfoArray[i].lScore = m_lGameScore[i];
  870. ScoreInfoArray[i].cbType = ScoreKind;
  871. }
  872. m_pITableFrame->WriteTableScore(ScoreInfoArray, CountArray(ScoreInfoArray));
  873. ConcludeGame(GS_MJ_FREE);
  874. DeletePrivateTable(true);
  875. return true;
  876. return true;
  877. }
  878. case GER_NETWORK_ERROR: //网络错误
  879. case GER_USER_LEAVE: //用户强退
  880. {
  881. if (pIServerUserItem != NULL){
  882. DWORD dwUserID = pIServerUserItem->GetUserID();
  883. m_offlineUsers.push_back(dwUserID);
  884. }
  885. return true;
  886. }
  887. }
  888. //错误断言
  889. ASSERT(FALSE);
  890. return false;
  891. }
  892. //发送场景duanxian用户断线重连
  893. bool CTableFrameSink_tdh::OnEventSendGameScene(WORD wChiarID, IServerUserItem * pIServerUserItem, BYTE cbGameStatus, bool bSendSecret)
  894. {
  895. switch (cbGameStatus)
  896. {
  897. case GS_MJ_FREE: //空闲状态
  898. {
  899. //变量定义
  900. CMD_S_StatusFree StatusFree;
  901. memset(&StatusFree, 0, sizeof(StatusFree));
  902. //游戏房主基础配置
  903. CopyMemory(&StatusFree.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig));
  904. for (int i = 0; i < mPlayGameUserCount; i++)
  905. {
  906. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  907. {
  908. continue;
  909. }
  910. StatusFree.lUserTmpScore[i] = (INT)m_lGameTatolScore[i];
  911. }
  912. StatusFree.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0;
  913. //构造数据
  914. StatusFree.UserStat = pIServerUserItem->GetUserInfo()->cbUserStatus;
  915. //发送场景
  916. return m_pITableFrame->SendGameScene(pIServerUserItem, &StatusFree, sizeof(StatusFree));
  917. }
  918. case GS_MJ_PLAY: //游戏状态
  919. {
  920. //变量定义
  921. CMD_S_StatusPlay StatusPlay;
  922. memset(&StatusPlay, 0, sizeof(StatusPlay));
  923. //游戏房主基础配置
  924. CopyMemory(&StatusPlay.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig));
  925. CopyMemory(StatusPlay.lUserTmpScore, m_lGameTatolScore, sizeof(m_lGameTatolScore));
  926. StatusPlay.cbTotalCardCount = m_cbTotalCardCount;
  927. StatusPlay.cbLeftCardCount = m_cbLeftCardCount;
  928. StatusPlay.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0;
  929. //游戏变量
  930. StatusPlay.wBankerUser = m_wBankerUser;
  931. WORD wSice = WORD(m_lSiceCount & 0xffff);
  932. StatusPlay.lSiZi[0] = HIBYTE(wSice);
  933. StatusPlay.lSiZi[1] = LOBYTE(wSice);
  934. StatusPlay.lSiZi[2] = m_cbMagicFirstData;
  935. StatusPlay.lSiZi[3] = m_cbMagicSecondData;
  936. StatusPlay.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID();
  937. CopyMemory(StatusPlay.cbDiscardCard, m_cbDiscardCard, sizeof(StatusPlay.cbDiscardCard));
  938. CopyMemory(StatusPlay.cbDiscardCount, m_cbDiscardCount, sizeof(StatusPlay.cbDiscardCount));
  939. StatusPlay.totalOptTime = 10;
  940. StatusPlay.leftOptTime = 0;
  941. //组合扑克
  942. CopyMemory(StatusPlay.WeaveItemArray, m_WeaveItemArray, sizeof(m_WeaveItemArray));
  943. CopyMemory(StatusPlay.cbWeaveCount, m_cbWeaveItemCount, sizeof(m_cbWeaveItemCount));
  944. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  945. {
  946. //StatusPlay.bWanLaiZi[i] = m_OutLaiZi[i];
  947. //StatusPlay.bWanLaiZi[i] |= (m_OutHongZhongGang[i] << 4);
  948. //StatusPlay.bWanLaiZi[i] |= (m_OutFaCaiGang[i] << 8);
  949. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  950. {
  951. continue;
  952. }
  953. StatusPlay.cbCardCount[i] = m_GameLogic.GetCardCount(m_cbCardIndex[i]);
  954. }
  955. m_GameLogic.SwitchToCardData(m_cbCardIndex[wChiarID], StatusPlay.cbCardData);//手牌数据
  956. StatusPlay.cbActionMask = m_cbUserAction[wChiarID]; //需要用到操作码
  957. if (m_cbUserAction[wChiarID] & (WIK_AN_GANG | WIK_BU_GANG | WIK_DAN_BU_GANG | WIK_DAN_AN_GANG | WIK_SHUANG_AN_GANG | WIK_SAN_AN_GANG | WIK_QUANG_AN_GANG))
  958. {
  959. tagGangCardResult GangCardResult;
  960. ZeroMemory(&GangCardResult, sizeof(GangCardResult));
  961. m_GameLogic.AnalyseGangCard(m_cbCardIndex[wChiarID], m_WeaveItemArray[wChiarID], m_cbWeaveItemCount[wChiarID], GangCardResult);
  962. for (BYTE i = 0; i < GangCardResult.cbCardCount; i++)
  963. {
  964. StatusPlay.gangCards[i] = GangCardResult.cbCardData[i];
  965. }
  966. }
  967. ASSERT(m_wProvideUser >= 0 && m_wProvideUser <= 3);
  968. //当前到谁家
  969. StatusPlay.wCurrentUser = (m_wCurrentUser == INVALID_CHAIR ? m_wProvideUser : m_wCurrentUser);
  970. BYTE OldUser = 0;//定义一个最后出牌用户
  971. if ((m_wProvideUser == m_wCurrentUser&&m_wOutCardUser == INVALID_CHAIR) || (m_wProvideUser == m_wCurrentUser&&m_wResumeUser == m_wCurrentUser && m_cbProvideCard == 0))//牌权是摸牌得且没出牌
  972. {
  973. if (m_bTwoPlayerFlag)
  974. {
  975. OldUser = (m_wProvideUser - 2 + GAME_PLAYER) % GAME_PLAYER;
  976. }
  977. else
  978. {
  979. OldUser = (m_wProvideUser - 1 + mPlayGameUserCount) % mPlayGameUserCount;
  980. }
  981. BYTE TempIndex = 0;
  982. BYTE bDiscardCount = (m_cbDiscardCount[OldUser] - 1) >= 0 ? (m_cbDiscardCount[OldUser] - 1) : 0;
  983. for (BYTE i = bDiscardCount; i < 40; i++)
  984. {
  985. if (m_cbDiscardCard[OldUser][i] == 0)
  986. {
  987. TempIndex = i - 1;
  988. break;
  989. }
  990. }
  991. TempIndex = (TempIndex == 255) ? 0 : TempIndex;
  992. StatusPlay.bPutCardData[OldUser] = m_cbDiscardCard[OldUser][TempIndex];
  993. //}
  994. }
  995. if (m_wProvideUser == m_wOutCardUser && m_wCurrentUser == INVALID_CHAIR)//当有人可以碰且没有碰时候
  996. {
  997. StatusPlay.bPutCardData[m_wProvideUser] = m_cbProvideCard;
  998. StatusPlay.cbDiscardCard[m_wProvideUser][StatusPlay.cbDiscardCount[m_wProvideUser]++] = m_cbProvideCard;
  999. }
  1000. if (wChiarID == StatusPlay.wCurrentUser&&m_wCurrentUser != INVALID_CHAIR&&m_wCurrentUser != m_wProvideUser)//表示当前牌权就在断线玩家手里,且是轮到他出牌(牌权碰来得)
  1001. {
  1002. ZeroMemory(StatusPlay.cbCardData, sizeof(StatusPlay.cbCardData));
  1003. BYTE TempCardData[MAX_INDEX];
  1004. CopyMemory(TempCardData, m_cbCardIndex[wChiarID], sizeof(TempCardData));
  1005. BYTE TempEndCardData = m_GameLogic.GetEndCard(TempCardData);
  1006. BYTE TempCardIndex = m_GameLogic.SwitchToCardIndex(TempEndCardData);
  1007. if (TempCardData[TempCardIndex] == 0){ ASSERT(false); return false; }
  1008. TempCardData[TempCardIndex]--;
  1009. BYTE cardNum = m_GameLogic.SwitchToCardData(TempCardData, StatusPlay.cbCardData);
  1010. StatusPlay.cbCardData[cardNum] = TempEndCardData;
  1011. }
  1012. if (wChiarID == StatusPlay.wCurrentUser && m_wCurrentUser != INVALID_CHAIR && m_wCurrentUser == m_wProvideUser)//牌权是轮到他抓牌,未打出
  1013. {
  1014. ZeroMemory(StatusPlay.cbCardData, sizeof(StatusPlay.cbCardData));
  1015. BYTE TempCardData[MAX_INDEX];
  1016. CopyMemory(TempCardData, m_cbCardIndex[wChiarID], sizeof(TempCardData));
  1017. BYTE TempCardIndex = m_GameLogic.SwitchToCardIndex(m_cbProvideCard);
  1018. if (m_cbCardIndex[wChiarID][TempCardIndex] == 0)ASSERT(false);
  1019. TempCardData[TempCardIndex]--;
  1020. BYTE cardNum = m_GameLogic.SwitchToCardData(TempCardData, StatusPlay.cbCardData);
  1021. StatusPlay.cbCardData[cardNum] = m_GameLogic.SwitchToCardData(TempCardIndex);//处理得到最后一张牌数据放最后
  1022. }
  1023. //////////////////////////////////////////////////////////////////////////
  1024. //发送场景
  1025. return m_pITableFrame->SendGameScene(pIServerUserItem, &StatusPlay, sizeof(StatusPlay));
  1026. }
  1027. }
  1028. return false;
  1029. }
  1030. //定时器事件
  1031. bool CTableFrameSink_tdh::OnTimerMessage(DWORD wTimerID, WPARAM wBindParam)
  1032. {
  1033. return false;
  1034. }
  1035. //游戏消息处理
  1036. void CTableFrameSink_tdh::SetGameConfig(VOID * pDataBuffer, WORD wDataSize, std::wstring sPrivateRoomId)
  1037. {
  1038. tagGameConfig* ppConfig = (tagGameConfig*)pDataBuffer;
  1039. m_gameConfig.wSubGameID = ppConfig->wSubGameID;
  1040. m_gameConfig.wDiScore = ppConfig->wPlayRule;
  1041. m_gameConfig.wFanFei = ppConfig->wMaxFanRule;
  1042. m_gameConfig.wIpLimit = ppConfig->wMaxScore;
  1043. m_gameConfig.wPlayCountRule = ppConfig->wPlayCountRule;
  1044. m_gameConfig.RoomId = ppConfig->wHadPlayCount;
  1045. m_gameConfig.wHadPlayCount = 0;
  1046. m_gameConfig.bDuoLai = ppConfig->bDuoLai;
  1047. m_gameConfig.wFengDing = ppConfig->wFengDing;
  1048. m_gameConfig.tmp1 = ppConfig->tmp1;
  1049. if (m_gameConfig.wFengDing == 0 || m_gameConfig.wFengDing == 5)
  1050. {
  1051. mMaxTaiNum = 5;
  1052. }
  1053. else if (m_gameConfig.wFengDing == 6 || m_gameConfig.wFengDing == 7)
  1054. {
  1055. mMaxTaiNum = m_gameConfig.wFengDing;
  1056. }
  1057. else
  1058. {
  1059. mMaxTaiNum = 20;
  1060. }
  1061. lstrcpy(m_gameConfig.sPrivateTableID, sPrivateRoomId.c_str());
  1062. m_cbTotalCardCount = MAX_REPERTORY_ZJ;
  1063. //协议修改为 4 3 2
  1064. if (m_gameConfig.tmp1 == 0)
  1065. {
  1066. mPlayGameUserCount = 4;
  1067. }
  1068. else
  1069. {
  1070. if (m_gameConfig.tmp1 == 2)
  1071. {
  1072. m_bTwoPlayerFlag = TRUE;
  1073. mPlayGameUserCount = 3;
  1074. m_cbTotalCardCount = MAX_REPERTORY_ZJ_Two;
  1075. m_pITableFrame->SetStartMode(START_MODE_ALL_READY);
  1076. }
  1077. else
  1078. {
  1079. mPlayGameUserCount = m_gameConfig.tmp1;
  1080. }
  1081. }
  1082. m_pITableFrame->SetChairCount(mPlayGameUserCount);
  1083. ASSERT(m_gameConfig.wSubGameID >= 0 && m_gameConfig.wSubGameID < MahJongType::count);
  1084. if (!sPrivateRoomId.empty())
  1085. {
  1086. mGameTableId = _wtoi(sPrivateRoomId.c_str());
  1087. }
  1088. else
  1089. {
  1090. mGameTableId = 1;
  1091. }
  1092. //1 不能放冲 0 能放冲胡吧
  1093. CString strTmp;
  1094. strTmp.Format(_T("bDuoLai=%d"), m_gameConfig.bDuoLai);
  1095. OutputDebugString(strTmp);
  1096. if (m_gameConfig.bDuoLai==1)
  1097. {
  1098. mCanFangChong = TRUE;
  1099. }
  1100. else
  1101. {
  1102. mCanFangChong = FALSE;
  1103. }
  1104. }
  1105. //游戏消息处理
  1106. bool CTableFrameSink_tdh::OnGameMessage(WORD wSubCmdID, VOID* pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem)
  1107. {
  1108. switch (wSubCmdID)
  1109. {
  1110. case SUB_C_OUT_CARD: //出牌消息
  1111. {
  1112. //定义变量
  1113. SparrowMaJiang::PB_CS_C_OutCard OutCard;
  1114. OutCard.ParseFromArray(pDataBuffer, wDataSize);
  1115. //用户效验
  1116. if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
  1117. //用户效验
  1118. if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
  1119. bool bRet = OnUserOutCard(pIServerUserItem->GetChairID(), OutCard.cbcarddata());
  1120. return bRet;
  1121. }
  1122. case SUB_C_OPERATE_CARD: //操作消息
  1123. {
  1124. SparrowMaJiang::PB_CS_C_OperateCard OperateCard;
  1125. OperateCard.ParseFromArray(pDataBuffer, wDataSize);
  1126. //用户效验
  1127. if (pIServerUserItem->GetUserStatus() != US_PLAYING) return true;
  1128. CMD_C_OperateCard pOperateCard;
  1129. for (WORD i = 0; i < 4; i++)
  1130. {
  1131. pOperateCard.cbCaiShenCard[i] = OperateCard.cbcaishencard(i);
  1132. }
  1133. pOperateCard.cbOperateCard = OperateCard.cboperatecard();
  1134. pOperateCard.cbOperateCode = OperateCard.cboperatecode();
  1135. return OnUserOperateCard(pIServerUserItem->GetChairID(), pOperateCard.cbOperateCode, pOperateCard.cbOperateCard, pOperateCard.cbCaiShenCard);
  1136. }
  1137. case SUB_C_TRUSTEE: //托管
  1138. {
  1139. SparrowMaJiang::PB_CS_C_Trustee pTrustee;
  1140. pTrustee.ParseFromArray(pDataBuffer, wDataSize);
  1141. m_bTrustee[pIServerUserItem->GetChairID()] = pTrustee.btrustee();
  1142. CMD_S_Trustee Trustee;
  1143. Trustee.bTrustee = pTrustee.btrustee();
  1144. Trustee.wChairID = pIServerUserItem->GetChairID();
  1145. SparrowMaJiang::PB_CS_S_Trustee Trustees;
  1146. Trustees.set_btrustee(Trustee.bTrustee);
  1147. Trustees.set_wchairid(Trustee.wChairID);
  1148. std::string pbdata = Trustees.SerializePartialAsString();
  1149. RepayRecord(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1150. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1151. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1152. return true;
  1153. }
  1154. //case SUB_C_SELECT_BAO:{
  1155. // CMD_C_BAO *pBaoTai = (CMD_C_BAO *)pDataBuffer;
  1156. // SelectBaoTaiNum(pIServerUserItem->GetChairID(), pBaoTai->cbTaiNum);
  1157. // return true;
  1158. //}
  1159. //case SUB_C_SELECT_CAI:{
  1160. // CMD_C_Magic *pMagic = (CMD_C_Magic*)pDataBuffer;
  1161. // SelectBaoMagic(pIServerUserItem->GetChairID(), pMagic->cbMagicFirst, pMagic->cbMagicSenced);
  1162. // return true;
  1163. //}
  1164. default:
  1165. return false;
  1166. }
  1167. return false;
  1168. }
  1169. //框架消息处理
  1170. bool CTableFrameSink_tdh::OnFrameMessage(WORD wSubCmdID, VOID * pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem)
  1171. {
  1172. return false;
  1173. }
  1174. //用户断线重连
  1175. bool CTableFrameSink_tdh::OnActionUserConnect(WORD wChairID, IServerUserItem * pIServerUserItem)
  1176. {
  1177. auto dwUserID = pIServerUserItem->GetUserID();
  1178. auto iter = std::find(m_offlineUsers.begin(), m_offlineUsers.end(), dwUserID);
  1179. if (m_TabbOutCardCout[wChairID] > 0)
  1180. HttpTingCard(wChairID);
  1181. if (iter != end(m_offlineUsers))
  1182. {
  1183. m_offlineUsers.erase(iter); //玩家重新上线
  1184. return true;
  1185. }
  1186. return true;
  1187. }
  1188. //用户坐下
  1189. bool CTableFrameSink_tdh::OnActionUserSitDown(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
  1190. {
  1191. // CString str;
  1192. // str.Format(_T("椅子ID=%d 用户id=%d"),wChairID,pIServerUserItem->GetUserID());
  1193. // OutputDebugString(str);
  1194. return true;
  1195. }
  1196. //游戏中途旁观进入
  1197. bool CTableFrameSink_tdh::PerformLookonLogin(IServerUserItem * pIServerUserItem)
  1198. {
  1199. CMD_S_PangGuan StatusPlay;
  1200. memset(&StatusPlay, 0, sizeof(StatusPlay));
  1201. //游戏房主基础配置
  1202. CopyMemory(&StatusPlay.gameConfig, &m_gameConfig, sizeof(CMD_S_GameConfig));
  1203. CopyMemory(StatusPlay.lUserTmpScore, m_lGameTatolScore, sizeof(m_lGameTatolScore));
  1204. StatusPlay.cbTotalCardCount = m_cbTotalCardCount;
  1205. StatusPlay.cbLeftCardCount = m_cbLeftCardCount;
  1206. StatusPlay.gameConfig.IsOwner = m_pITableFrame->GetPrivateTableOwnerID() == pIServerUserItem->GetUserID() ? 1 : 0;
  1207. StatusPlay.GameStatus = m_pITableFrame->IsDrawStarted();
  1208. if (StatusPlay.GameStatus)
  1209. {
  1210. //游戏变量
  1211. StatusPlay.wBankerUser = m_wBankerUser;
  1212. WORD wSice = WORD(m_lSiceCount & 0xffff);
  1213. StatusPlay.lSiZi[0] = HIBYTE(wSice);
  1214. StatusPlay.lSiZi[1] = LOBYTE(wSice);
  1215. StatusPlay.lSiZi[2] = m_cbMagicFirstData;
  1216. StatusPlay.lSiZi[3] = m_cbMagicSecondData;
  1217. StatusPlay.dwOwnerID = m_pITableFrame->GetPrivateTableOwnerID();
  1218. CopyMemory(StatusPlay.cbDiscardCard, m_cbDiscardCard, sizeof(StatusPlay.cbDiscardCard));
  1219. CopyMemory(StatusPlay.cbDiscardCount, m_cbDiscardCount, sizeof(StatusPlay.cbDiscardCount));
  1220. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  1221. {
  1222. //StatusPlay.bWanLaiZi[i] = m_OutLaiZi[i];
  1223. //StatusPlay.bWanLaiZi[i] |= (m_OutHongZhongGang[i] << 4);
  1224. //StatusPlay.bWanLaiZi[i] |= (m_OutFaCaiGang[i] << 8);
  1225. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  1226. {
  1227. continue;
  1228. }
  1229. StatusPlay.cbCardCount[i] = m_GameLogic.GetCardCount(m_cbCardIndex[i]);
  1230. }
  1231. StatusPlay.totalOptTime = 10;
  1232. StatusPlay.leftOptTime = 0;
  1233. ASSERT(m_wProvideUser >= 0 && m_wProvideUser <= 3);
  1234. //当前到谁家
  1235. StatusPlay.wCurrentUser = (m_wCurrentUser == INVALID_CHAIR ? m_wProvideUser : m_wCurrentUser);
  1236. WORD OldUser = 0;//定义一个最后出牌用户`
  1237. if (m_wProvideUser == m_wCurrentUser&&m_wOutCardUser == INVALID_CHAIR)//牌权是摸牌得且没出牌
  1238. {
  1239. //if (m_bGangStatus)
  1240. //{
  1241. // StatusPlay.bPutCardData[m_wProvideUser] = m_OutLastLaiZiData;
  1242. //}
  1243. //else
  1244. //{
  1245. if (m_bTwoPlayerFlag)
  1246. {
  1247. OldUser = (m_wProvideUser - 2 + GAME_PLAYER) % GAME_PLAYER;
  1248. }
  1249. else
  1250. {
  1251. OldUser = (m_wProvideUser - 1 + mPlayGameUserCount) % mPlayGameUserCount;
  1252. }
  1253. BYTE TempIndex = 0;
  1254. BYTE bDiscardCount = (m_cbDiscardCount[OldUser] - 1) >= 0 ? (m_cbDiscardCount[OldUser] - 1) : 0;
  1255. for (BYTE i = bDiscardCount; i < 40; i++)
  1256. {
  1257. if (m_cbDiscardCard[OldUser][i] == 0)
  1258. {
  1259. TempIndex = i - 1;
  1260. break;
  1261. }
  1262. }
  1263. TempIndex = (TempIndex == 255) ? 0 : TempIndex;
  1264. StatusPlay.bPutCardData[OldUser] = m_cbDiscardCard[OldUser][TempIndex];
  1265. //}
  1266. }
  1267. if (m_wProvideUser == m_wOutCardUser&& m_wCurrentUser == INVALID_CHAIR)//当有人可以碰且没有碰时候
  1268. {
  1269. StatusPlay.bPutCardData[m_wProvideUser] = m_cbProvideCard;
  1270. StatusPlay.cbDiscardCard[m_wProvideUser][StatusPlay.cbDiscardCount[m_wProvideUser]++] = m_cbProvideCard;
  1271. }
  1272. //组合扑克
  1273. CopyMemory(StatusPlay.WeaveItemArray, m_WeaveItemArray, sizeof(m_WeaveItemArray));
  1274. CopyMemory(StatusPlay.cbWeaveCount, m_cbWeaveItemCount, sizeof(m_cbWeaveItemCount));
  1275. }
  1276. SparrowMaJiang::PB_CS_S_PangGuan PangGuan;
  1277. PangGuan.mutable_gameconfig()->set_bduolai(StatusPlay.gameConfig.bDuoLai);
  1278. PangGuan.mutable_gameconfig()->set_isowner(StatusPlay.gameConfig.IsOwner);
  1279. PangGuan.mutable_gameconfig()->set_roomid(StatusPlay.gameConfig.RoomId);
  1280. std::string sPrivateTableID = CW2AEX<1024>(StatusPlay.gameConfig.sPrivateTableID, CP_UTF8).m_psz;
  1281. PangGuan.mutable_gameconfig()->set_sprivatetableid(sPrivateTableID);
  1282. PangGuan.mutable_gameconfig()->set_tmp1(StatusPlay.gameConfig.tmp1);
  1283. PangGuan.mutable_gameconfig()->set_tmp2(StatusPlay.gameConfig.tmp2);
  1284. PangGuan.mutable_gameconfig()->set_wdiscore(StatusPlay.gameConfig.wDiScore);
  1285. PangGuan.mutable_gameconfig()->set_wfanfei(StatusPlay.gameConfig.wFanFei);
  1286. PangGuan.mutable_gameconfig()->set_wfengding(StatusPlay.gameConfig.wFengDing);
  1287. PangGuan.mutable_gameconfig()->set_whadplaycount(StatusPlay.gameConfig.wHadPlayCount);
  1288. PangGuan.mutable_gameconfig()->set_wiplimit(StatusPlay.gameConfig.wIpLimit);
  1289. PangGuan.mutable_gameconfig()->set_wplaycountrule(StatusPlay.gameConfig.wPlayCountRule);
  1290. PangGuan.mutable_gameconfig()->set_wsubgameid(StatusPlay.gameConfig.wSubGameID);
  1291. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  1292. {
  1293. PangGuan.add_lusertmpscore(StatusPlay.lUserTmpScore[j]);
  1294. PangGuan.add_bputcarddata(StatusPlay.bPutCardData[j]);
  1295. PangGuan.add_cbcardcount(StatusPlay.cbCardCount[j]);
  1296. PangGuan.add_cbweavecount(StatusPlay.cbWeaveCount[j]);
  1297. PangGuan.add_cbdiscardcount(StatusPlay.cbDiscardCount[j]);
  1298. SparrowMaJiang::pb_cbDiscardCard* DiscardCard = PangGuan.add_cbdiscardcard();
  1299. for (BYTE i = 0; i < 40; i++)
  1300. {
  1301. DiscardCard->add_cbdiscardcard(StatusPlay.cbDiscardCard[j][i]);
  1302. }
  1303. SparrowMaJiang::pb_WeaveItemArray* WeaveItemArray = PangGuan.add_weaveitemarray();
  1304. for (BYTE i = 0; i < 4; i++)
  1305. {
  1306. SparrowMaJiang::pb_WeaveItem* WeaveItem = WeaveItemArray->add_weaveitem();
  1307. WeaveItem->set_cbcentercard(StatusPlay.WeaveItemArray[j][i].cbCenterCard);
  1308. WeaveItem->set_cbpubliccard(StatusPlay.WeaveItemArray[j][i].cbPublicCard);
  1309. WeaveItem->set_cbweavekind(StatusPlay.WeaveItemArray[j][i].cbWeaveKind);
  1310. WeaveItem->set_wprovideuser(StatusPlay.WeaveItemArray[j][i].wProvideUser);
  1311. for (BYTE k = 0; k < 4; k++)
  1312. {
  1313. WeaveItem->add_cbmargicoffset(StatusPlay.WeaveItemArray[j][i].cbMargicOffset[k]);
  1314. }
  1315. }
  1316. }
  1317. PangGuan.set_gamestatus(StatusPlay.GameStatus);
  1318. PangGuan.set_cbtotalcardcount(StatusPlay.cbTotalCardCount);
  1319. PangGuan.set_cbleftcardcount(StatusPlay.cbLeftCardCount);
  1320. PangGuan.set_wbankeruser(StatusPlay.wBankerUser);
  1321. for (BYTE j = 0; j < 4; j++)
  1322. {
  1323. PangGuan.add_lsizi(StatusPlay.lSiZi[j]);
  1324. }
  1325. PangGuan.set_dwownerid(StatusPlay.dwOwnerID);
  1326. PangGuan.set_wcurrentuser(StatusPlay.wCurrentUser);
  1327. PangGuan.set_totalopttime(StatusPlay.totalOptTime);
  1328. PangGuan.set_leftopttime(StatusPlay.leftOptTime);
  1329. std::string pbdata = PangGuan.SerializePartialAsString();
  1330. return m_pITableFrame->SendUserItemData(pIServerUserItem, SUB_S_PANGGUAN, (void*)pbdata.c_str(), pbdata.length());
  1331. }
  1332. //用户起来
  1333. bool CTableFrameSink_tdh::OnActionUserStandUp(WORD wChairID, IServerUserItem * pIServerUserItem, bool bLookonUser)
  1334. {
  1335. //庄家设置
  1336. if (bLookonUser == false && !QueryUseTemporaryScore())
  1337. {
  1338. m_bTrustee[wChairID] = false;
  1339. CMD_S_Trustee Trustee;
  1340. Trustee.bTrustee = false;
  1341. Trustee.wChairID = wChairID;
  1342. SparrowMaJiang::PB_CS_S_Trustee Trustees;
  1343. Trustees.set_btrustee(Trustee.bTrustee);
  1344. Trustees.set_wchairid(Trustee.wChairID);
  1345. std::string pbdata = Trustees.SerializePartialAsString();
  1346. RepayRecord(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1347. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1348. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_TRUSTEE, (void*)pbdata.c_str(), pbdata.length());
  1349. }
  1350. return true;
  1351. }
  1352. //用户出牌
  1353. bool CTableFrameSink_tdh::OnUserOutCard(WORD wChairID, BYTE cbCardData)
  1354. {
  1355. m_cbLastGangCard = 0;
  1356. //if (mMjType == 1 && mbStartBaoTai != 3)
  1357. //{
  1358. // return false;
  1359. //}
  1360. m_bQiangGang = false;
  1361. //效验状态
  1362. ASSERT(m_pITableFrame->GetGameStatus() == GS_MJ_PLAY);
  1363. if (m_pITableFrame->GetGameStatus() != GS_MJ_PLAY) return true;
  1364. //错误断言
  1365. ASSERT(wChairID == m_wCurrentUser);
  1366. ASSERT(m_GameLogic.IsValidCard(cbCardData) == true);
  1367. //效验参数
  1368. if (wChairID != m_wCurrentUser) return false;
  1369. if (m_GameLogic.IsValidCard(cbCardData) == false) return false;
  1370. if ((m_GameLogic.GetCardCount(m_cbCardIndex[wChairID]) - 2) % 3 != 0)
  1371. {
  1372. return false;
  1373. }
  1374. //“吃”的不能出(一圈内),特例:大吊车时(即只剩两张牌)
  1375. if (m_cbOptCard[wChairID] == cbCardData)
  1376. {
  1377. return false;
  1378. }
  1379. //删除扑克
  1380. if (m_GameLogic.RemoveCard(m_cbCardIndex[wChairID], cbCardData) == false)
  1381. {
  1382. ASSERT(FALSE);
  1383. return false;
  1384. }
  1385. ZeroMemory(&m_cbOptCard[wChairID], sizeof(m_cbOptCard[wChairID]));
  1386. //清除记忆库
  1387. ZeroMemory(&m_cbLastDisCardData[wChairID], sizeof(m_cbLastDisCardData[wChairID]));
  1388. m_cbLastDisCount[wChairID] = 0;
  1389. //for (BYTE i = 0; i < GAME_PLAYER; i++)
  1390. //{
  1391. // if (i == wChairID)continue;
  1392. // m_cbLastDisCardData[i][m_cbLastDisCount[i]++] = cbCardData;//打出得牌,放到其他玩家得记忆库里面
  1393. //}
  1394. //m_bSendStatus = true;
  1395. //if (m_bGangStatus)
  1396. //{
  1397. //m_OutLastLaiZiData = 0; //最后杠牌数据,断线重连用的着
  1398. //m_bGangStatus = false;
  1399. ZeroMemory(m_bUsersGangStatus, GAME_PLAYER);
  1400. m_bGangOption = 0;
  1401. m_GangPrivedUserID = -1;
  1402. //m_bGangOutStatus = true;
  1403. //}
  1404. m_cbUserAction[wChairID] = WIK_NULL;
  1405. m_cbPerformAction[wChairID] = WIK_NULL;
  1406. //出牌记录
  1407. m_cbOutCardCount++;
  1408. m_wOutCardUser = wChairID; //记录出牌人
  1409. m_cbOutCardData = cbCardData; //记录出牌数据
  1410. m_TabbOutCardCout[wChairID] = 0; //可以打出的牌就听牌的个数
  1411. ZeroMemory(m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID])); //具体打哪几张牌
  1412. ZeroMemory(m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  1413. ZeroMemory(m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  1414. BYTE FanHui[MAX_INDEX] = { 0 };
  1415. /*m_GameLogic.IsCanChangCardAndCount(m_cbCardIndex[wChairID], FanHui);
  1416. if (m_GameLogic.IsTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], FanHui))
  1417. {*/
  1418. OutTingCard(wChairID, m_GameLogic.SwitchToCardIndex(m_cbOutCardData));
  1419. //}
  1420. //构造数据
  1421. CMD_S_OutCard OutCard;
  1422. OutCard.wOutCardUser = wChairID;
  1423. OutCard.cbOutCardData = cbCardData;
  1424. OutCard.bOptType = 0;
  1425. SparrowMaJiang::PB_CS_S_OutCard Card;
  1426. Card.set_woutcarduser(OutCard.wOutCardUser);
  1427. Card.set_cboutcarddata(OutCard.cbOutCardData);
  1428. Card.set_bopttype(OutCard.bOptType);
  1429. //发送数据
  1430. std::string pbdata = Card.SerializePartialAsString();
  1431. RepayRecord(INVALID_CHAIR, SUB_S_OUT_CARD, (void*)pbdata.c_str(), pbdata.length());
  1432. //发送消息
  1433. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OUT_CARD, (void*)pbdata.c_str(), pbdata.length());
  1434. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OUT_CARD, (void*)pbdata.c_str(), pbdata.length());
  1435. m_wProvideUser = wChairID;
  1436. m_cbProvideCard = cbCardData;
  1437. //用户切换
  1438. if (m_bTwoPlayerFlag)
  1439. {
  1440. m_wCurrentUser = (wChairID + 2) % GAME_PLAYER;
  1441. }
  1442. else
  1443. {
  1444. m_wCurrentUser = (wChairID + 1) % mPlayGameUserCount;
  1445. }
  1446. //响应判断
  1447. //推倒胡,增加玩家出的牌如果是最后一张(出牌后无牌可发),此时不允许其他玩家有吃碰杠的操作。直接流局。
  1448. bool bAroseAction = false;
  1449. if (m_cbLeftCardCount==0)
  1450. {
  1451. bAroseAction = false;
  1452. }
  1453. else
  1454. {
  1455. bAroseAction = EstimateUserRespond(wChairID, cbCardData, EstimatKind_OutCard);
  1456. }
  1457. //派发扑克
  1458. if (bAroseAction == false)
  1459. {
  1460. DispatchCardData(m_wCurrentUser);
  1461. }
  1462. return true;
  1463. }
  1464. //用户操作
  1465. bool CTableFrameSink_tdh::OnUserOperateCard(WORD wChairID, int cbOperateCode, BYTE cbOperateCard, BYTE cbCaiShenCard[4])
  1466. {
  1467. //效验状态
  1468. ASSERT(m_pITableFrame->GetGameStatus() == GS_MJ_PLAY);
  1469. if (m_pITableFrame->GetGameStatus() != GS_MJ_PLAY)
  1470. return true;
  1471. //效验用户 注意:机器人有可能发生此断言
  1472. //ASSERT((wChairID==m_wCurrentUser)||(m_wCurrentUser==INVALID_CHAIR));
  1473. if ((wChairID != m_wCurrentUser) && (m_wCurrentUser != INVALID_CHAIR))
  1474. return true;
  1475. tagGangCardResult GangCardResult;
  1476. ZeroMemory(&GangCardResult, sizeof(GangCardResult));
  1477. //被动动作
  1478. if (m_wCurrentUser == INVALID_CHAIR&&wChairID != m_wProvideUser)//表示有人出牌后,下一个人还未摸牌这段时间内,有人对上一张出牌有吃胡、杠、碰等操作
  1479. {
  1480. //效验状态
  1481. if (m_bResponse[wChairID] == true)
  1482. return true;
  1483. if ((cbOperateCode != WIK_NULL) && ((m_cbUserAction[wChairID] & cbOperateCode) == 0))
  1484. return true;
  1485. //变量定义
  1486. WORD wTargetUser = wChairID;
  1487. int cbTargetAction = cbOperateCode;
  1488. //设置变量
  1489. m_bResponse[wChairID] = true;
  1490. m_cbPerformAction[wChairID] = cbOperateCode;
  1491. m_cbOperateCard[wChairID] = cbOperateCard;
  1492. CopyMemory(m_cbOperateCaiCard[wChairID], cbCaiShenCard, sizeof(cbCaiShenCard));
  1493. //执行动作的优先级判断, WIK_CHI_HU 大于 WIK_PENG 大于 [WIK_RIGHT or WIK_CENTER or WIK_LEFT]
  1494. WORD TempUser = m_wProvideUser;
  1495. OperatorPriority(TempUser, wTargetUser, cbTargetAction);
  1496. if (m_bResponse[wTargetUser] == false)//操作判断
  1497. {
  1498. if (cbOperateCode == WIK_NULL)
  1499. m_cbLastDisCardData[wChairID][m_cbLastDisCount[wChairID]++] = m_cbProvideCard;
  1500. return true;
  1501. }
  1502. //放弃操作
  1503. if (m_bQiangGang&&cbOperateCard == 0 && cbTargetAction &WIK_ZI_MO)//此处if 主要用于解决,用户抢杠胡那一刻,断线重连。客户端不知道用户抢的那张牌。所以必须后台强制处理一下。
  1504. {
  1505. m_cbOperateCard[wTargetUser] = m_cbProvideCard;
  1506. }
  1507. else
  1508. {
  1509. m_bQiangGang = false;
  1510. }
  1511. if (cbOperateCode == WIK_NULL &&cbTargetAction == WIK_NULL)
  1512. {
  1513. //用户状态
  1514. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  1515. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  1516. ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard));
  1517. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  1518. //当该用户点过时 加入该张牌
  1519. //if(wTargetUser==wChairID)
  1520. //{
  1521. m_cbLastDisCardData[wTargetUser][m_cbLastDisCount[wTargetUser]++] = m_cbProvideCard;
  1522. //}
  1523. if (m_wCurrentUser == INVALID_CHAIR)
  1524. DispatchCardData(m_wResumeUser);
  1525. return true;
  1526. }
  1527. //变量定义
  1528. BYTE cbTargetCard = m_cbOperateCard[wTargetUser];
  1529. BYTE cbTargetCaiCard[4] = { 0 };
  1530. CopyMemory(cbTargetCaiCard, m_cbOperateCaiCard[wTargetUser], sizeof(cbTargetCaiCard));
  1531. if (cbTargetCard != m_cbProvideCard)//校验很重要
  1532. {
  1533. m_bResponse[wTargetUser] = false;
  1534. ASSERT(false);
  1535. return false;
  1536. }
  1537. //出牌变量
  1538. m_cbOutCardData = 0;
  1539. //m_bSendStatus = true;
  1540. m_wOutCardUser = INVALID_CHAIR;
  1541. //m_bEnjoinChiHu[wTargetUser] = true;
  1542. //用户状态
  1543. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  1544. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  1545. ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard));
  1546. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  1547. //组合扑克
  1548. if (cbTargetAction&(WIK_LEFT | WIK_CENTER | WIK_RIGHT | WIK_PENG | WIK_MING_GANG))
  1549. {
  1550. ASSERT(m_cbWeaveItemCount[wTargetUser] < 4);
  1551. if (m_cbWeaveItemCount[wTargetUser] > 4)return false;
  1552. WORD wIndex = m_cbWeaveItemCount[wTargetUser]++;
  1553. m_WeaveItemArray[wTargetUser][wIndex].cbPublicCard = TRUE;
  1554. m_WeaveItemArray[wTargetUser][wIndex].cbCenterCard = cbTargetCard;
  1555. m_WeaveItemArray[wTargetUser][wIndex].cbWeaveKind = cbTargetAction;
  1556. m_WeaveItemArray[wTargetUser][wIndex].wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser;
  1557. //本轮操作后 不允许打该张牌
  1558. m_cbOptCard[wTargetUser] = cbTargetCard;
  1559. }
  1560. if (cbTargetAction &WIK_ZI_MO)//此动作为抢杠胡才会促发
  1561. {
  1562. m_bQiangGang = true;
  1563. //m_bGangStatus = false;
  1564. ZeroMemory(m_bUsersGangStatus, GAME_PLAYER);
  1565. m_wCurrentUser = wTargetUser;
  1566. m_wProvideUser = m_wProvideUser;
  1567. m_cbSendCardData = m_cbProvideCard;
  1568. m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;
  1569. m_cbUserAction[wTargetUser] = WIK_ZI_MO;
  1570. OnUserOperateCard(wTargetUser, WIK_ZI_MO, m_cbProvideCard, NULL);
  1571. return true;
  1572. }
  1573. if (cbTargetAction& WIK_CHI_HU&&mCanFangChong==TRUE)
  1574. {
  1575. int TempAction = 0;
  1576. CChiHuRight chr;
  1577. BYTE TaiShu = 0;
  1578. TempAction |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[wTargetUser], m_WeaveItemArray[wTargetUser],
  1579. m_cbWeaveItemCount[wTargetUser], m_cbProvideCard, chr, TaiShu);
  1580. if (TempAction == WIK_NULL)
  1581. {
  1582. ASSERT(false);
  1583. return false;
  1584. }
  1585. m_HuPai[wTargetUser]++;
  1586. CMD_S_OperateResult OperateResult;
  1587. OperateResult.wOperateUser = wTargetUser;
  1588. OperateResult.cbOperateCard = cbOperateCard;
  1589. OperateResult.cbOperateCode = cbOperateCode;
  1590. OperateResult.wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser;
  1591. WORD paitype = bHuPaiType(chr);
  1592. if (!(chr&ZJ_TAI_CaiDiao).IsEmpty())
  1593. {
  1594. OperateResult.cbOperateCode = WIK_CAIDIAO;
  1595. }
  1596. if (!(chr&ZJ_TAI_SiCaiHu).IsEmpty())
  1597. {
  1598. OperateResult.cbOperateCode = WIK_SI_CAIHU;
  1599. }
  1600. OperateResult.cbActionMask = TaiShu | (paitype << 16);
  1601. ZeroMemory(OperateResult.cbActionCard, sizeof(OperateResult.cbActionCard));
  1602. SparrowMaJiang::PB_CS_S_OperateResult Result;
  1603. Result.set_woperateuser(OperateResult.wOperateUser);
  1604. Result.set_cboperatecard(OperateResult.cbOperateCard);
  1605. Result.set_cboperatecode(OperateResult.cbOperateCode);
  1606. Result.set_wprovideuser(OperateResult.wProvideUser);
  1607. for (BYTE j = 0; j < 4; j++)
  1608. {
  1609. Result.add_cbcaishencard(OperateResult.cbCaiShenCard[j]);
  1610. }
  1611. Result.set_cbactionmask(OperateResult.cbActionMask);
  1612. for (BYTE j = 0; j < 6; j++)
  1613. {
  1614. Result.add_cbactioncard(OperateResult.cbActionCard[j]);
  1615. }
  1616. //发送数据
  1617. std::string pbdata = Result.SerializePartialAsString();
  1618. RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  1619. //发送消息
  1620. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  1621. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  1622. //积分变动
  1623. CMD_S_GangScore gs;
  1624. ZeroMemory(&gs, sizeof(gs));
  1625. gs.wChairId = wTargetUser;
  1626. gs.cbOperateCode = WIK_CHI_HU;
  1627. int TempInfoScore = 0;
  1628. WORD LaoZhuang = m_wBankerUser & 0x00ff;
  1629. if (LianXuHuPai[LaoZhuang] >= 2)
  1630. {
  1631. TaiShu *= 2;
  1632. }
  1633. CaculationScore(wTargetUser, TaiShu, Win_FangPao, m_wProvideUser, chr, gs);
  1634. LianXuHuPai[wTargetUser]++;
  1635. SparrowMaJiang::PB_CS_S_GangScore GangScore;
  1636. GangScore.set_cboperatecode(gs.cbOperateCode);
  1637. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  1638. {
  1639. GangScore.add_cbwanjiascore(gs.cbWanJiaScore[j]);
  1640. GangScore.add_lgangscore(gs.lGangScore[j]);
  1641. }
  1642. GangScore.set_wchairid(gs.wChairId);
  1643. std::string pbscore = GangScore.SerializePartialAsString();
  1644. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  1645. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  1646. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  1647. {
  1648. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  1649. {
  1650. continue;
  1651. }
  1652. gs.cbWanJiaScore[i] = m_lGameScore[i];
  1653. }
  1654. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  1655. {
  1656. GangScore.set_cbwanjiascore(j, gs.cbWanJiaScore[j]);
  1657. }
  1658. std::string pbscores = GangScore.SerializePartialAsString();
  1659. RepayRecord(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscores.c_str(), pbscores.length());
  1660. OnEventGameConclude(wTargetUser, NULL, GER_NORMAL);
  1661. return true;
  1662. }
  1663. DeleteCaiShenCard(wTargetUser, cbTargetCaiCard, cbTargetAction, cbTargetCard);
  1664. //杠牌处理
  1665. if (cbTargetAction & (WIK_MING_GANG | WIK_DAN_MING_GANG | WIK_SHUANG_MING_GANG | WIK_SAN_MING_GANG))
  1666. {
  1667. int cbActionMask = WIK_NULL;
  1668. WORD cbActionCard[6] = { 0 };
  1669. HttpOperateResult(wTargetUser, cbTargetCaiCard, cbTargetAction, cbTargetCard, cbActionMask, cbActionCard);
  1670. //设置用户
  1671. m_wCurrentUser = wTargetUser;
  1672. m_bGangOption = cbTargetAction;
  1673. m_GangPrivedUserID = m_wProvideUser;
  1674. //本轮操作后 不允许打该张牌
  1675. m_cbOptCard[wTargetUser] = cbTargetCard;
  1676. m_cbLastGangCard = cbOperateCard;
  1677. DispatchCardData(wTargetUser, true);
  1678. return true;
  1679. }
  1680. else
  1681. {
  1682. WORD cbActionCard[6] = { 0 };
  1683. int cbActionMask = NULL;
  1684. ZeroMemory(m_TabbTingCardData[wTargetUser], sizeof(m_TabbTingCardData[wTargetUser])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  1685. TingCard(wTargetUser);
  1686. HttpOperateResult(wTargetUser, cbTargetCaiCard, cbTargetAction, cbTargetCard, cbActionMask, cbActionCard);
  1687. //设置用户
  1688. m_wCurrentUser = wTargetUser;
  1689. if (m_TabbOutCardCout[wTargetUser] > 0)//有听牌就发一个听牌协议
  1690. {
  1691. HttpTingCard(wTargetUser);
  1692. }
  1693. return true;
  1694. }
  1695. ASSERT(false);
  1696. return false;
  1697. }
  1698. //主动动作
  1699. if (m_wCurrentUser == wChairID) //如果是摸牌用户的操作,比如自摸或者自杠
  1700. {
  1701. if (cbOperateCode == WIK_NULL)
  1702. {
  1703. //用户状态
  1704. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  1705. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  1706. ZeroMemory(m_cbOperateCard, sizeof(m_cbOperateCard));
  1707. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  1708. //发送扑克
  1709. return true;
  1710. }
  1711. //效验操作
  1712. if ((cbOperateCode == WIK_NULL) || ((m_cbUserAction[wChairID] & cbOperateCode) == 0))
  1713. return true;
  1714. //设置变量
  1715. //m_bSendStatus = true;
  1716. //m_bEnjoinChiHu[m_wCurrentUser]=true;
  1717. m_cbUserAction[m_wCurrentUser] = WIK_NULL;
  1718. m_cbPerformAction[m_wCurrentUser] = WIK_NULL;
  1719. bool bPublic = false;
  1720. //执行动作
  1721. if (cbOperateCode & (WIK_TIAN_ZI_MO | WIK_ZI_MO))
  1722. {
  1723. BYTE TempCardData = m_cbProvideCard;
  1724. if (m_cbProvideCard != m_cbSendCardData || m_cbProvideCard != cbOperateCard)
  1725. {
  1726. ASSERT(false);
  1727. return false;
  1728. }
  1729. int TempAction = 0;
  1730. CChiHuRight chr;
  1731. BYTE TaiShu = 1;
  1732. m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]--;
  1733. TempAction |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID],
  1734. m_cbWeaveItemCount[wChairID], m_cbSendCardData, chr, TaiShu, m_bUsersGangStatus[wChairID], m_bQiangGang);
  1735. m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;
  1736. if (TempAction == WIK_NULL)
  1737. {
  1738. ASSERT(false);
  1739. return false;
  1740. }
  1741. m_HuPai[wChairID]++;
  1742. CMD_S_OperateResult OperateResult;
  1743. OperateResult.wOperateUser = wChairID;
  1744. OperateResult.cbOperateCard = cbOperateCard;
  1745. OperateResult.cbOperateCode = cbOperateCode;
  1746. OperateResult.wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wChairID : m_wProvideUser;
  1747. WORD paitype = bHuPaiType(chr);
  1748. if (m_bUsersGangStatus[wChairID] == true)
  1749. {
  1750. paitype |= ZJ_TAI_GangKai;
  1751. chr |= ZJ_TAI_GangKai;
  1752. }
  1753. if (m_bQiangGang == true)
  1754. {
  1755. paitype |= ZJ_TAI_QiangGang;
  1756. chr |= ZJ_TAI_QiangGang;
  1757. }
  1758. if (!(chr&ZJ_TAI_CaiDiao).IsEmpty())
  1759. {
  1760. OperateResult.cbOperateCode = WIK_CAIDIAO;
  1761. }
  1762. if (!(chr&ZJ_TAI_SiCaiHu).IsEmpty())
  1763. {
  1764. OperateResult.cbOperateCode = WIK_SI_CAIHU;
  1765. }
  1766. if (!(chr&ZJ_TAI_GangKai).IsEmpty())
  1767. {
  1768. OperateResult.cbOperateCode = WIK_GANG_SHANG_KAI;
  1769. }
  1770. if (!(chr&ZJ_TAI_QiangGang).IsEmpty())
  1771. {
  1772. OperateResult.cbOperateCode = WIK_Qiang_GANG;
  1773. m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]--;
  1774. }
  1775. OperateResult.cbActionMask = TaiShu | (paitype << 16);
  1776. //OperateResult.cbActionMask = paitype;
  1777. ZeroMemory(OperateResult.cbActionCard, sizeof(OperateResult.cbActionCard));
  1778. SparrowMaJiang::PB_CS_S_OperateResult Result;
  1779. Result.set_woperateuser(OperateResult.wOperateUser);
  1780. Result.set_cboperatecard(OperateResult.cbOperateCard);
  1781. Result.set_cboperatecode(OperateResult.cbOperateCode);
  1782. Result.set_wprovideuser(OperateResult.wProvideUser);
  1783. for (BYTE j = 0; j < 4; j++)
  1784. {
  1785. Result.add_cbcaishencard(OperateResult.cbCaiShenCard[j]);
  1786. }
  1787. Result.set_cbactionmask(OperateResult.cbActionMask);
  1788. for (BYTE j = 0; j < 6; j++)
  1789. {
  1790. Result.add_cbactioncard(OperateResult.cbActionCard[j]);
  1791. }
  1792. //发送数据
  1793. std::string pbdata = Result.SerializePartialAsString();
  1794. RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  1795. //发送消息
  1796. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  1797. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  1798. //积分变动
  1799. CMD_S_GangScore gs;
  1800. ZeroMemory(&gs, sizeof(gs));
  1801. gs.wChairId = wChairID;
  1802. gs.cbOperateCode = WIK_ZI_MO;
  1803. if (m_bQiangGang == true){
  1804. gs.cbOperateCode = WIK_Qiang_GANG;
  1805. }
  1806. else
  1807. {
  1808. gs.cbOperateCode = WIK_ZI_MO;
  1809. }
  1810. int TempInfoScore = 0;
  1811. WORD LaoZhuang = m_wBankerUser & 0x00ff;
  1812. if (LianXuHuPai[LaoZhuang] >= 2)
  1813. {
  1814. TaiShu *= 2;
  1815. }
  1816. CaculationScore(wChairID, TaiShu, Win_ZiMo, m_wProvideUser, chr, gs);
  1817. LianXuHuPai[wChairID]++;
  1818. SparrowMaJiang::PB_CS_S_GangScore GangScore;
  1819. GangScore.set_cboperatecode(gs.cbOperateCode);
  1820. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  1821. {
  1822. GangScore.add_cbwanjiascore(gs.cbWanJiaScore[j]);
  1823. GangScore.add_lgangscore(gs.lGangScore[j]);
  1824. }
  1825. GangScore.set_wchairid(gs.wChairId);
  1826. std::string pbscore = GangScore.SerializePartialAsString();
  1827. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  1828. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  1829. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  1830. {
  1831. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  1832. {
  1833. continue;
  1834. }
  1835. gs.cbWanJiaScore[i] = m_lGameScore[i];
  1836. }
  1837. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  1838. {
  1839. GangScore.set_cbwanjiascore(j, gs.cbWanJiaScore[j]);
  1840. }
  1841. std::string pbrecord = GangScore.SerializePartialAsString();
  1842. RepayRecord(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbrecord.c_str(), pbrecord.length());
  1843. OnEventGameConclude(wChairID, NULL, GER_NORMAL);
  1844. return true;
  1845. }
  1846. if (cbOperateCode & (WIK_DAN_BU_GANG | WIK_BU_GANG))
  1847. {
  1848. DeleteCard(wChairID, cbCaiShenCard, cbOperateCode, cbOperateCard);
  1849. int cbActionMask = WIK_NULL;
  1850. WORD cbActionCard[6] = { 0 };
  1851. HttpOperateResult(wChairID, cbCaiShenCard, cbOperateCode, cbOperateCard, cbActionMask, cbActionCard);
  1852. m_cbLastGangCard = cbOperateCard;
  1853. //响应判断
  1854. m_wProvideUser = wChairID;
  1855. m_bQiangGang = true;
  1856. m_bUsersGangStatus[wChairID] = true;
  1857. bool bAroseAction = EstimateUserRespond(wChairID, cbOperateCard, EstimatKind_GangCard);//补杠,别人可以抢杠胡
  1858. //派发扑克
  1859. if (bAroseAction == false)
  1860. {
  1861. m_bQiangGang = false;
  1862. m_bGangOption = cbOperateCode;
  1863. m_GangPrivedUserID = m_wCurrentUser;
  1864. DispatchCardData(m_wCurrentUser, true);
  1865. }
  1866. else
  1867. {
  1868. //m_bGangStatus = false;
  1869. m_bQiangGang = true;
  1870. }
  1871. return true;
  1872. }
  1873. if (cbOperateCode&WIK_AN_GANG)
  1874. {
  1875. m_cbLastGangCard = cbOperateCard;
  1876. }
  1877. DeleteCard(wChairID, cbCaiShenCard, cbOperateCode, cbOperateCard);
  1878. int cbActionMask = WIK_NULL;
  1879. WORD cbActionCard[6] = { 0 };
  1880. HttpOperateResult(wChairID, cbCaiShenCard, cbOperateCode, cbOperateCard, cbActionMask, cbActionCard);
  1881. DispatchCardData(wChairID, true);
  1882. return true;
  1883. }
  1884. return true;
  1885. }
  1886. //发送操作
  1887. bool CTableFrameSink_tdh::SendOperateNotify()
  1888. {
  1889. //发送提示
  1890. for (WORD i = 0; i < mPlayGameUserCount; i++)
  1891. {
  1892. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  1893. {
  1894. continue;
  1895. }
  1896. if (m_cbUserAction[i] != WIK_NULL)
  1897. {
  1898. //构造数据
  1899. CMD_S_OperateNotify OperateNotify;
  1900. OperateNotify.wResumeUser = m_wResumeUser;
  1901. OperateNotify.cbActionCard = m_cbProvideCard;
  1902. OperateNotify.cbActionMask = m_cbUserAction[i];
  1903. SparrowMaJiang::PB_CS_S_OperateNotify Notify;
  1904. Notify.set_wresumeuser(OperateNotify.wResumeUser);
  1905. Notify.set_cbactioncard(OperateNotify.cbActionCard);
  1906. Notify.set_cbactionmask(OperateNotify.cbActionMask);
  1907. std::string pbdata = Notify.SerializePartialAsString();
  1908. //发送数据
  1909. m_pITableFrame->SendTableData(i, SUB_S_OPERATE_NOTIFY, (void*)pbdata.c_str(), pbdata.length());
  1910. ////-沙 前端需要展示提示数据
  1911. OperateNotify.wResumeUser = i;
  1912. Notify.set_wresumeuser(OperateNotify.wResumeUser);
  1913. std::string pbdatas = Notify.SerializePartialAsString();
  1914. RepayRecord(i, SUB_S_OPERATE_NOTIFY, (void*)pbdatas.c_str(), pbdatas.length());
  1915. }
  1916. }
  1917. //m_pITableFrame->SendLookonData(i, SUB_S_OPERATE_NOTIFY, &OperateNotify, sizeof(OperateNotify));
  1918. return true;
  1919. }
  1920. //派发扑克,wCurrentUser表示给哪个用户,bTail表示是末尾拿牌还是不是,true表示末尾,同时标示杠牌抓牌
  1921. bool CTableFrameSink_tdh::DispatchCardData(WORD wCurrentUser, bool bTail)
  1922. {
  1923. //状态效验
  1924. ASSERT(wCurrentUser != INVALID_CHAIR);
  1925. if (wCurrentUser == INVALID_CHAIR)
  1926. return false;
  1927. //丢弃扑克
  1928. if ((m_wOutCardUser != INVALID_CHAIR) && (m_cbOutCardData != 0))
  1929. {
  1930. m_cbDiscardCount[m_wOutCardUser]++;
  1931. m_cbDiscardCard[m_wOutCardUser][m_cbDiscardCount[m_wOutCardUser] - 1] = m_cbOutCardData;
  1932. }
  1933. //清除当前玩家的碰 杠
  1934. ZeroMemory(&m_cbOptCard[wCurrentUser], sizeof(m_cbOptCard[wCurrentUser]));
  1935. //荒庄结束
  1936. if (m_cbLeftCardCount == 0)
  1937. {
  1938. //m_cbChiHuCard = 0;
  1939. m_wProvideUser = INVALID_CHAIR;
  1940. bIsHuang = true;
  1941. OnEventGameConclude(m_wProvideUser, NULL, GER_NORMAL);
  1942. return true;
  1943. }
  1944. //设置变量
  1945. m_cbOutCardData = 0;
  1946. m_wCurrentUser = wCurrentUser; //记录拿牌人的索引。
  1947. m_wOutCardUser = INVALID_CHAIR; //置空上次出牌用户的索引
  1948. BYTE ActionCard[3] = { 0 }; //操作牌值
  1949. BYTE AnActionCount = 0;
  1950. //发送扑克
  1951. m_cbSendCardCount++;
  1952. --m_cbLeftCardCount;//剩余牌减少
  1953. m_cbSendCardData = m_cbRepertoryCard[--m_cbShiJiLeftCardCount];//实际剩余牌减少
  1954. CChiHuRight chr;
  1955. BYTE TaiShu = 0;
  1956. m_bUsersGangStatus[wCurrentUser] = bTail;
  1957. m_cbUserAction[wCurrentUser] |= m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[wCurrentUser], m_WeaveItemArray[wCurrentUser],
  1958. m_cbWeaveItemCount[wCurrentUser], m_cbSendCardData, chr, TaiShu, bTail);
  1959. //加牌
  1960. m_cbCardIndex[wCurrentUser][m_GameLogic.SwitchToCardIndex(m_cbSendCardData)]++;
  1961. //设置变量
  1962. m_wProvideUser = wCurrentUser;
  1963. m_cbProvideCard = m_cbSendCardData;
  1964. //杠牌判断
  1965. tagGangCardResult GangCardResult;
  1966. ZeroMemory(&GangCardResult, sizeof(GangCardResult));
  1967. if (m_cbLeftCardCount > 0)
  1968. {
  1969. bool bCanAnGang = true;//此true表示自己抓牌,false表示表人打得去检验杠,
  1970. m_cbUserAction[wCurrentUser] |= m_GameLogic.AnalyseGangCard(m_cbCardIndex[wCurrentUser],
  1971. m_WeaveItemArray[wCurrentUser], m_cbWeaveItemCount[wCurrentUser], GangCardResult);
  1972. }
  1973. //听牌计算
  1974. // m_TabbOutCardCout[wCurrentUser] = 0; //可以打出的牌就听牌的个数
  1975. // ZeroMemory(m_TabbOutCardData[wCurrentUser], sizeof(m_TabbOutCardData[wCurrentUser])); //具体打哪几张牌
  1976. // ZeroMemory(m_TabbTingCardCount[wCurrentUser], sizeof(m_TabbTingCardCount[wCurrentUser])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  1977. // ZeroMemory(m_TabbTingCardData[wCurrentUser], sizeof(m_TabbTingCardData[wCurrentUser])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  1978. if (!(m_cbUserAction[wCurrentUser] & WIK_ZI_MO))
  1979. TingCard(m_wCurrentUser);
  1980. //构造数据
  1981. CMD_S_SendCard SendCard;
  1982. ZeroMemory(&SendCard, sizeof(SendCard));
  1983. SendCard.wCurrentUser = wCurrentUser;
  1984. SendCard.bTail = bTail;
  1985. SendCard.bLeftCardCount = m_cbLeftCardCount;
  1986. SendCard.cbActionMask = m_cbUserAction[wCurrentUser];
  1987. SendCard.cbCardData = m_cbSendCardData;
  1988. SparrowMaJiang::PB_CS_S_SendCard Card;
  1989. Card.set_wcurrentuser(SendCard.wCurrentUser);
  1990. Card.set_btail(SendCard.bTail);
  1991. Card.set_bleftcardcount(SendCard.bLeftCardCount);
  1992. Card.set_cbactionmask(SendCard.cbActionMask);
  1993. Card.set_cbcarddata(SendCard.cbCardData);
  1994. std::string pbdatas = Card.SerializePartialAsString();
  1995. RepayRecord(INVALID_CHAIR, SUB_S_SEND_CARD, (void*)pbdatas.c_str(), pbdatas.length());
  1996. //发送数据
  1997. for (int i = 0; i < mPlayGameUserCount; i++)
  1998. {
  1999. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2000. {
  2001. continue;
  2002. }
  2003. if (i == m_wCurrentUser)
  2004. {//发送给摸牌玩家的数据,附带麻将牌面数据
  2005. for (BYTE j = 0; j < GangCardResult.cbCardCount; j++)//先暗杠后补杠牌数据
  2006. SendCard.cbActionCard[j] = GangCardResult.cbCardData[j];
  2007. SendCard.cbCardData = m_cbSendCardData;
  2008. SendCard.cbActionMask = m_cbUserAction[wCurrentUser];
  2009. for (BYTE j = 0; j < GangCardResult.cbCardCount; j++)
  2010. {
  2011. Card.add_cbactioncard(SendCard.cbActionCard[j]);
  2012. }
  2013. Card.set_cbactionmask(SendCard.cbActionMask);
  2014. Card.set_cbcarddata(SendCard.cbCardData);
  2015. std::string pbdata = Card.SerializePartialAsString();
  2016. m_pITableFrame->SendTableData(i, SUB_S_SEND_CARD, (void*)pbdata.c_str(), pbdata.length());
  2017. }
  2018. else
  2019. {//发送给其他玩家的数据,没有麻将牌面数据(防止客户端作弊)
  2020. ZeroMemory(SendCard.cbActionCard, sizeof(SendCard.cbActionCard));
  2021. SendCard.cbCardData = 0x00;
  2022. SendCard.cbActionMask = 0x0000;
  2023. for (BYTE j = 0; j < GangCardResult.cbCardCount; j++)
  2024. {
  2025. Card.add_cbactioncard(SendCard.cbActionCard[j]);
  2026. }
  2027. Card.set_cbactionmask(SendCard.cbActionMask);
  2028. Card.set_cbcarddata(SendCard.cbCardData);
  2029. std::string pbdata = Card.SerializePartialAsString();
  2030. m_pITableFrame->SendTableData(i, SUB_S_SEND_CARD, (void*)pbdata.c_str(), pbdata.length());
  2031. }
  2032. }
  2033. SendCard.cbActionMask = 0;
  2034. SendCard.cbCardData = 0;
  2035. Card.set_cbactionmask(SendCard.cbActionMask);
  2036. Card.set_cbcarddata(SendCard.cbCardData);
  2037. std::string pbdata = Card.SerializePartialAsString();
  2038. //给旁观者的抓牌动作
  2039. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_SEND_CARD, (void*)pbdata.c_str(), pbdata.length());
  2040. if (m_TabbOutCardCout[m_wCurrentUser] > 0)//有听牌就发一个听牌协议
  2041. {
  2042. HttpTingCard(m_wCurrentUser);
  2043. }
  2044. return true;
  2045. }
  2046. //响应判断
  2047. bool CTableFrameSink_tdh::EstimateUserRespond(WORD wCenterUser, BYTE cbCenterCard, enEstimatKind EstimatKind)
  2048. {
  2049. //财神牌不判断
  2050. if (m_GameLogic.IsMagicCard(cbCenterCard))return false;
  2051. //变量定义
  2052. bool bAroseAction[GAME_PLAYER] = { false };
  2053. bool mbAroseAction = false;
  2054. //吃牌判断,出牌玩家下家位置
  2055. WORD wEatUser = (wCenterUser + 1) % mPlayGameUserCount;
  2056. if (m_bTwoPlayerFlag&&wEatUser == TowMjNullseat)
  2057. {
  2058. wEatUser++;
  2059. }
  2060. //用户状态
  2061. ZeroMemory(m_bResponse, sizeof(m_bResponse));
  2062. ZeroMemory(m_cbUserAction, sizeof(m_cbUserAction));
  2063. ZeroMemory(m_cbPerformAction, sizeof(m_cbPerformAction));
  2064. //动作判断
  2065. for (WORD nUserIndex = 0; nUserIndex < mPlayGameUserCount; nUserIndex++)
  2066. {
  2067. if (m_bTwoPlayerFlag&&nUserIndex == TowMjNullseat)
  2068. {
  2069. continue;
  2070. }
  2071. //用户过滤
  2072. if (wCenterUser == nUserIndex) continue;
  2073. //出牌类型
  2074. if (EstimatKind == EstimatKind_OutCard)
  2075. {
  2076. CChiHuRight Chr;
  2077. BYTE TaiShu = 0;
  2078. int wAction = 0;
  2079. if (mCanFangChong)
  2080. {
  2081. wAction = m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[nUserIndex], m_WeaveItemArray[nUserIndex], m_cbWeaveItemCount[nUserIndex], cbCenterCard, Chr, TaiShu);
  2082. if (wAction != WIK_NULL&& (Chr&ZJ_TAI_CaiDiao).IsEmpty())
  2083. {
  2084. m_cbUserAction[nUserIndex] = WIK_CHI_HU;
  2085. // if (m_cbOutCardCount == 1 && (m_wBankerUser & 0xff) != nUserIndex)
  2086. // {
  2087. // m_cbUserAction[nUserIndex] = WIK_DI_CHIHU;
  2088. // }
  2089. }
  2090. }
  2091. //确定只有下家才能吃牌
  2092. if (wEatUser == nUserIndex)
  2093. {
  2094. m_cbUserAction[nUserIndex] |= m_GameLogic.EstimateEatCard(m_cbCardIndex[nUserIndex], cbCenterCard);
  2095. }
  2096. //碰牌判断
  2097. m_cbUserAction[nUserIndex] |= m_GameLogic.EstimatePengCard(m_cbCardIndex[nUserIndex], cbCenterCard);
  2098. //杠牌判断
  2099. if (m_cbLeftCardCount > 0)
  2100. {
  2101. m_cbUserAction[nUserIndex] |= m_GameLogic.EstimateGangCard(m_cbCardIndex[nUserIndex], cbCenterCard);
  2102. }
  2103. }
  2104. if (EstimatKind == EstimatKind_GangCard)
  2105. {
  2106. CChiHuRight Chr;
  2107. BYTE TaiShu = 0;
  2108. int wAction = 0;
  2109. wAction = m_GameLogic.AnalyseChiHuCard(m_cbCardIndex[nUserIndex], m_WeaveItemArray[nUserIndex], m_cbWeaveItemCount[nUserIndex], cbCenterCard, Chr, TaiShu);
  2110. //财吊玩家,不能抢杠胡,只能自摸
  2111. if (wAction&WIK_ZI_MO && (Chr&ZJ_TAI_CaiDiao).IsEmpty())
  2112. {
  2113. m_cbUserAction[nUserIndex] |= WIK_ZI_MO;
  2114. }
  2115. }
  2116. //结果判断
  2117. if (m_cbUserAction[nUserIndex] != WIK_NULL)
  2118. {
  2119. bAroseAction[nUserIndex] = true;
  2120. if (m_cbUserAction[nUserIndex] & (WIK_PENG | WIK_CHI_HU | WIK_PENG_PENG))
  2121. {
  2122. BYTE bTemp = 0;
  2123. //记忆牌有多少张
  2124. for (BYTE j = 0; j < m_cbLastDisCount[nUserIndex]; j++)
  2125. {
  2126. //如果在一圈中 记忆1个一样的牌 则不能操作
  2127. if (m_cbLastDisCardData[nUserIndex][j] == cbCenterCard)
  2128. {
  2129. m_cbUserAction[nUserIndex] = m_cbUserAction[nUserIndex] & (~(WIK_PENG | WIK_CHI_HU | WIK_PENG_PENG));
  2130. if (m_cbUserAction[nUserIndex] == WIK_NULL)
  2131. bAroseAction[nUserIndex] = false;
  2132. }
  2133. }
  2134. }
  2135. }
  2136. }
  2137. for (int nUserIndex = 0; nUserIndex < mPlayGameUserCount; nUserIndex++)
  2138. {
  2139. if (m_bTwoPlayerFlag&&nUserIndex == TowMjNullseat)
  2140. {
  2141. continue;
  2142. }
  2143. if (bAroseAction[nUserIndex] == true)
  2144. {
  2145. mbAroseAction = true;
  2146. break;
  2147. }
  2148. }
  2149. //结果处理
  2150. if (mbAroseAction == true)
  2151. {
  2152. //设置变量
  2153. m_wProvideUser = wCenterUser;
  2154. m_cbProvideCard = cbCenterCard;
  2155. m_wResumeUser = m_wCurrentUser;
  2156. m_wCurrentUser = INVALID_CHAIR;
  2157. //发送提示
  2158. SendOperateNotify();
  2159. return true;
  2160. }
  2161. return false;
  2162. }
  2163. //胡的这张牌 牌堆里面还有几张
  2164. //计算方式 服务器上剩余里面的牌,+其他三位位玩家手牌= 该胡牌个数
  2165. BYTE CTableFrameSink_tdh::RemainNum(WORD wChairId, const BYTE m_cbCard, BYTE cbOutCardIndex)
  2166. {
  2167. BYTE m_cbNum = 0;
  2168. BYTE mCard[MAX_INDEX] = { 0 }; //把所有当前用户可以看到的牌 都扔到这个数组中
  2169. BYTE TempIndex = m_GameLogic.SwitchToCardIndex(m_cbCard);
  2170. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  2171. {
  2172. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2173. {
  2174. continue;
  2175. }
  2176. for (BYTE j = 0; j < m_cbDiscardCount[i]; j++)//丢弃数
  2177. {
  2178. mCard[m_GameLogic.SwitchToCardIndex(m_cbDiscardCard[i][j])]++;
  2179. }
  2180. for (BYTE k = 0; k < m_cbWeaveItemCount[i]; k++)//摆出来的牌
  2181. {
  2182. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_PENG)
  2183. {
  2184. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 3;
  2185. }
  2186. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_LEFT)
  2187. {
  2188. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)]++;
  2189. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard + 1)]++;
  2190. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard + 2)]++;
  2191. }
  2192. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_RIGHT)
  2193. {
  2194. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)]++;
  2195. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard - 1)]++;
  2196. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard - 2)]++;
  2197. }
  2198. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_CENTER)
  2199. {
  2200. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)]++;
  2201. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard - 1)]++;
  2202. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard + 1)]++;
  2203. }
  2204. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_MING_GANG || (i == wChairId&&m_WeaveItemArray[i][k].cbWeaveKind == WIK_AN_GANG))
  2205. {
  2206. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 4;
  2207. }
  2208. if (m_WeaveItemArray[i][k].cbWeaveKind& (WIK_SHUANG_CAICHI | WIK_SHUANG_PENG | WIK_DAN_CHI))
  2209. {
  2210. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)]++;
  2211. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2212. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[1])]++;
  2213. }
  2214. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_DAN_PENG)
  2215. {
  2216. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 2;
  2217. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2218. }
  2219. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_DAN_MING_GANG || (i == wChairId && m_WeaveItemArray[i][k].cbWeaveKind == WIK_DAN_AN_GANG))
  2220. {
  2221. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 3;
  2222. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2223. }
  2224. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_SHUANG_MING_GANG || (i == wChairId && m_WeaveItemArray[i][k].cbWeaveKind == WIK_SHUANG_AN_GANG))
  2225. {
  2226. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 2;
  2227. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2228. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[1])]++;
  2229. }
  2230. if (m_WeaveItemArray[i][k].cbWeaveKind == WIK_SAN_MING_GANG || (i == wChairId && m_WeaveItemArray[i][k].cbWeaveKind == WIK_SAN_AN_GANG))
  2231. {
  2232. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] += 1;
  2233. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2234. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[1])]++;
  2235. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[2])]++;
  2236. }
  2237. if (i == wChairId && m_WeaveItemArray[i][k].cbWeaveKind == WIK_QUANG_AN_GANG)
  2238. {
  2239. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[0])]++;
  2240. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[1])]++;
  2241. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[2])]++;
  2242. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[3])]++;
  2243. }
  2244. if (m_WeaveItemArray[i][k].cbWeaveKind & (WIK_BU_GANG | WIK_DAN_BU_GANG))
  2245. {
  2246. for (int m = 0; m < 4; m++)
  2247. {
  2248. if (m_WeaveItemArray[i][k].cbMargicOffset[m] != 0)
  2249. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbMargicOffset[m])]++;
  2250. else
  2251. mCard[m_GameLogic.SwitchToCardIndex(m_WeaveItemArray[i][k].cbCenterCard)] ++;
  2252. }
  2253. }
  2254. }
  2255. }
  2256. //8个财神变7个 在加回来一个
  2257. //非包麻将 需要计算翻财神的那张牌
  2258. //BYTE cbMagicFirstIndex = m_GameLogic.SwitchToCardIndex(m_cbMagicSecondData);
  2259. //if (mCard[cbMagicFirstIndex] < 4)
  2260. //{
  2261. // mCard[cbMagicFirstIndex]++;
  2262. //}
  2263. //非包麻将 不需要把财神那张牌加入落地牌
  2264. //增加自己假设去掉的牌 这样才真正的标示 牌桌加手牌
  2265. mCard[cbOutCardIndex]++;
  2266. for (BYTE i = 0; i < MAX_INDEX; i++)
  2267. {
  2268. mCard[i] += m_cbCardIndex[wChairId][i];
  2269. }
  2270. m_cbNum = 4 - mCard[TempIndex];
  2271. if (m_GameLogic.SwitchToCardData(TempIndex)== m_cbMagicFirstData)
  2272. {
  2273. m_cbNum--;
  2274. }
  2275. ASSERT(m_cbNum >= 0 && m_cbNum <= 4);
  2276. if (m_cbNum < 0)m_cbNum = 0;
  2277. return m_cbNum;
  2278. }
  2279. //对手牌遍历,并把该牌减去,然后分析这13张拍能胡什么
  2280. bool CTableFrameSink_tdh::TingCard(WORD wChairID)
  2281. {
  2282. m_PaiQuan[wChairID] = 0;
  2283. m_TabbOutCardCout[wChairID] = 0; //可以打出的牌就听牌的个数
  2284. ZeroMemory(m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID])); //具体打哪几张牌
  2285. ZeroMemory(m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  2286. ZeroMemory(m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  2287. BYTE WilEnumCard[MAX_INDEX] = { 0 };
  2288. m_GameLogic.IsCanChangCardAndCount(m_cbCardIndex[wChairID], WilEnumCard);
  2289. for (BYTE i = 0; i < MAX_INDEX; i++)
  2290. {
  2291. if (m_cbCardIndex[wChairID][i] == 0)continue;
  2292. if (--m_cbCardIndex[wChairID][i] < 0){ ASSERT(false); return false; }
  2293. //if (m_GameLogic.IsTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID],FanHui))
  2294. //{
  2295. m_TabbOutCardData[wChairID][m_TabbOutCardCout[wChairID]] = m_GameLogic.SwitchToCardData(i);
  2296. BYTE m_cbTingPai[MAX_INDEX] = { 0 };//听牌数组,听哪个牌就把哪个牌设置为1
  2297. BYTE m_cbTingParCount = 0; //听牌数据
  2298. int BaoUserID = 0;
  2299. int BaoUserTaiNum = 0;
  2300. if (m_GameLogic.AnalyseTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], m_cbTingPai, WilEnumCard, wChairID, BaoUserID, BaoUserTaiNum))
  2301. {
  2302. for (BYTE j = 0; j < MAX_INDEX; j++)
  2303. {
  2304. if (m_cbTingPai[j] > 0)
  2305. {
  2306. if (m_cbTingParCount == 19)
  2307. {
  2308. m_cbTingParCount++;
  2309. break;
  2310. }
  2311. m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount++] = m_GameLogic.SwitchToCardData(j);
  2312. //计算所胡的这张牌 还剩余几张
  2313. BYTE num = RemainNum(wChairID, m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount - 1], i);
  2314. m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount - 1] = m_GameLogic.GetValue(num, m_cbTingPai[j], m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]][m_cbTingParCount - 1]);
  2315. }
  2316. }
  2317. if (m_cbTingParCount == 20)
  2318. {
  2319. m_TabbTingCardCount[wChairID][m_TabbOutCardCout[wChairID]] = 255;
  2320. ZeroMemory(m_TabbTingCardData[wChairID][m_TabbOutCardCout[wChairID]], m_cbTingParCount);
  2321. }
  2322. else
  2323. m_TabbTingCardCount[wChairID][m_TabbOutCardCout[wChairID]] = m_cbTingParCount;
  2324. }
  2325. if (m_cbTingParCount > 0)
  2326. m_TabbOutCardCout[wChairID]++;
  2327. else{ m_TabbOutCardData[wChairID][m_TabbOutCardCout[wChairID]] = 0; }
  2328. //}
  2329. m_cbCardIndex[wChairID][i]++;
  2330. }
  2331. return true;
  2332. }
  2333. bool CTableFrameSink_tdh::OutTingCard(WORD wChairID, BYTE cardIndex)
  2334. {
  2335. m_PaiQuan[wChairID] = 1;
  2336. m_TabbOutCardCout[wChairID] = 1; //可以打出的牌就听牌的个数,当打出牌已经完成,默认255不存在
  2337. ZeroMemory(m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID])); //具体打哪几张牌
  2338. ZeroMemory(m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID])); //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数
  2339. ZeroMemory(m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID])); //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据
  2340. BYTE m_cbTingPai[MAX_INDEX] = { 0 };//听牌数组,听哪个牌就把哪个牌设置为1
  2341. BYTE m_cbTingParCount = 0;//听牌数据
  2342. BYTE FanHui[MAX_INDEX] = { 0 };
  2343. m_GameLogic.IsCanChangCardAndCount(m_cbCardIndex[wChairID], FanHui);
  2344. if (m_GameLogic.AnalyseTingCard(m_cbCardIndex[wChairID], m_WeaveItemArray[wChairID], m_cbWeaveItemCount[wChairID], m_cbTingPai, FanHui, wChairID))
  2345. {
  2346. for (BYTE j = 0; j < MAX_INDEX; j++)
  2347. {
  2348. if (m_cbTingPai[j] > 0)
  2349. {
  2350. if (m_cbTingParCount == 19)
  2351. {
  2352. m_cbTingParCount++;
  2353. break;
  2354. }
  2355. m_TabbTingCardData[wChairID][0][m_cbTingParCount++] = m_GameLogic.SwitchToCardData(j);
  2356. //用户ID
  2357. BYTE num = RemainNum(wChairID, m_TabbTingCardData[wChairID][0][m_cbTingParCount - 1], cardIndex);
  2358. m_TabbTingCardData[wChairID][0][m_cbTingParCount - 1] = m_GameLogic.GetValue(num, m_cbTingPai[j], m_TabbTingCardData[wChairID][0][m_cbTingParCount - 1]);
  2359. }
  2360. }
  2361. if (m_cbTingParCount == 20)
  2362. {
  2363. m_TabbTingCardCount[wChairID][0] = 255;
  2364. ZeroMemory(m_TabbTingCardData[wChairID][0], m_cbTingParCount);
  2365. }
  2366. else
  2367. {
  2368. m_TabbTingCardCount[wChairID][0] = m_cbTingParCount;
  2369. }
  2370. return true;
  2371. }
  2372. return false;
  2373. }
  2374. void CTableFrameSink_tdh::HttpTingCard(WORD wChairID)
  2375. {
  2376. CMD_S_TingCard strTingCard;
  2377. ZeroMemory(&strTingCard, sizeof(strTingCard));
  2378. strTingCard.bPaiQuan = m_PaiQuan[wChairID];
  2379. strTingCard.bOutCardCout = m_TabbOutCardCout[wChairID];
  2380. CopyMemory(strTingCard.bOutCardData, m_TabbOutCardData[wChairID], sizeof(m_TabbOutCardData[wChairID]));
  2381. CopyMemory(strTingCard.bTingCardCount, m_TabbTingCardCount[wChairID], sizeof(m_TabbTingCardCount[wChairID]));
  2382. CopyMemory(strTingCard.bTingCardData, m_TabbTingCardData[wChairID], sizeof(m_TabbTingCardData[wChairID]));
  2383. SparrowMaJiang::PB_CS_S_TingCard Card;
  2384. Card.set_bpaiquan(strTingCard.bPaiQuan);
  2385. Card.set_boutcardcout(strTingCard.bOutCardCout);
  2386. for (BYTE j = 0; j < strTingCard.bOutCardCout; j++)
  2387. {
  2388. Card.add_boutcarddata(strTingCard.bOutCardData[j]);
  2389. }
  2390. for (BYTE j = 0; j < strTingCard.bOutCardCout; j++)
  2391. {
  2392. Card.add_btingcardcount(strTingCard.bTingCardCount[j]);
  2393. }
  2394. for (BYTE i = 0; i < strTingCard.bOutCardCout; i++)
  2395. {
  2396. SparrowMaJiang::pb_bTingCardData* CardData = Card.add_btingcarddata();
  2397. for (BYTE j = 0; j < strTingCard.bTingCardCount[i]; j++)
  2398. {
  2399. CardData->add_btingcarddatas(strTingCard.bTingCardData[i][j]);
  2400. }
  2401. }
  2402. std::string pbdata = Card.SerializePartialAsString();
  2403. m_pITableFrame->SendTableData(wChairID, SUB_S_TING_CARD, (void*)pbdata.c_str(), pbdata.length());
  2404. }
  2405. void CTableFrameSink_tdh::HttpOperateResult(WORD wChairID, BYTE cbCaiShenCard[4], int cbOperateCode, BYTE cbOperateCard, int cbActionMask, WORD cbActionCard[6])
  2406. {
  2407. //
  2408. //推倒胡发送及时杠牌积分变动
  2409. //SendGangScore(wChairID, m_wProvideUser, cbOperateCode);
  2410. if (cbOperateCode & WIK_GANG_GANG)
  2411. {//构造结果
  2412. CMD_S_OperateResult OperateResult;
  2413. memset(&OperateResult, 0, sizeof(OperateResult));
  2414. OperateResult.wOperateUser = wChairID;
  2415. OperateResult.wProvideUser = wChairID;
  2416. OperateResult.cbOperateCode = cbOperateCode;
  2417. OperateResult.cbOperateCard = cbOperateCard;
  2418. CopyMemory(OperateResult.cbCaiShenCard, cbCaiShenCard, sizeof(OperateResult.cbCaiShenCard));
  2419. OperateResult.cbActionMask = cbActionMask;
  2420. CopyMemory(OperateResult.cbActionCard, cbActionCard, sizeof(OperateResult.cbActionCard));
  2421. SparrowMaJiang::PB_CS_S_OperateResult Result;
  2422. Result.set_woperateuser(OperateResult.wOperateUser);
  2423. Result.set_cboperatecard(OperateResult.cbOperateCard);
  2424. Result.set_cboperatecode(OperateResult.cbOperateCode);
  2425. Result.set_wprovideuser(OperateResult.wProvideUser);
  2426. for (BYTE j = 0; j < 4; j++)
  2427. {
  2428. Result.add_cbcaishencard(OperateResult.cbCaiShenCard[j]);
  2429. }
  2430. Result.set_cbactionmask(OperateResult.cbActionMask);
  2431. for (BYTE j = 0; j < 6; j++)
  2432. {
  2433. Result.add_cbactioncard(OperateResult.cbActionCard[j]);
  2434. }
  2435. //发送数据
  2436. std::string pbdata = Result.SerializePartialAsString();
  2437. RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2438. //发送消息
  2439. m_pITableFrame->SendTableData(wChairID, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2440. ZeroMemory(OperateResult.cbCaiShenCard, sizeof(OperateResult.cbCaiShenCard));
  2441. for (BYTE j = 0; j < 4; j++)
  2442. {
  2443. Result.add_cbcaishencard(OperateResult.cbCaiShenCard[j]);
  2444. }
  2445. for (BYTE i = 0; i < mPlayGameUserCount; i++)
  2446. {
  2447. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2448. {
  2449. continue;
  2450. }
  2451. if (i == wChairID)continue;
  2452. //发送消息
  2453. m_pITableFrame->SendTableData(i, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2454. }
  2455. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2456. }
  2457. else
  2458. {
  2459. CMD_S_OperateResult OperateResult;
  2460. memset(&OperateResult, 0, sizeof(OperateResult));
  2461. OperateResult.wOperateUser = wChairID;
  2462. OperateResult.wProvideUser = m_wProvideUser;
  2463. if (cbOperateCode &(WIK_DAN_BU_GANG | WIK_BU_GANG))
  2464. OperateResult.wProvideUser = wChairID;
  2465. OperateResult.cbOperateCode = cbOperateCode;
  2466. OperateResult.cbOperateCard = cbOperateCard;
  2467. CopyMemory(OperateResult.cbCaiShenCard, cbCaiShenCard, sizeof(OperateResult.cbCaiShenCard));
  2468. OperateResult.cbActionMask = cbActionMask;
  2469. CopyMemory(OperateResult.cbActionCard, cbActionCard, sizeof(OperateResult.cbActionCard));
  2470. SparrowMaJiang::PB_CS_S_OperateResult Result;
  2471. Result.set_woperateuser(OperateResult.wOperateUser);
  2472. Result.set_cboperatecard(OperateResult.cbOperateCard);
  2473. Result.set_cboperatecode(OperateResult.cbOperateCode);
  2474. Result.set_wprovideuser(OperateResult.wProvideUser);
  2475. for (BYTE j = 0; j < 4; j++)
  2476. {
  2477. Result.add_cbcaishencard(OperateResult.cbCaiShenCard[j]);
  2478. }
  2479. Result.set_cbactionmask(OperateResult.cbActionMask);
  2480. for (BYTE j = 0; j < 6; j++)
  2481. {
  2482. Result.add_cbactioncard(OperateResult.cbActionCard[j]);
  2483. }
  2484. //发送数据
  2485. std::string pbdata = Result.SerializePartialAsString();
  2486. RepayRecord(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2487. //发送消息
  2488. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2489. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_OPERATE_RESULT, (void*)pbdata.c_str(), pbdata.length());
  2490. }
  2491. }
  2492. BYTE CTableFrameSink_tdh::GetNextMagicCardData(BYTE cbMagicCardFirstData)
  2493. {
  2494. BYTE TmpCardData = 0;
  2495. BYTE HuaSe = m_GameLogic.GetCardColor(cbMagicCardFirstData);
  2496. switch (HuaSe)
  2497. {
  2498. case 0:
  2499. case 1:
  2500. case 2:
  2501. {
  2502. if ((cbMagicCardFirstData & MASK_VALUE) == 0x09)
  2503. {
  2504. TmpCardData = (cbMagicCardFirstData & MASK_COLOR) | 0x01;
  2505. }
  2506. else
  2507. {
  2508. TmpCardData = cbMagicCardFirstData + 1;
  2509. }
  2510. break;
  2511. }
  2512. case 3:
  2513. {
  2514. if ((cbMagicCardFirstData & MASK_VALUE) == 0x04)
  2515. {
  2516. TmpCardData = (cbMagicCardFirstData & MASK_COLOR) | 0x01;
  2517. }
  2518. else if ((cbMagicCardFirstData & MASK_VALUE) == 0x07)
  2519. {
  2520. TmpCardData = cbMagicCardFirstData - 2;
  2521. }
  2522. else
  2523. {
  2524. TmpCardData = cbMagicCardFirstData + 1;
  2525. }
  2526. break;
  2527. }
  2528. default:
  2529. {
  2530. ASSERT(false);
  2531. break;
  2532. }
  2533. }
  2534. return TmpCardData;
  2535. }
  2536. void CTableFrameSink_tdh::FanMagicCaculation(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score)
  2537. {
  2538. switch (WinWay)
  2539. {
  2540. case Win_ZiMo:{
  2541. if (!(chr&ZJ_TAI_QiangGang).IsEmpty())
  2542. {
  2543. WinFanMagic_ZiMo_QiangGang_Score(WinChairID, nTai, WinWay, provideUserID, cmd_Score);
  2544. break;
  2545. }
  2546. else
  2547. {
  2548. WinFanMagic_ZiMo_Score(WinChairID, nTai, WinWay, provideUserID, cmd_Score);
  2549. }
  2550. break;
  2551. }
  2552. case Win_FangPao:{
  2553. WinFanMagic_FangPao_Score(WinChairID, nTai, WinWay, provideUserID, cmd_Score);
  2554. break;
  2555. }
  2556. default:
  2557. break;
  2558. }
  2559. }
  2560. void CTableFrameSink_tdh::WinFanMagic_FangPao_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID,CMD_S_GangScore& cmd_Score)
  2561. {
  2562. for (BYTE i = 0; i < mPlayGameUserCount; i++)//各个玩家游戏积分变动
  2563. {
  2564. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2565. {
  2566. continue;
  2567. }
  2568. if (i == WinChairID)
  2569. {
  2570. //cmd_Score.lGangScore[i] += m_gangScore[i];
  2571. continue;
  2572. }
  2573. if (i == provideUserID)
  2574. {
  2575. LianXuHuPai[i] = 0;
  2576. cmd_Score.lGangScore[i] -= m_gameConfig.wDiScore * nTai*2;
  2577. // [9/16/2017 Zoro] 计算杠牌影响的分数
  2578. cmd_Score.lGangScore[i] += m_gangScore[i];
  2579. m_lGameScore[i] += cmd_Score.lGangScore[i];
  2580. m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  2581. cmd_Score.cbWanJiaScore[i] = m_lGameTatolScore[i];
  2582. }
  2583. else
  2584. {
  2585. LianXuHuPai[i] = 0;
  2586. cmd_Score.lGangScore[i] -= m_gameConfig.wDiScore * nTai;
  2587. cmd_Score.lGangScore[i] += m_gangScore[i];
  2588. m_lGameScore[i] += cmd_Score.lGangScore[i];
  2589. m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  2590. cmd_Score.cbWanJiaScore[i] = m_lGameTatolScore[i];
  2591. }
  2592. }
  2593. if (m_bTwoPlayerFlag)
  2594. {
  2595. cmd_Score.lGangScore[WinChairID] = m_gameConfig.wDiScore * 2 * nTai;//2个玩家
  2596. }
  2597. else
  2598. {
  2599. cmd_Score.lGangScore[WinChairID] = m_gameConfig.wDiScore * mPlayGameUserCount * nTai;
  2600. }
  2601. cmd_Score.lGangScore[WinChairID] += m_gangScore[WinChairID];
  2602. m_lGameScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  2603. m_lGameTatolScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  2604. cmd_Score.cbWanJiaScore[WinChairID] = m_lGameTatolScore[WinChairID];
  2605. }
  2606. void CTableFrameSink_tdh::CaculationHuangZhuang(CMD_S_GangScore& cmd_Score)
  2607. {
  2608. WORD BankUserID = m_wBankerUser & 0x00ff;
  2609. int FanBei = 1;
  2610. //if (LianXuHuPai[BankUserID] >= 2)
  2611. //{
  2612. // FanBei++;
  2613. //}
  2614. ZeroMemory(m_gangScore, sizeof(m_gangScore));
  2615. //计算所有杠牌四家的积分变动。
  2616. for (int i = 0; i < mPlayGameUserCount; i++)
  2617. {
  2618. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2619. {
  2620. continue;
  2621. }
  2622. int nCount = m_cbWeaveItemCount[i];
  2623. for (int nWeaveItem = 0; nWeaveItem < nCount; nWeaveItem++)
  2624. {
  2625. tagWeaveItem tag = m_WeaveItemArray[i][nWeaveItem];
  2626. switch (tag.cbWeaveKind)
  2627. {
  2628. //点杠
  2629. case WIK_MING_GANG:
  2630. {
  2631. m_gangScore[i] += 2 * m_gameConfig.wDiScore*FanBei;
  2632. m_gangScore[tag.wProvideUser] -= 2 * m_gameConfig.wDiScore*FanBei;
  2633. break;
  2634. }
  2635. case WIK_AN_GANG:
  2636. {
  2637. for (int j = 0; j < mPlayGameUserCount; j++)
  2638. {
  2639. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2640. {
  2641. continue;
  2642. }
  2643. if (j == i)
  2644. {
  2645. if (m_bTwoPlayerFlag)
  2646. {
  2647. m_gangScore[i] += (mPlayGameUserCount - 2) * 2 * m_gameConfig.wDiScore*FanBei;
  2648. }
  2649. else
  2650. {
  2651. m_gangScore[i] += (mPlayGameUserCount - 1) * 2 * m_gameConfig.wDiScore*FanBei;
  2652. }
  2653. continue;
  2654. }
  2655. m_gangScore[j] -= 2 * m_gameConfig.wDiScore*FanBei;
  2656. }
  2657. break;
  2658. }
  2659. case WIK_BU_GANG:{
  2660. for (int j = 0; j < mPlayGameUserCount; j++)
  2661. {
  2662. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2663. {
  2664. continue;
  2665. }
  2666. if (j == i)
  2667. {
  2668. if (m_bTwoPlayerFlag)
  2669. {
  2670. m_gangScore[i] += (mPlayGameUserCount - 2) * m_gameConfig.wDiScore*FanBei;
  2671. }
  2672. else
  2673. {
  2674. m_gangScore[i] += (mPlayGameUserCount - 1) * m_gameConfig.wDiScore*FanBei;
  2675. }
  2676. continue;
  2677. }
  2678. m_gangScore[j] -= m_gameConfig.wDiScore*FanBei;
  2679. }
  2680. break;
  2681. }
  2682. default:
  2683. break;
  2684. }
  2685. }
  2686. }
  2687. for (int i = 0; i < mPlayGameUserCount; i++)
  2688. {
  2689. // CString str;
  2690. // str.Format(_T("CaculationHuangZhuang 玩家%d 杠牌分数变动=%d"), i, m_gangScore[i]);
  2691. // OutputDebugString(str);
  2692. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2693. {
  2694. continue;
  2695. }
  2696. cmd_Score.lGangScore[i] += m_gangScore[i];
  2697. m_lGameScore[i] += cmd_Score.lGangScore[i];
  2698. m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  2699. cmd_Score.cbWanJiaScore[i] = m_lGameTatolScore[i];
  2700. }
  2701. }
  2702. void CTableFrameSink_tdh::WinFanMagic_ZiMo_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score)
  2703. {
  2704. int TempInfoScore = 0;
  2705. for (BYTE i = 0; i < mPlayGameUserCount; i++)//各个玩家游戏积分变动
  2706. {
  2707. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2708. {
  2709. continue;
  2710. }
  2711. if (i == WinChairID)continue;
  2712. LianXuHuPai[i] = 0;
  2713. cmd_Score.lGangScore[i] -= m_gameConfig.wDiScore * nTai;
  2714. // [9/16/2017 Zoro] 计算杠牌影响的分数
  2715. cmd_Score.lGangScore[i] += m_gangScore[i];
  2716. m_lGameScore[i] += cmd_Score.lGangScore[i];
  2717. m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  2718. cmd_Score.cbWanJiaScore[i] = m_lGameTatolScore[i];
  2719. //
  2720. TempInfoScore -= cmd_Score.lGangScore[i];
  2721. }
  2722. cmd_Score.lGangScore[WinChairID] = TempInfoScore;
  2723. m_lGameScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  2724. m_lGameTatolScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  2725. cmd_Score.cbWanJiaScore[WinChairID] = m_lGameTatolScore[WinChairID];
  2726. }
  2727. void CTableFrameSink_tdh::WinFanMagic_ZiMo_QiangGang_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score)
  2728. {
  2729. WORD BankUserID = m_wBankerUser & 0x00ff;
  2730. int FanBei = 1;
  2731. if (LianXuHuPai[BankUserID] >= 2)
  2732. {
  2733. FanBei++;
  2734. }
  2735. int TempInfoScore = 0;
  2736. for (BYTE i = 0; i < mPlayGameUserCount; i++)//各个玩家游戏积分变动
  2737. {
  2738. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2739. {
  2740. continue;
  2741. }
  2742. if (i == WinChairID)
  2743. {
  2744. //cmd_Score.lGangScore[i] += m_gangScore[i];
  2745. continue;
  2746. }
  2747. if (i == provideUserID)
  2748. {
  2749. LianXuHuPai[i] = 0;
  2750. if (m_bTwoPlayerFlag)
  2751. {
  2752. cmd_Score.lGangScore[i] -= m_gameConfig.wDiScore * (mPlayGameUserCount-1) * FanBei;
  2753. }
  2754. else
  2755. {
  2756. cmd_Score.lGangScore[i] -= m_gameConfig.wDiScore * mPlayGameUserCount * FanBei;
  2757. }
  2758. // [9/16/2017 Zoro] 计算杠牌影响的分数
  2759. cmd_Score.lGangScore[i] += m_gangScore[i];
  2760. m_lGameScore[i] += cmd_Score.lGangScore[i];
  2761. m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  2762. cmd_Score.cbWanJiaScore[i] = m_lGameTatolScore[i];
  2763. TempInfoScore -= cmd_Score.lGangScore[i];
  2764. }
  2765. else
  2766. {
  2767. cmd_Score.lGangScore[i] += m_gangScore[i];
  2768. m_lGameScore[i] += m_gangScore[i];
  2769. m_lGameTatolScore[i] += cmd_Score.lGangScore[i];
  2770. }
  2771. }
  2772. if (m_bTwoPlayerFlag)
  2773. {
  2774. cmd_Score.lGangScore[WinChairID] = m_gameConfig.wDiScore * (mPlayGameUserCount-1) * FanBei;
  2775. }
  2776. else
  2777. {
  2778. cmd_Score.lGangScore[WinChairID] = m_gameConfig.wDiScore * mPlayGameUserCount * FanBei;
  2779. }
  2780. cmd_Score.lGangScore[WinChairID] += m_gangScore[WinChairID];
  2781. m_lGameScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  2782. m_lGameTatolScore[WinChairID] += cmd_Score.lGangScore[WinChairID];
  2783. cmd_Score.cbWanJiaScore[WinChairID] = m_lGameTatolScore[WinChairID];
  2784. }
  2785. //由于推倒胡 财神不能落地。所以只有暗杠 明杠 补杠
  2786. void CTableFrameSink_tdh::SendGangScore(BYTE GangUserID, BYTE ProvideUserID, int cbOperateCode)
  2787. {
  2788. //积分变动
  2789. //暗杠
  2790. CMD_S_GangScore gs;
  2791. ZeroMemory(&gs, sizeof(gs));
  2792. gs.wChairId = GangUserID;
  2793. gs.cbOperateCode = cbOperateCode;
  2794. CopyMemory(gs.cbWanJiaScore, m_lGameTatolScore,sizeof(m_lGameTatolScore));
  2795. if (cbOperateCode & WIK_GANG_GANG)
  2796. {
  2797. for (int j = 0; j < mPlayGameUserCount; j++)
  2798. {
  2799. if (m_bTwoPlayerFlag&&j == TowMjNullseat)
  2800. {
  2801. continue;
  2802. }
  2803. if (j == GangUserID)
  2804. {
  2805. if (m_bTwoPlayerFlag)
  2806. {
  2807. gs.lGangScore[j] += (mPlayGameUserCount - 2) * 2 * m_gameConfig.wDiScore;
  2808. }
  2809. else
  2810. {
  2811. gs.lGangScore[j] += (mPlayGameUserCount - 1) * 2 * m_gameConfig.wDiScore;
  2812. }
  2813. continue;
  2814. }
  2815. gs.lGangScore[j] -= 2 * m_gameConfig.wDiScore;
  2816. }
  2817. SparrowMaJiang::PB_CS_S_GangScore GangScore;
  2818. GangScore.set_cboperatecode(gs.cbOperateCode);
  2819. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  2820. {
  2821. GangScore.add_cbwanjiascore(gs.cbWanJiaScore[j]);
  2822. GangScore.add_lgangscore(gs.lGangScore[j]);
  2823. }
  2824. GangScore.set_wchairid(gs.wChairId);
  2825. std::string pbscore = GangScore.SerializePartialAsString();
  2826. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  2827. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  2828. RepayRecord(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  2829. return;
  2830. }
  2831. //明杠
  2832. if (cbOperateCode & WIK_MING_GANG)
  2833. {
  2834. gs.lGangScore[GangUserID] += 2 * m_gameConfig.wDiScore;
  2835. gs.lGangScore[ProvideUserID] -= 2 * m_gameConfig.wDiScore;
  2836. SparrowMaJiang::PB_CS_S_GangScore GangScore;
  2837. GangScore.set_cboperatecode(gs.cbOperateCode);
  2838. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  2839. {
  2840. GangScore.add_cbwanjiascore(gs.cbWanJiaScore[j]);
  2841. GangScore.add_lgangscore(gs.lGangScore[j]);
  2842. }
  2843. GangScore.set_wchairid(gs.wChairId);
  2844. std::string pbscore = GangScore.SerializePartialAsString();
  2845. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  2846. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  2847. RepayRecord(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  2848. return;
  2849. }
  2850. //补杠
  2851. if (cbOperateCode&WIK_BU_GANG)
  2852. {
  2853. for (int j = 0; j < mPlayGameUserCount; j++)
  2854. {
  2855. if (m_bTwoPlayerFlag&&j == TowMjNullseat)
  2856. {
  2857. continue;
  2858. }
  2859. if (j == GangUserID)
  2860. {
  2861. if (m_bTwoPlayerFlag)
  2862. {
  2863. gs.lGangScore[j] += (mPlayGameUserCount - 2) * m_gameConfig.wDiScore;
  2864. }
  2865. else
  2866. {
  2867. gs.lGangScore[j] += (mPlayGameUserCount - 1) * m_gameConfig.wDiScore;
  2868. }
  2869. continue;
  2870. }
  2871. gs.lGangScore[j] -= m_gameConfig.wDiScore;
  2872. }
  2873. SparrowMaJiang::PB_CS_S_GangScore GangScore;
  2874. GangScore.set_cboperatecode(gs.cbOperateCode);
  2875. for (BYTE j = 0; j < mPlayGameUserCount; j++)
  2876. {
  2877. GangScore.add_cbwanjiascore(gs.cbWanJiaScore[j]);
  2878. GangScore.add_lgangscore(gs.lGangScore[j]);
  2879. }
  2880. GangScore.set_wchairid(gs.wChairId);
  2881. std::string pbscore = GangScore.SerializePartialAsString();
  2882. m_pITableFrame->SendTableData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  2883. m_pITableFrame->SendLookonData(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  2884. RepayRecord(INVALID_CHAIR, SUB_S_GANG_SCORE, (void*)pbscore.c_str(), pbscore.length());
  2885. return;
  2886. }
  2887. }
  2888. void CTableFrameSink_tdh::CaculationScore(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight UserChr, CMD_S_GangScore& cmd_Score)
  2889. {
  2890. //int nWinUserItemCount = m_cbWeaveItemCount[WinChairID];
  2891. //if (!(UserChr&ZJ_TAI_GangKai).IsEmpty())
  2892. //{
  2893. // CString str;
  2894. // str.Format(_T("杠开~~~ 玩家id=%d 杠开的牌=%02x"), WinChairID,m_cbLastGangCard);
  2895. // OutputDebugString(str);
  2896. //
  2897. //}
  2898. // [10/9/2017 Zoro] 取消老庄 杠牌翻倍,取消杠开不算积分问题(使杠开的杠也算分)。
  2899. //WORD BankUserID = m_wBankerUser & 0x00ff;
  2900. int FanBei = 1;
  2901. //if (LianXuHuPai[BankUserID] >= 2)
  2902. //{
  2903. // FanBei++;
  2904. //}
  2905. ZeroMemory(m_gangScore, sizeof(m_gangScore));
  2906. //计算所有杠牌四家的积分变动。
  2907. for (int i = 0; i < mPlayGameUserCount; i++)
  2908. {
  2909. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  2910. {
  2911. continue;
  2912. }
  2913. int nCount = m_cbWeaveItemCount[i];
  2914. for (int nWeaveItem = 0; nWeaveItem <nCount; nWeaveItem++)
  2915. {
  2916. if (!(UserChr&ZJ_TAI_QiangGang).IsEmpty()&&i==m_wProvideUser)
  2917. {
  2918. if (m_WeaveItemArray[i][nWeaveItem].cbCenterCard == m_cbSendCardData)
  2919. {
  2920. // CString str;
  2921. // str.Format(_T("抢杠胡,去掉玩家 %d 第%d个落地杠 牌值=%02x\r\n"), i, nWeaveItem, m_cbSendCardData);
  2922. // OutputDebugString(str);
  2923. continue;
  2924. }
  2925. }
  2926. // if (!(UserChr&ZJ_TAI_GangKai).IsEmpty() && i == WinChairID&& m_WeaveItemArray[i][nWeaveItem].cbCenterCard==m_cbLastGangCard)
  2927. // {
  2928. // continue;
  2929. // }
  2930. tagWeaveItem tag = m_WeaveItemArray[i][nWeaveItem];
  2931. switch (tag.cbWeaveKind)
  2932. {
  2933. //点杠
  2934. case WIK_MING_GANG:
  2935. {
  2936. m_gangScore[i] += (2 * m_gameConfig.wDiScore*FanBei);
  2937. m_gangScore[tag.wProvideUser] -= (2 * m_gameConfig.wDiScore*FanBei);
  2938. break;
  2939. }
  2940. case WIK_AN_GANG:
  2941. {
  2942. for (int j = 0; j < mPlayGameUserCount;j++)
  2943. {
  2944. if (m_bTwoPlayerFlag&&j == TowMjNullseat)
  2945. {
  2946. continue;
  2947. }
  2948. if (j==i)
  2949. {
  2950. if (m_bTwoPlayerFlag)
  2951. {
  2952. m_gangScore[i] += (mPlayGameUserCount - 2) * 2 * m_gameConfig.wDiScore*FanBei;
  2953. }
  2954. else
  2955. {
  2956. m_gangScore[i] += (mPlayGameUserCount - 1) * 2 * m_gameConfig.wDiScore*FanBei;
  2957. }
  2958. continue;
  2959. }
  2960. m_gangScore[j] -= 2 * m_gameConfig.wDiScore*FanBei;
  2961. }
  2962. break;
  2963. }
  2964. case WIK_BU_GANG:{
  2965. for (int j = 0; j < mPlayGameUserCount; j++)
  2966. {
  2967. if (m_bTwoPlayerFlag&&j == TowMjNullseat)
  2968. {
  2969. continue;
  2970. }
  2971. if (j == i)
  2972. {
  2973. if (m_bTwoPlayerFlag)
  2974. {
  2975. m_gangScore[i] += (mPlayGameUserCount - 2) * m_gameConfig.wDiScore*FanBei;
  2976. }
  2977. else
  2978. {
  2979. m_gangScore[i] += (mPlayGameUserCount - 1) * m_gameConfig.wDiScore*FanBei;
  2980. }
  2981. continue;
  2982. }
  2983. m_gangScore[j] -= m_gameConfig.wDiScore*FanBei;
  2984. }
  2985. break;
  2986. }
  2987. default:
  2988. break;
  2989. }
  2990. }
  2991. }
  2992. // for (int i = 0; i < GAME_PLAYER;i++)
  2993. // {
  2994. // CString str;
  2995. // str.Format(_T("玩家%d 杠牌分数变动=%d"),i,m_gangScore[i]);
  2996. // OutputDebugString(str);
  2997. // }
  2998. FanMagicCaculation(WinChairID, nTai, WinWay, provideUserID, UserChr, cmd_Score);
  2999. }
  3000. void CTableFrameSink_tdh::WritePaiCardData(TCHAR* TableId, int count)
  3001. {
  3002. CString strCfgFile;
  3003. GetModuleFileName(NULL, strCfgFile.GetBufferSetLength(MAX_PATH), MAX_PATH);
  3004. strCfgFile.ReleaseBuffer();
  3005. WCHAR* pTmp = wcsrchr(strCfgFile.GetBuffer(), L'\\');
  3006. if (pTmp)
  3007. {
  3008. *pTmp = 0;
  3009. }
  3010. PathAppend(strCfgFile.GetBufferSetLength(MAX_PATH), _T("cfg.ini"));
  3011. strCfgFile.ReleaseBuffer();
  3012. CString strPath;
  3013. GetPrivateProfileString(_T("datpath"), _T("value"), _T(""), strPath.GetBufferSetLength(MAX_PATH), MAX_PATH, strCfgFile.GetBuffer());
  3014. strPath.ReleaseBuffer();
  3015. CString strFileName;
  3016. if (strPath.IsEmpty())
  3017. {
  3018. strFileName.Format(_T("TableData\\Table_%s_%d.dat"), TableId, count);
  3019. }
  3020. else
  3021. {
  3022. strFileName.Format(_T("%s\\TableData\\Table_%s_%d.dat"), strPath.GetBuffer(), TableId, count);
  3023. }
  3024. CString strCreate;
  3025. strCreate = strPath;
  3026. PathAppend(strCreate.GetBufferSetLength(MAX_PATH), _T("\\TableData"));
  3027. strCreate.ReleaseBuffer();
  3028. if (!PathFileExists(strCreate.GetBuffer()))
  3029. {
  3030. CreateDirectory(strCreate.GetBuffer(), NULL);
  3031. }
  3032. HANDLE hFile = CreateFile(strFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_NEW, NULL, NULL);
  3033. if (hFile != INVALID_HANDLE_VALUE)
  3034. {
  3035. DWORD dwWrite;
  3036. WriteFile(hFile, m_cbRepertoryCard, m_cbTotalCardCount, &dwWrite, NULL);
  3037. CloseHandle(hFile);
  3038. }
  3039. }
  3040. BOOL CTableFrameSink_tdh::ReadGameData()
  3041. {
  3042. CString strFileName;
  3043. strFileName = _T("Table.dat");
  3044. if (!PathFileExists(_T("Table.dat")))
  3045. {
  3046. return FALSE;
  3047. }
  3048. HANDLE hFile = CreateFile(strFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, NULL, NULL);
  3049. if (hFile != INVALID_HANDLE_VALUE)
  3050. {
  3051. DWORD dwRead;
  3052. DWORD dwFileSize;
  3053. DWORD fileSize = GetFileSize(hFile, &dwFileSize);
  3054. if (fileSize != m_cbTotalCardCount)
  3055. {
  3056. CloseHandle(hFile);
  3057. return FALSE;
  3058. }
  3059. SetFilePointer(hFile, 0, 0, FILE_BEGIN);
  3060. //BYTE tmpCard[MAX_REPERTORY_ZJ] = { 0 };
  3061. ReadFile(hFile, m_cbRepertoryCard, m_cbTotalCardCount, &dwRead, NULL);
  3062. CloseHandle(hFile);
  3063. }
  3064. return TRUE;
  3065. }
  3066. //打印玩家所有积分
  3067. void CTableFrameSink_tdh::PrintUsersScore(LPCTSTR lpstrInfo)
  3068. {
  3069. //OutputDebugString(lpstrInfo);
  3070. CString strInfo;
  3071. for (int i = 0; i < mPlayGameUserCount; i++)
  3072. {
  3073. if (m_bTwoPlayerFlag&&i == TowMjNullseat)
  3074. {
  3075. continue;
  3076. }
  3077. CString strTmp;
  3078. strTmp.Format(_T("UserID =%d 本次变更积分 %d 本局剩余拥有积分%d"),
  3079. i, m_lGameScore[i], m_lGameTatolScore[i]);
  3080. //OutputDebugString(strTmp);
  3081. }
  3082. }
  3083. //被动操作删除手牌
  3084. bool CTableFrameSink_tdh::DeleteCaiShenCard(WORD wTargetUser, BYTE cbTargetCaiCard[4], int cbTargetAction, BYTE cbTargetCard)
  3085. {
  3086. switch (cbTargetAction)
  3087. {
  3088. case WIK_SAN_MING_GANG:
  3089. {
  3090. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(cbTargetCaiCard[0])]--)
  3091. {
  3092. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(cbTargetCaiCard[1])]--)
  3093. {
  3094. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(cbTargetCaiCard[2])]--)
  3095. {
  3096. ASSERT(m_cbWeaveItemCount[wTargetUser] < 4);
  3097. if (m_cbWeaveItemCount[wTargetUser] > 4)return false;
  3098. WORD wIndex = m_cbWeaveItemCount[wTargetUser]++;
  3099. m_WeaveItemArray[wTargetUser][wIndex].cbPublicCard = TRUE;
  3100. m_WeaveItemArray[wTargetUser][wIndex].cbCenterCard = cbTargetCard;
  3101. m_WeaveItemArray[wTargetUser][wIndex].cbWeaveKind = cbTargetAction;
  3102. m_WeaveItemArray[wTargetUser][wIndex].wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser;
  3103. m_WeaveItemArray[wTargetUser][wIndex].cbMargicOffset[0] = cbTargetCaiCard[0];
  3104. m_WeaveItemArray[wTargetUser][wIndex].cbMargicOffset[1] = cbTargetCaiCard[1];
  3105. m_WeaveItemArray[wTargetUser][wIndex].cbMargicOffset[2] = cbTargetCaiCard[2];
  3106. if (mPlayGameUserCount == 4)
  3107. {
  3108. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3109. m_cbLeftCardCount -= 6;
  3110. else//少于三墩就只有一张可以抓的牌咯
  3111. m_cbLeftCardCount = 1;
  3112. }
  3113. m_cbGangCount++;//打了几个杠
  3114. return true;
  3115. }
  3116. else
  3117. {
  3118. ASSERT(false);
  3119. return false;
  3120. }
  3121. }
  3122. else
  3123. {
  3124. ASSERT(false);
  3125. return false;
  3126. }
  3127. }
  3128. else
  3129. {
  3130. ASSERT(false);
  3131. return false;
  3132. }
  3133. }
  3134. case WIK_DAN_CHI:
  3135. case WIK_SHUANG_CAICHI:
  3136. case WIK_SHUANG_PENG:
  3137. {
  3138. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(cbTargetCaiCard[0])]--)
  3139. {
  3140. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(cbTargetCaiCard[1])]--)
  3141. {
  3142. ASSERT(m_cbWeaveItemCount[wTargetUser] < 4);
  3143. if (m_cbWeaveItemCount[wTargetUser] > 4)return false;
  3144. WORD wIndex = m_cbWeaveItemCount[wTargetUser]++;
  3145. m_WeaveItemArray[wTargetUser][wIndex].cbPublicCard = TRUE;
  3146. m_WeaveItemArray[wTargetUser][wIndex].cbCenterCard = cbTargetCard;
  3147. m_WeaveItemArray[wTargetUser][wIndex].cbWeaveKind = cbTargetAction;
  3148. m_WeaveItemArray[wTargetUser][wIndex].wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser;
  3149. m_WeaveItemArray[wTargetUser][wIndex].cbMargicOffset[0] = cbTargetCaiCard[0];
  3150. m_WeaveItemArray[wTargetUser][wIndex].cbMargicOffset[1] = cbTargetCaiCard[1];
  3151. return true;
  3152. }
  3153. else
  3154. {
  3155. ASSERT(false);
  3156. return false;
  3157. }
  3158. }
  3159. else
  3160. {
  3161. ASSERT(false);
  3162. return false;
  3163. }
  3164. }
  3165. case WIK_SHUANG_MING_GANG:
  3166. {
  3167. BYTE CardIndex = m_GameLogic.SwitchToCardIndex(cbTargetCard);
  3168. if (m_cbCardIndex[wTargetUser][CardIndex]--)
  3169. {
  3170. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(cbTargetCaiCard[0])]--)
  3171. {
  3172. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(cbTargetCaiCard[1])]--)
  3173. {
  3174. ASSERT(m_cbWeaveItemCount[wTargetUser] < 4);
  3175. if (m_cbWeaveItemCount[wTargetUser] > 4)return false;
  3176. WORD wIndex = m_cbWeaveItemCount[wTargetUser]++;
  3177. m_WeaveItemArray[wTargetUser][wIndex].cbPublicCard = TRUE;
  3178. m_WeaveItemArray[wTargetUser][wIndex].cbCenterCard = cbTargetCard;
  3179. m_WeaveItemArray[wTargetUser][wIndex].cbWeaveKind = cbTargetAction;
  3180. m_WeaveItemArray[wTargetUser][wIndex].wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser;
  3181. m_WeaveItemArray[wTargetUser][wIndex].cbMargicOffset[0] = cbTargetCaiCard[0];
  3182. m_WeaveItemArray[wTargetUser][wIndex].cbMargicOffset[1] = cbTargetCaiCard[1];
  3183. m_WeaveItemArray[wTargetUser][wIndex].cbMargicOffset[2] = cbTargetCard;
  3184. if (mPlayGameUserCount == 4)
  3185. {
  3186. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3187. m_cbLeftCardCount -= 6;
  3188. else//少于三墩就只有一张可以抓的牌咯
  3189. m_cbLeftCardCount = 1;
  3190. }
  3191. m_cbGangCount++;//打了几个杠
  3192. return true;
  3193. }
  3194. else
  3195. {
  3196. ASSERT(false);
  3197. return false;
  3198. }
  3199. }
  3200. else
  3201. {
  3202. ASSERT(false);
  3203. return false;
  3204. }
  3205. }
  3206. else
  3207. {
  3208. ASSERT(false);
  3209. return false;
  3210. }
  3211. }
  3212. case WIK_DAN_PENG:
  3213. {
  3214. BYTE CardIndex = m_GameLogic.SwitchToCardIndex(cbTargetCard);
  3215. if (m_cbCardIndex[wTargetUser][CardIndex]--)
  3216. {
  3217. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(cbTargetCaiCard[0])]--)
  3218. {
  3219. ASSERT(m_cbWeaveItemCount[wTargetUser] < 4);
  3220. if (m_cbWeaveItemCount[wTargetUser] > 4)return false;
  3221. WORD wIndex = m_cbWeaveItemCount[wTargetUser]++;
  3222. m_WeaveItemArray[wTargetUser][wIndex].cbPublicCard = TRUE;
  3223. m_WeaveItemArray[wTargetUser][wIndex].cbCenterCard = cbTargetCard;
  3224. m_WeaveItemArray[wTargetUser][wIndex].cbWeaveKind = cbTargetAction;
  3225. m_WeaveItemArray[wTargetUser][wIndex].wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser;
  3226. m_WeaveItemArray[wTargetUser][wIndex].cbMargicOffset[0] = cbTargetCaiCard[0];
  3227. return true;
  3228. }
  3229. else
  3230. {
  3231. ASSERT(false);
  3232. return false;
  3233. }
  3234. }
  3235. else
  3236. {
  3237. ASSERT(false);
  3238. return false;
  3239. }
  3240. }
  3241. case WIK_DAN_MING_GANG:
  3242. {
  3243. BYTE CardIndex = m_GameLogic.SwitchToCardIndex(cbTargetCard);
  3244. if (m_cbCardIndex[wTargetUser][CardIndex] - 2 >= 0)
  3245. {
  3246. m_cbCardIndex[wTargetUser][CardIndex] -= 2;
  3247. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(cbTargetCaiCard[0])]--)
  3248. {
  3249. ASSERT(m_cbWeaveItemCount[wTargetUser] < 4);
  3250. if (m_cbWeaveItemCount[wTargetUser] > 4)return false;
  3251. WORD wIndex = m_cbWeaveItemCount[wTargetUser]++;
  3252. m_WeaveItemArray[wTargetUser][wIndex].cbPublicCard = TRUE;
  3253. m_WeaveItemArray[wTargetUser][wIndex].cbCenterCard = cbTargetCard;
  3254. m_WeaveItemArray[wTargetUser][wIndex].cbWeaveKind = cbTargetAction;
  3255. m_WeaveItemArray[wTargetUser][wIndex].wProvideUser = (m_wProvideUser == INVALID_CHAIR) ? wTargetUser : m_wProvideUser;
  3256. m_WeaveItemArray[wTargetUser][wIndex].cbMargicOffset[0] = cbTargetCaiCard[0];
  3257. if (mPlayGameUserCount == 4)
  3258. {
  3259. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3260. m_cbLeftCardCount -= 6;
  3261. else//少于三墩就只有一张可以抓的牌咯
  3262. m_cbLeftCardCount = 1;
  3263. }
  3264. m_cbGangCount++;//打了几个杠
  3265. return true;
  3266. }
  3267. else
  3268. {
  3269. ASSERT(false);
  3270. return false;
  3271. }
  3272. }
  3273. else
  3274. {
  3275. ASSERT(false);
  3276. return false;
  3277. }
  3278. }
  3279. case WIK_LEFT: //上牌操作,左吃
  3280. {
  3281. //删除扑克
  3282. BYTE cbRemoveCard[3];
  3283. BYTE cbMagicCard[4] = { 0 };
  3284. m_GameLogic.GetWeaveCard(WIK_LEFT, cbTargetCard, cbMagicCard, cbRemoveCard);
  3285. VERIFY(m_GameLogic.RemoveCard(cbRemoveCard, 3, &cbTargetCard, 1));
  3286. VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, 2));
  3287. return true;
  3288. }
  3289. case WIK_RIGHT: //上牌操作,右吃
  3290. {
  3291. //删除扑克
  3292. BYTE cbRemoveCard[3];
  3293. BYTE cbMagicCard[4] = { 0 };
  3294. m_GameLogic.GetWeaveCard(WIK_RIGHT, cbTargetCard, cbMagicCard, cbRemoveCard);
  3295. VERIFY(m_GameLogic.RemoveCard(cbRemoveCard, 3, &cbTargetCard, 1));
  3296. VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, 2));
  3297. return true;
  3298. }
  3299. case WIK_CENTER: //上牌操作,中吃
  3300. {
  3301. //删除扑克
  3302. BYTE cbRemoveCard[3];
  3303. BYTE cbMagicCard[4] = { 0 };
  3304. m_GameLogic.GetWeaveCard(WIK_CENTER, cbTargetCard, cbMagicCard, cbRemoveCard);
  3305. VERIFY(m_GameLogic.RemoveCard(cbRemoveCard, 3, &cbTargetCard, 1));
  3306. VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, 2));
  3307. return true;
  3308. }
  3309. case WIK_PENG: //碰牌操作
  3310. {
  3311. //删除扑克
  3312. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)] < 2)
  3313. {
  3314. ASSERT(false);
  3315. return false;
  3316. }
  3317. BYTE cbRemoveCard[] = { cbTargetCard, cbTargetCard };
  3318. VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, 2));
  3319. return true;
  3320. }
  3321. case WIK_MING_GANG: //明杠牌操作
  3322. {
  3323. if (m_cbCardIndex[wTargetUser][m_GameLogic.SwitchToCardIndex(m_cbProvideCard)] != 3)
  3324. {
  3325. ASSERT(false);
  3326. return false;
  3327. }
  3328. BYTE cbRemoveCard[] = { cbTargetCard, cbTargetCard, cbTargetCard };
  3329. VERIFY(m_GameLogic.RemoveCard(m_cbCardIndex[wTargetUser], cbRemoveCard, CountArray(cbRemoveCard)));
  3330. if (mPlayGameUserCount == 4)
  3331. {
  3332. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3333. m_cbLeftCardCount -= 6;
  3334. else//少于三墩就只有一张可以抓的牌咯
  3335. m_cbLeftCardCount = 1;
  3336. }
  3337. m_cbGangCount++;//打了几个杠
  3338. return true;
  3339. }
  3340. default:
  3341. {
  3342. ASSERT(false);
  3343. return false;
  3344. }
  3345. }
  3346. }
  3347. //自主操作删除手牌
  3348. bool CTableFrameSink_tdh::DeleteCard(WORD wChairID, BYTE cbCaiShenCard[4], int cbOperateCode, BYTE cbOperateCard)
  3349. {
  3350. switch (cbOperateCode)
  3351. {
  3352. case WIK_QUANG_AN_GANG:
  3353. {
  3354. //变量定义
  3355. BYTE cbWeaveIndex = 0xFF;
  3356. BYTE cbCardIndex = m_GameLogic.SwitchToCardIndex(cbOperateCard);
  3357. BYTE CaiShenCount = m_GameLogic.GetMaigcCardCount(m_cbCardIndex[wChairID]);
  3358. if (CaiShenCount > 3)
  3359. {
  3360. if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbCaiShenCard[0])]--)
  3361. {
  3362. if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbCaiShenCard[1])]--)
  3363. {
  3364. if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbCaiShenCard[2])]--)
  3365. {
  3366. if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbCaiShenCard[3])]--)
  3367. {
  3368. cbWeaveIndex = m_cbWeaveItemCount[wChairID]++;
  3369. m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = FALSE;
  3370. m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID;
  3371. m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode;
  3372. m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard;
  3373. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[0] = cbCaiShenCard[0];
  3374. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[1] = cbCaiShenCard[1];
  3375. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[2] = cbCaiShenCard[2];
  3376. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[3] = cbCaiShenCard[3];
  3377. if (mPlayGameUserCount == 4)
  3378. {
  3379. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3380. m_cbLeftCardCount -= 6;
  3381. else//少于三墩就只有一张可以抓的牌咯
  3382. m_cbLeftCardCount = 1;
  3383. }
  3384. m_cbGangCount++;//打了几个杠
  3385. return true;
  3386. }
  3387. else
  3388. {
  3389. ASSERT(false);
  3390. return false;
  3391. }
  3392. }
  3393. else
  3394. {
  3395. ASSERT(false);
  3396. return false;
  3397. }
  3398. }
  3399. else
  3400. {
  3401. ASSERT(false);
  3402. return false;
  3403. }
  3404. }
  3405. else
  3406. {
  3407. ASSERT(false);
  3408. return false;
  3409. }
  3410. }
  3411. else
  3412. {
  3413. ASSERT(false);
  3414. return false;
  3415. }
  3416. }
  3417. case WIK_SAN_AN_GANG:
  3418. {
  3419. //变量定义
  3420. BYTE cbWeaveIndex = 0xFF;
  3421. BYTE cbCardIndex = m_GameLogic.SwitchToCardIndex(cbOperateCard);
  3422. BYTE CaiShenCount = m_GameLogic.GetMaigcCardCount(m_cbCardIndex[wChairID]);
  3423. if (CaiShenCount > 2)
  3424. {
  3425. if (m_cbCardIndex[wChairID][cbCardIndex]--)
  3426. {
  3427. if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbCaiShenCard[0])]--)
  3428. {
  3429. if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbCaiShenCard[1])]--)
  3430. {
  3431. if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbCaiShenCard[2])]--)
  3432. {
  3433. cbWeaveIndex = m_cbWeaveItemCount[wChairID]++;
  3434. m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = FALSE;
  3435. m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID;
  3436. m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode;
  3437. m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard;
  3438. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[0] = cbCaiShenCard[0];
  3439. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[1] = cbCaiShenCard[1];
  3440. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[2] = cbCaiShenCard[2];
  3441. if (mPlayGameUserCount == 4)
  3442. {
  3443. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3444. m_cbLeftCardCount -= 6;
  3445. else//少于三墩就只有一张可以抓的牌咯
  3446. m_cbLeftCardCount = 1;
  3447. }
  3448. return true;
  3449. }
  3450. else
  3451. {
  3452. ASSERT(false);
  3453. return false;
  3454. }
  3455. }
  3456. else
  3457. {
  3458. ASSERT(false);
  3459. return false;
  3460. }
  3461. }
  3462. else
  3463. {
  3464. ASSERT(false);
  3465. return false;
  3466. }
  3467. }
  3468. else
  3469. {
  3470. ASSERT(false);
  3471. return false;
  3472. }
  3473. }
  3474. else
  3475. {
  3476. ASSERT(false);
  3477. return false;
  3478. }
  3479. }
  3480. case WIK_SHUANG_AN_GANG:
  3481. {
  3482. //变量定义
  3483. BYTE cbWeaveIndex = 0xFF;
  3484. BYTE cbCardIndex = m_GameLogic.SwitchToCardIndex(cbOperateCard);
  3485. BYTE CaiShenCount = m_GameLogic.GetMaigcCardCount(m_cbCardIndex[wChairID]);
  3486. if (CaiShenCount > 1)
  3487. {
  3488. if (m_cbCardIndex[wChairID][cbCardIndex] - 2 >= 0)
  3489. {
  3490. m_cbCardIndex[wChairID][cbCardIndex] -= 2;
  3491. if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbCaiShenCard[0])]--)
  3492. {
  3493. if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbCaiShenCard[1])]--)
  3494. {
  3495. cbWeaveIndex = m_cbWeaveItemCount[wChairID]++;
  3496. m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = FALSE;
  3497. m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID;
  3498. m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode;
  3499. m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard;
  3500. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[0] = cbCaiShenCard[0];
  3501. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[1] = cbCaiShenCard[1];
  3502. if (mPlayGameUserCount == 4)
  3503. {
  3504. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3505. m_cbLeftCardCount -= 6;
  3506. else//少于三墩就只有一张可以抓的牌咯
  3507. m_cbLeftCardCount = 1;
  3508. }
  3509. m_cbGangCount++;//打了几个杠
  3510. return true;
  3511. }
  3512. else
  3513. {
  3514. ASSERT(false);
  3515. return false;
  3516. }
  3517. }
  3518. else
  3519. {
  3520. ASSERT(false);
  3521. return false;
  3522. }
  3523. }
  3524. else
  3525. {
  3526. ASSERT(false);
  3527. return false;
  3528. }
  3529. }
  3530. else
  3531. {
  3532. ASSERT(false);
  3533. return false;
  3534. }
  3535. }
  3536. case WIK_DAN_AN_GANG:
  3537. {
  3538. //变量定义
  3539. BYTE cbWeaveIndex = 0xFF;
  3540. BYTE cbCardIndex = m_GameLogic.SwitchToCardIndex(cbOperateCard);
  3541. BYTE CaiShenCount = m_GameLogic.GetMaigcCardCount(m_cbCardIndex[wChairID]);
  3542. if (CaiShenCount > 0)
  3543. {
  3544. if (m_cbCardIndex[wChairID][cbCardIndex] - 3 >= 0)
  3545. {
  3546. m_cbCardIndex[wChairID][cbCardIndex] -= 3;
  3547. if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbCaiShenCard[0])]--)
  3548. {
  3549. cbWeaveIndex = m_cbWeaveItemCount[wChairID]++;
  3550. m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = FALSE;
  3551. m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID;
  3552. m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode;
  3553. m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard;
  3554. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[0] = cbCaiShenCard[0];
  3555. if (mPlayGameUserCount == 4)
  3556. {
  3557. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3558. m_cbLeftCardCount -= 6;
  3559. else//少于三墩就只有一张可以抓的牌咯
  3560. m_cbLeftCardCount = 1;
  3561. }
  3562. m_cbGangCount++;//打了几个杠
  3563. return true;
  3564. }
  3565. else
  3566. {
  3567. ASSERT(false);
  3568. return false;
  3569. }
  3570. }
  3571. else
  3572. {
  3573. ASSERT(false);
  3574. return false;
  3575. }
  3576. }
  3577. else
  3578. {
  3579. ASSERT(false);
  3580. return false;
  3581. }
  3582. }
  3583. case WIK_DAN_BU_GANG:
  3584. {
  3585. //变量定义
  3586. BYTE cbWeaveIndex = 0xFF;
  3587. BYTE cbCardIndex = m_GameLogic.SwitchToCardIndex(cbOperateCard);
  3588. BYTE CaiShenCount = m_GameLogic.GetMaigcCardCount(m_cbCardIndex[wChairID]);
  3589. if (CaiShenCount > 0 && cbCaiShenCard[0] != 0)
  3590. {
  3591. if (m_cbCardIndex[wChairID][m_GameLogic.SwitchToCardIndex(cbCaiShenCard[0])]--)
  3592. {
  3593. INT cbWeaveKind;
  3594. for (BYTE i = 0; i < m_cbWeaveItemCount[wChairID]; i++)
  3595. {
  3596. cbWeaveKind = m_WeaveItemArray[wChairID][i].cbWeaveKind;
  3597. BYTE cbCenterCard = m_WeaveItemArray[wChairID][i].cbCenterCard;
  3598. if ((cbCenterCard == cbOperateCard) && (cbWeaveKind & (WIK_PENG | WIK_DAN_PENG | WIK_SHUANG_PENG)))
  3599. {
  3600. cbWeaveIndex = i;
  3601. break;
  3602. }
  3603. }
  3604. if (cbWeaveKind == WIK_PENG)
  3605. {
  3606. m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = true;
  3607. //m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID;
  3608. m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode;
  3609. m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard;
  3610. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[0] = cbCaiShenCard[0];
  3611. }
  3612. else if (cbWeaveKind == WIK_DAN_PENG)
  3613. {
  3614. m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = true;
  3615. //m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID;
  3616. m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode;
  3617. m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard;
  3618. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[1] = cbCaiShenCard[0];
  3619. }
  3620. else
  3621. {
  3622. m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = true;
  3623. //m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID;
  3624. m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode;
  3625. m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard;
  3626. m_WeaveItemArray[wChairID][cbWeaveIndex].cbMargicOffset[2] = cbCaiShenCard[0];
  3627. }
  3628. if (mPlayGameUserCount == 4)
  3629. {
  3630. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3631. m_cbLeftCardCount -= 6;
  3632. else//少于三墩就只有一张可以抓的牌咯
  3633. m_cbLeftCardCount = 1;
  3634. }
  3635. m_cbGangCount++;//打了几个杠
  3636. return true;
  3637. }
  3638. else
  3639. {
  3640. ASSERT(false);
  3641. return false;
  3642. }
  3643. }
  3644. else
  3645. {
  3646. ASSERT(false);
  3647. return false;
  3648. }
  3649. }
  3650. case WIK_AN_GANG: //暗杠牌操作
  3651. {
  3652. //扑克效验
  3653. ASSERT((cbOperateCode == WIK_AN_GANG) || (m_GameLogic.IsValidCard(cbOperateCard) == true));
  3654. if ((cbOperateCode != WIK_AN_GANG) && (m_GameLogic.IsValidCard(cbOperateCard) == false))
  3655. return false;
  3656. //变量定义
  3657. BYTE cbWeaveIndex = 0xFF;
  3658. BYTE cbCardIndex = m_GameLogic.SwitchToCardIndex(cbOperateCard);
  3659. //杠牌处理
  3660. if (m_cbCardIndex[wChairID][cbCardIndex] == 4)
  3661. {
  3662. //扑克效验
  3663. ASSERT(m_cbCardIndex[wChairID][cbCardIndex] == 4);
  3664. if (m_cbCardIndex[wChairID][cbCardIndex] != 4)
  3665. {
  3666. ASSERT(false);
  3667. return false;
  3668. }
  3669. cbWeaveIndex = m_cbWeaveItemCount[wChairID]++;
  3670. m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = FALSE;
  3671. m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID;
  3672. m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode;
  3673. m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard;
  3674. }
  3675. else
  3676. {
  3677. ASSERT(FALSE);
  3678. return false;
  3679. }
  3680. //删除扑克
  3681. m_cbCardIndex[wChairID][cbCardIndex] = 0;
  3682. if (mPlayGameUserCount == 4)
  3683. {
  3684. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3685. m_cbLeftCardCount -= 6;
  3686. else//少于三墩就只有一张可以抓的牌咯
  3687. m_cbLeftCardCount = 1;
  3688. }
  3689. m_cbGangCount++;//打了几个杠
  3690. return true;
  3691. }
  3692. case WIK_BU_GANG:
  3693. {
  3694. //扑克效验
  3695. ASSERT((cbOperateCode == WIK_NULL) || (cbOperateCode == WIK_BU_GANG) || (m_GameLogic.IsValidCard(cbOperateCard) == true));
  3696. if ((cbOperateCode != WIK_BU_GANG) && (m_GameLogic.IsValidCard(cbOperateCard) == false))
  3697. return false;
  3698. BYTE cbWeaveIndex = 0xFF;
  3699. BYTE cbCardIndex = m_GameLogic.SwitchToCardIndex(cbOperateCard);
  3700. //杠牌处理
  3701. if (m_cbCardIndex[wChairID][cbCardIndex] >= 1)//表示续杠类型
  3702. {
  3703. //寻找组合
  3704. for (BYTE i = 0; i < m_cbWeaveItemCount[wChairID]; i++)
  3705. {
  3706. INT cbWeaveKind = m_WeaveItemArray[wChairID][i].cbWeaveKind;
  3707. BYTE cbCenterCard = m_WeaveItemArray[wChairID][i].cbCenterCard;
  3708. if ((cbCenterCard == cbOperateCard) && (cbWeaveKind &(WIK_DAN_PENG | WIK_PENG | WIK_SHUANG_PENG)))
  3709. {
  3710. cbWeaveIndex = i;
  3711. break;
  3712. }
  3713. }
  3714. //效验动作
  3715. ASSERT(cbWeaveIndex != 0xFF);
  3716. if (cbWeaveIndex == 0xFF) return false;
  3717. //组合扑克
  3718. m_WeaveItemArray[wChairID][cbWeaveIndex].cbPublicCard = TRUE;
  3719. //m_WeaveItemArray[wChairID][cbWeaveIndex].wProvideUser = wChairID;
  3720. m_WeaveItemArray[wChairID][cbWeaveIndex].cbWeaveKind = cbOperateCode;
  3721. m_WeaveItemArray[wChairID][cbWeaveIndex].cbCenterCard = cbOperateCard;
  3722. }
  3723. else
  3724. {
  3725. ASSERT(false);
  3726. return false;
  3727. }
  3728. //删除扑克
  3729. m_cbCardIndex[wChairID][cbCardIndex] -= 1;
  3730. if (mPlayGameUserCount == 4)
  3731. {
  3732. if (m_cbLeftCardCount > 6)//扣除3墩可摸的牌
  3733. m_cbLeftCardCount -= 6;
  3734. else//少于三墩就只有一张可以抓的牌咯
  3735. m_cbLeftCardCount = 1;
  3736. }
  3737. m_cbGangCount++;//打了几个杠
  3738. return true;
  3739. }
  3740. default:
  3741. {
  3742. ASSERT(false);
  3743. return false;
  3744. };
  3745. }
  3746. }
  3747. //优先级判断
  3748. bool CTableFrameSink_tdh::OperatorPriority(WORD TempUser, WORD &wTargetUser, int &cbTargetAction)
  3749. {
  3750. for (WORD UserPlayIndex = 0; UserPlayIndex < mPlayGameUserCount; UserPlayIndex++)//除了打牌人,操作人与其他两位对操作优先级
  3751. {
  3752. if (m_bTwoPlayerFlag&&UserPlayIndex == TowMjNullseat)
  3753. {
  3754. continue;
  3755. }
  3756. TempUser = (TempUser + 1) % mPlayGameUserCount;
  3757. if (TempUser == wTargetUser)continue;
  3758. //获取动作
  3759. int cbUserAction = (m_bResponse[TempUser] == false) ? m_cbUserAction[TempUser] : m_cbPerformAction[TempUser];
  3760. //优先级别
  3761. BYTE cbUserActionRank = m_GameLogic.GetUserActionRank(cbUserAction);
  3762. BYTE cbTargetActionRank = m_GameLogic.GetUserActionRank(cbTargetAction);
  3763. //动作判断
  3764. if (cbUserActionRank > cbTargetActionRank)
  3765. {
  3766. wTargetUser = TempUser;
  3767. cbTargetAction = cbUserAction;
  3768. continue;
  3769. }
  3770. if (cbUserActionRank == cbTargetActionRank && cbTargetActionRank != WIK_NULL)
  3771. {
  3772. if (UserPlayIndex == 2)//肯定和其他人都比了,最后一次两个人的操作一样,且表示操作人不在末端操作人
  3773. {
  3774. return true;
  3775. }
  3776. else if (UserPlayIndex == 1)//对比一次,对比了两次说明操作人不是下家的下家;操作人只能是第一家或者最后一家,如果是第一家操作:,如果是最后一家
  3777. {
  3778. WORD TempTempUser = (TempUser + 1) % mPlayGameUserCount;
  3779. if (wTargetUser == TempTempUser)//确定操作人是最后一个,这是第二次对比
  3780. {
  3781. wTargetUser = TempUser;
  3782. cbTargetAction = cbUserAction;
  3783. return true;
  3784. }
  3785. else//第一次对比,确定操作人是出牌人下家,这个时候再把他和后面一个人的牌权对比
  3786. {
  3787. int cbUserAction = (m_bResponse[TempTempUser] == false) ? m_cbUserAction[TempTempUser] : m_cbPerformAction[TempTempUser];
  3788. //优先级别
  3789. BYTE cbUserActionRank = m_GameLogic.GetUserActionRank(cbUserAction);
  3790. BYTE cbTargetActionRank = m_GameLogic.GetUserActionRank(cbTargetAction);
  3791. if (cbUserActionRank > cbTargetActionRank)
  3792. {
  3793. wTargetUser = TempTempUser;
  3794. cbTargetAction = cbUserAction;
  3795. return true;
  3796. }
  3797. break;
  3798. }
  3799. }
  3800. else//冲上来就比了一次,说操作人不是打牌人下家
  3801. {
  3802. wTargetUser = TempUser;
  3803. cbTargetAction = cbUserAction;
  3804. WORD TempTempUser = (TempUser + 1) % mPlayGameUserCount;
  3805. if (wTargetUser == TempTempUser)TempTempUser = (TempTempUser + 1) % mPlayGameUserCount;//如果在中间就换一个人
  3806. int cbUserAction = (m_bResponse[TempTempUser] == false) ? m_cbUserAction[TempTempUser] : m_cbPerformAction[TempTempUser];
  3807. //优先级别
  3808. BYTE cbUserActionRank = m_GameLogic.GetUserActionRank(cbUserAction);
  3809. BYTE cbTargetActionRank = m_GameLogic.GetUserActionRank(cbTargetAction);
  3810. if (cbUserActionRank > cbTargetActionRank)
  3811. {
  3812. wTargetUser = TempTempUser;
  3813. cbTargetAction = cbUserAction;
  3814. return true;
  3815. }
  3816. return true;
  3817. }
  3818. }
  3819. }
  3820. return true;
  3821. }
  3822. int CTableFrameSink_tdh::bHuPaiType(CChiHuRight &CChiHuRight)
  3823. {
  3824. int hutype = 0;
  3825. if (!(CChiHuRight&ZJ_TAI_QingYiSe).IsEmpty())
  3826. {
  3827. hutype |= ZJ_TAI_QingYiSe;
  3828. }
  3829. if (!(CChiHuRight&ZJ_TAI_DongFeng).IsEmpty())
  3830. {
  3831. hutype |= ZJ_TAI_DongFeng;
  3832. }
  3833. if (!(CChiHuRight&ZJ_TAI_WuMagic).IsEmpty())
  3834. {
  3835. hutype |= ZJ_TAI_WuMagic;
  3836. }
  3837. if (!(CChiHuRight&ZJ_TAI_QuanShun).IsEmpty())
  3838. {
  3839. hutype |= ZJ_TAI_QuanShun;
  3840. }
  3841. if (!(CChiHuRight&ZJ_TAI_PengPeng).IsEmpty())
  3842. {
  3843. hutype |= ZJ_TAI_PengPeng;
  3844. }
  3845. if (!(CChiHuRight&ZJ_TAI_HunYiSe).IsEmpty())
  3846. {
  3847. hutype |= ZJ_TAI_HunYiSe;
  3848. }
  3849. if (!(CChiHuRight&ZJ_TAI_Gang).IsEmpty())
  3850. {
  3851. hutype |= ZJ_TAI_Gang;
  3852. }
  3853. if (!(CChiHuRight&ZJ_TAI_ZFB).IsEmpty())
  3854. {
  3855. hutype |= ZJ_TAI_ZFB;
  3856. }
  3857. if (!(CChiHuRight&ZJ_TAI_QuanZi).IsEmpty())
  3858. {
  3859. hutype = ZJ_TAI_QuanZi;
  3860. }
  3861. if (!(CChiHuRight&ZJ_TAI_ZHAHU).IsEmpty())
  3862. {
  3863. hutype = ZJ_TAI_ZHAHU;
  3864. }
  3865. if (!(CChiHuRight&ZJ_TAI_SiCaiHu).IsEmpty())
  3866. {
  3867. hutype = ZJ_TAI_SiCaiHu;
  3868. }
  3869. if (!(CChiHuRight&ZJ_TAI_CaiDiao).IsEmpty())
  3870. {
  3871. hutype = ZJ_TAI_CaiDiao;
  3872. }
  3873. return hutype;
  3874. }