#ifndef TABLE_FRAME_SINK_HEAD_FILE_DSC #define TABLE_FRAME_SINK_HEAD_FILE_DSC #pragma once #include "Stdafx.h" #include "GameLogic_dcs.h" #include "ReplayRecordManager.h" #include "data.h" #include "../俱乐部/Source/MessageDef/Pb_RecordPacket.pb.h" struct CanDcsSt{ BYTE MagicCard; BYTE MagicCardNext; BYTE nTai; bool bDuCanHu; }; struct CanMadeMagic{ BYTE firstIndex; BYTE SecIndex; CanMadeMagic(){ firstIndex = MAX_INDEX; SecIndex = MAX_INDEX; } }; struct CaiCards{ BYTE firstCardIndex; BYTE secCardIndex; }; #define DingDuGao2 0x0 #define DingRightGao2 0x40 #define DingLeftGao2 0x80 #define DingLeftAndRightGao2 0xC0 #define DingMagicMinTai 3 #define TowMjNullseat 1 //游戏桌子类 class CTableFrameSink_dcs : public ITableFrameSink, public ITableUserAction { enum MagicCount { MagicZero = 0, MagicOne, MagicTwo, }; //游戏变量 public: UINT32 m_startTime; //游戏开始时间 BYTE LianXuHuPai[GAME_PLAYER]; //连续胡牌次数,用来记录老庄的 LONG m_lSiceCount; //骰子点数 WORD m_wBankerUser; //庄家用户,庄家用户是老庄高8位为1,否则就是平常的 WORD m_wNextBankerUser; //下一个庄家 int m_lGameScore[GAME_PLAYER]; //单局游戏得分 int m_lGameTatolScore[GAME_PLAYER]; //单轮积分计算 拥有计分 BYTE m_HuPai[GAME_PLAYER]; //玩家胡牌次数 int m_HuPaiLiuShui[16*GAME_PLAYER]; //流水详情 BYTE m_cbCardIndex[GAME_PLAYER][MAX_INDEX]; //用户扑克 BYTE m_bTrustee[GAME_PLAYER]; //是否托管 BYTE m_bReading[GAME_PLAYER]; //是否准备 BYTE m_cbMagicFirstData; //癞子皮(两个财神牌) BYTE m_cbMagicSecondData; //癞子 BYTE m_cbQiangGangCardData[GAME_PLAYER]; //抢杠的牌 bool m_bPlayStatus[GAME_PLAYER]; //玩家状态 std::list m_offlineUsers; //掉线的玩家 //BYTE m_OutLastLaiZiData; //最后杠牌数据 BYTE m_PaiQuan[GAME_PLAYER]; //1表示 当前不是自己的牌权,但是已经听了 BYTE m_TabbOutCardCout[GAME_PLAYER]; //可以打出的牌就听牌的个数 255表示 当前不是自己的牌权,但是已经听了 BYTE m_TabbOutCardData[GAME_PLAYER][MAX_COUNT]; //具体打哪几张牌 胡牌个数255 表示可以胡任意一个牌。 BYTE m_TabbTingCardCount[GAME_PLAYER][MAX_COUNT]; //相对应打出牌可听牌个数,索引表示第几张,值是对应对应的听牌个数 WORD m_TabbTingCardData[GAME_PLAYER][MAX_COUNT][MAX_TING]; //具体听牌数据,一维索引表示打出牌的第几个,二维索引表示听牌的第几个,值表示牌数据 // m_TabbTingCardData[wChairID][0][m_cbTingParCount - 1] public: CMD_S_GameConfig m_gameConfig; //游戏配置 bool m_isCanOutCard; //是否可以出牌 bool m_bDelete; //是否解散房间 bool bIsHuang; //是否黄庄 //出牌信息 private: WORD m_wOutCardUser; //出牌用户 BYTE m_cbOutCardData; //出牌扑克 BYTE m_cbOutCardCount; //出牌数目 BYTE m_cbDiscardCount[GAME_PLAYER]; //丢弃数目 BYTE m_cbDiscardCard[GAME_PLAYER][40]; //丢弃记录 //记忆库记录的是每一次牌权到另一次牌权牌 就是从抓牌到下一次抓牌的记忆库 BYTE m_cbLastDisCardData[GAME_PLAYER][MAX_COUNT];//每个玩家得记忆库,用于判断是否可以碰不 BYTE m_cbLastDisCount[GAME_PLAYER]; //每个玩家记忆库得个数 //发牌信息 private: BYTE m_cbSendCardData; //发牌扑克 BYTE m_cbSendCardCount; //发牌数目 BYTE m_cbLeftCardCount; //剩余数目 BYTE m_cbRepertoryCard[MAX_REPERTORY_ZJ]; //库存扑克 BYTE m_cbShiJiLeftCardCount; //实际剩余数目 BYTE m_cbGangCount; //记录杠的次数 byte m_cbTotalCardCount; //玩法总牌数 //运行变量 private: WORD m_wResumeUser; //还原用户(下一个用户?) WORD m_wCurrentUser; //当前用户 WORD m_wProvideUser; //供应用户 BYTE m_cbProvideCard; //供应扑克 //状态变量 private: //bool m_bGangStatus; //杠上开花状态位 bool m_bUsersGangStatus[GAME_PLAYER];//杠上开花状态位 int m_bGangOption; // 用操作状态标示 是补杠 暗杠 还是明杠 int m_GangPrivedUserID; //保存用户杠牌时 自己的补杠,暗杠,还是别人点的明杠 bool m_bQiangGang; //抢杠胡标示位,当有补杠,且有胡为true //用户状态 private: bool m_bResponse[GAME_PLAYER]; //响应标志 INT m_cbUserAction[GAME_PLAYER]; //用户动作 BYTE m_cbOperateCard[GAME_PLAYER]; //操作扑克 BYTE m_cbOperateCaiCard[GAME_PLAYER][GAME_PLAYER];//财神牌操作扑克 INT m_cbPerformAction[GAME_PLAYER]; //执行动作 //组合扑克 private: BYTE m_cbWeaveItemCount[GAME_PLAYER]; //组合数目 tagWeaveItem m_WeaveItemArray[GAME_PLAYER][MAX_WEAVE];//组合扑克 //组件变量 private: CGameLogic_dcs m_GameLogic; //游戏逻辑 ITableFrame * m_pITableFrame; //框架接口 const tagGameServiceOption * m_pGameServiceOption; //配置参数 bool m_bReplayRecordStart; //是否开始录像 std::vector m_UserReplayRecord; //对四个位置用户的数据的记录,用于回放。 //bool m_bReduceBean; //是否已扣房卡(游戏豆) //LONGLONG m_lUserTmpScore[GAME_PLAYER]; CString mTableDatastrPath;//tabledata 所在路径 BOOL mBWriteTableData; //游戏人数 byte mPlayGameUserCount; BOOL m_bTwoPlayerFlag; //桌子ID int int mGameTableId; //函数定义 public: //构造函数 CTableFrameSink_dcs(); //析构函数 virtual ~CTableFrameSink_dcs(); //void ReduceBean(); //bool IsCanOutCard(); //是否可以出牌 //基础接口 public: //释放对象 virtual VOID Release() { delete this; } //接口查询 virtual void * QueryInterface(const IID & Guid, DWORD dwQueryVer); //管理接口 public: //初始化 virtual bool Initialization(IUnknownEx * pIUnknownEx); //复位桌子 virtual VOID RepositionSink(); //查询接口 public: virtual void DeletePrivateTable(bool bSendState = false); virtual bool ConcludeGame(BYTE cbGameStatus, bool bSendState = false) { //结束记录回放数据 auto dataPair = RepayRecordEnd(); //结束游戏 m_pITableFrame->ConcludeGame(cbGameStatus, bSendState); return true; } //查询限额 virtual SCORE QueryConsumeQuota(IServerUserItem * pIServerUserItem){ return 0; }; //最少积分 virtual SCORE QueryLessEnterScore(WORD wChairID, IServerUserItem * pIServerUserItem){ return 0; }; //查询是否扣服务费 virtual bool QueryBuckleServiceCharge(WORD wChairID){return true;} //查询总得分 virtual int QueryTatolScore(WORD wChairID){ if (wChairID >= GAME_PLAYER || wChairID<0) ASSERT(false); return m_lGameTatolScore[wChairID]; } //查询癞子数 virtual int QueryTatolLaiGang(WORD wChairID){ if (wChairID >= GAME_PLAYER || wChairID < 0) ASSERT(false); return 0; } //查询是否使用临时积分 virtual bool QueryUseTemporaryScore() { return (0!=lstrlen(m_gameConfig.sPrivateTableID)); //私有房间私用临时积分 } //比赛接口 public: //设置基数 virtual void SetGameBaseScore(LONG lBaseScore){}; //把房间的基本信息记录到类 virtual void SetGameConfig(VOID * pDataBuffer, WORD wDataSize, std::wstring sPrivateRoomId); //游戏事件 public: bool RepayRecordStart(); bool RepayRecordEnd(); bool RepayRecord(WORD wChairID, WORD wSubCmdId, void* pData, WORD wSize); // bool CheckGameConclude(); public: //游戏开始 virtual bool OnEventGameStart(); //游戏结束 virtual bool OnEventGameConclude(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason, bool bSendState = false); //发送场景 virtual bool OnEventSendGameScene(WORD wChiarID, IServerUserItem * pIServerUserItem, BYTE cbGameStatus, bool bSendSecret); //事件接口 public: //定时器事件 virtual bool OnTimerMessage(DWORD wTimerID, WPARAM wBindParam); //数据事件 virtual bool OnDataBaseMessage(WORD wRequestID, VOID * pData, WORD wDataSize) { return false; } //积分事件 virtual bool OnUserScroeNotify(WORD wChairID, IServerUserItem * pIServerUserItem, BYTE cbReason) { return false; } //网络接口 public: //游戏消息处理 virtual bool OnGameMessage(WORD wSubCmdID, VOID * pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem); //框架消息处理 virtual bool OnFrameMessage(WORD wSubCmdID, VOID * pDataBuffer, WORD wDataSize, IServerUserItem * pIServerUserItem); //用户事件 public: //用户断线 virtual bool OnActionUserOffLine(WORD wChairID,IServerUserItem * pIServerUserItem) { return true; } //用户重入 需要处理重新发送指令 virtual bool OnActionUserConnect(WORD wChairID, IServerUserItem * pIServerUserItem); //用户坐下 virtual bool OnActionUserSitDown(WORD wChairID,IServerUserItem * pIServerUserItem, bool bLookonUser); //用户起立 virtual bool OnActionUserStandUp(WORD wChairID,IServerUserItem * pIServerUserItem, bool bLookonUser); //用户同意 virtual bool OnActionUserOnReady(WORD wChairID,IServerUserItem * pIServerUserItem, void * pData, WORD wDataSize) { return true; } //游戏中途旁观进入 virtual bool PerformLookonLogin(IServerUserItem * pIServerUserItem); //游戏事件 protected: //用户出牌 bool OnUserOutCard(WORD wChairID, BYTE cbCardData); //用户操作 bool OnUserOperateCard(WORD wChairID, int cbOperateCode, BYTE cbOperateCard, BYTE cbCaiShenCard[4]); //辅助函数 protected: //发送操作 bool SendOperateNotify(); //派发扑克,默认false正常起牌,true末尾棋牌 bool DispatchCardData(WORD wCurrentUser,bool bTail=false); //响应判断 bool EstimateUserRespond(WORD wCenterUser, BYTE cbCenterCard, enEstimatKind EstimatKind); //返回胡牌牌型 int bHuPaiType(CChiHuRight &CChiHuRight); //优先级判断 bool OperatorPriority(WORD TmpwProvideUser, WORD &wOptUser, int &cbTargetAction); //广播操作扣手牌牌 bool DeleteCaiShenCard(WORD wChairID, BYTE cbTargetCaiCard[4], int cbTargetAction, BYTE cbTargetCard); //自主操作扣财神牌 bool DeleteCard(WORD wChairID, BYTE cbTargetCaiCard[4], int cbOperateCode, BYTE cbOperateCard); //获取剩余牌数 BYTE RemainNum(WORD wChairId, const BYTE m_cbCard,BYTE cbOutCardIndex); //听牌数据函数 bool TingCard(WORD wChairID); //打出牌时固定听牌数据 bool OutTingCard(WORD wChairID, BYTE cardIndex); //发送听牌协议 void HttpTingCard(WORD wChairID); //操作协议 void HttpOperateResult(WORD wChairID, BYTE cbCaiShenCard[4], int cbOperateCode, BYTE cbOperateCard, int cbActionMask, WORD cbActionCard[6]); ////////////////////////////////////////////////////////////////////////// //ZORO public: BYTE GetNextMagicCardData(BYTE cbMagicCardFirstIndex); BYTE GetLastMagicCardData(BYTE cbMagicCardFirstIndex);//获取财神的上一张牌 int mMaxTaiNum; //包麻将相关 //1 拥有包麻将权限的玩家ID //2 包牌类型 无财 单财 双财 //3 财神index //4 包家 要几台 public: void SetMagicType(int Type){ mMagicType = Type; } int mMagicType; //BYTE mMjType; //0翻财神 1包麻将 2 3 4 后续扩展 血流之类的。 BYTE mBaoTaiNum[GAME_PLAYER]; BYTE mBaoUserInfo[GAME_PLAYER]; int nCountOptBao; int mbStartBaoTai ; //0未开始 1 开始 2结束 3财神结束 BYTE mCurrentBaoUser;//当前包台玩家 BYTE mCurrentMinBaoTai;//当前最小包台 //BaoEnum mMaxBaoNum;//保存前端传递过来的原始值-选包时 bool mBaoCacleDZFB; ////////////////////////////////////////////////////////////////////////// //计分 诸暨 enum _WinWay_ { Win_FangPao = 0, Win_ZiMo, win_DiHu, win_qianggang, }; //胡牌 计算分数 /* *WinChairID 胡牌玩家ID *nTai 胡牌台数 *WinWay 胡牌方式 *provideUserID 如果是放炮,谁放的 * */ void CaculationScore(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score); void FanMagicCaculation(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score); public: //void BaoMjCalculation(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score); void WinFanMagic_FangPao_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score); void WinQiangGang_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CChiHuRight chr, CMD_S_GangScore& cmd_Score); void WinFanMagic_ZiMo_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score); void WinFanMagic_DiHu_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score); // void WinBaoMagic_FangPao_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score); // void WinBaoMagic_ZiMo_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score); // void WinBaoMagic_DiHu_Score(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID, CMD_S_GangScore& cmd_Score); //void CalcDongZFB(BYTE WinChairID, BYTE nTai, BYTE WinWay, BYTE provideUserID); int mZFBBianScore[GAME_PLAYER]; ////////////////////////////////////////////////////////////////////////// //选择包 // int mUserOptBaoTai[GAME_PLAYER]; //bool SelectBaoTaiNum(WORD wChairID, BYTE nMagicTai); //bool SelectBaoMagic(WORD wChairID, BYTE cbMagicFirst,BYTE cbMagicSenced); // bool IsCanReturnResult(); // int FindNextBaoJiaID(int CurrentId); //bool IsAddTaiNum(int nNextID); // bool IsNoBaoUser(); // void NoHaveBaoUser(); ////////////////////////////////////////////////////////////////////////// void WritePaiCardData(TCHAR* TableId,int count); void ReadGameData(); void PrintUsersScore(LPCTSTR strInfo); // bool mBLastBaoStart; // // bool HandleBaoMjZaHu(WORD wChairID, int cbOperateCode, BYTE cbOperateCard, BYTE cbCaiShenCard[4]); // // bool mBZaHu; ////////////////////////////////////////////////////////////////////////// //订财 bool UserDingMagicCard(WORD wChairID); bool GetOneWeaveItemCards(const tagWeaveItem WeaveItem[], BYTE cbWeaveCount, BYTE * cbCards, INT & CardsCount); bool CardInCardArray(BYTE cbCard, BYTE* cbCards, int nCount); bool GetLianXuCards(BYTE* CardsIndex,std::vector &vCards); //获取14张手牌(包括落地牌),能够当作财神的牌,以及此牌当财神时胡的 台数 bool GetMagicCardAndTaiNum(BYTE* cardsIndex, WORD wChairID, BYTE cbCenterCard, std::vector &vCards,BOOL FindOneExit=FALSE); bool GetCanMadeMagicCards(BYTE* cardsIndex, std::vector &vCards,BYTE currentUserIndex); byte GetTaiNumFromCards(BYTE* cardsIndex, WORD wChairID, BYTE cbCenterCard, BYTE firstIndex, BYTE secIndex, bool bQiangGang = false); CMD_S_NOTIFY_QIANGGH mCmd_NotifyQianggh[4]; BOOL IsCanTianhu(); //特殊处理 抢杠胡时,玩家没有对应操作,但其他玩家 断线重连 导致显示的剩余牌不一样的问题。 bool mBCanShowLeft; int mTempLeftCount;//为断线重连准备,只有当发牌后 断线重连才使用真正的剩余牌。否则 增加剩余牌 BOOL GetCardCanHuWithAll(BYTE cbCard, std::vector &vCards); BOOL CardInAll(BYTE CbCard, BYTE *pByte, int Count); ////////////////////////////////////////////////////////////////////////// //保存可以做财神的牌,不可以做的为0 可以做的为4。 // BYTE mCanDingCaiCardArray[GAME_PLAYER][MAX_INDEX]; //根据所有用户落地派计算可以当财神的牌 void CalculationMagicCards(BYTE CurrentUserIndex); void EnumAllWeave(BYTE CurrentUserIndex); }; ////////////////////////////////////////////////////////////////////////// #endif