Files
wnmj/Classes/Games/WNMJ/WN_CardManager.cpp
2026-02-13 14:34:15 +08:00

1285 lines
30 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "WN_CardManager.h"
#include "cocos2d.h"
#include "ui/CocosGUI.h"
#include "cocostudio/CocoStudio.h"
#include "YSAudioEngine.h"
#include "PopScene.h"
using namespace WNMJ_SPACE;
/////////////////////////////// 麻将管理 ///////////////////////////////////////////
WN_CardManager::WN_CardManager()
{
m_IsGameRecord = false;
m_bOutCardStatus = false;
}
WN_CardManager::~WN_CardManager()
{
memset(m_cbOutCarCount, 0x0, sizeof(m_cbOutCarCount));
memset(m_cbWeaveCount, 0x0, sizeof(m_cbWeaveCount));
memset(m_cbHandCardCount, 0x0, sizeof(m_cbHandCardCount));
for (int i = 0; i < GAME_PLAYER; i++)
{
ClearCardList(i);
for (int l = 0; l < MAX_WEAVE; l++)
{
if (m_pWeaveCard[i][l])
{
m_pWeaveCard[i][l]->removeFromParentAndCleanup(true);
m_pWeaveCard[i][l] = nullptr;
}
}
}
for (std::list<WN_SparrowCard*>::iterator it = m_pOutCardSprite.begin(); it != m_pOutCardSprite.end(); it++)
{
WN_SparrowCard* card = *it;
if (card)
{
card->removeFromParentAndCleanup(true);
card = nullptr;
}
}
m_pOutCardSprite.clear();
for (int j = 0; j < 2; j++)
{
if (m_pKingCardSprite[j])
{
m_pKingCardSprite[j]->removeFromParentAndCleanup(true);
m_pKingCardSprite[j] = nullptr;
}
}
if (m_pCurrentOutCard)
{
m_pCurrentOutCard->removeFromParent();
m_pCurrentOutCard = nullptr;
}
}
bool WN_CardManager::init()
{
if (!Layer::init()) {
return false;
}
// 设置大小;
this->setContentSize(Size(1136, 640));
memset(m_cbOutCarCount, 0x0, sizeof(m_cbOutCarCount));
memset(m_pWeaveCard, 0x0, sizeof(m_pWeaveCard));
memset(m_cbWeaveCount, 0x0, sizeof(m_cbWeaveCount));
memset(m_pKingCardSprite, 0x0, sizeof(m_pKingCardSprite));
memset(m_cbHandCardCount, 0x0, sizeof(m_cbHandCardCount));
zeromemory(m_pLastHandCard, sizeof(m_pLastHandCard));
zeromemory(m_bActiveStatus, sizeof(m_bActiveStatus));
m_pCurrentOutCard = nullptr;
m_wCurrentUser = INVALID_CHAIR;
m_wRealChairCount = GAME_PLAYER;
// 高级操作界面
m_pNoticelayer = WN_NotifyDlg::create();
m_pNoticelayer->setVisible(false);
this->addChild(m_pNoticelayer, MAX_REPERTORY);
return true;
}
// 重置
void WN_CardManager::ResetAll()
{
SetCurrentUser(INVALID_CHAIR);
memset(m_cbOutCarCount, 0x0, sizeof(m_cbOutCarCount));
memset(m_cbWeaveCount, 0x0, sizeof(m_cbWeaveCount));
memset(m_cbHandCardCount, 0x0, sizeof(m_cbHandCardCount));
zeromemory(m_bActiveStatus, sizeof(m_bActiveStatus));
m_wRealChairCount = GAME_PLAYER;
for (int i = 0; i < GAME_PLAYER; i++)
{
if (m_pLastHandCard[i])
{
m_pLastHandCard[i]->removeFromParent();
m_pLastHandCard[i] = nullptr;
}
ClearCardList(i);
for (int l = 0; l < MAX_WEAVE; l++)
{
if (m_pWeaveCard[i][l])
{
m_pWeaveCard[i][l]->removeFromParentAndCleanup(true);
m_pWeaveCard[i][l] = nullptr;
}
}
m_cbHandCardCount[i] = 0;
m_cbOutCarCount[i] = 0;
m_cbWeaveCount[i] = 0;
}
for (std::list<WN_SparrowCard*>::iterator it = m_pOutCardSprite.begin(); it != m_pOutCardSprite.end(); it++)
{
WN_SparrowCard* card = *it;
if (card)
{
card->removeFromParentAndCleanup(true);
card = nullptr;
}
}
m_pOutCardSprite.clear();
if (m_pCurrentOutCard)
{
m_pCurrentOutCard->removeFromParent();
m_pCurrentOutCard = nullptr;
}
if (m_pNoticelayer)
{
CCLOG("WN_NotifyDlg HideNotifyDlg...WN_CardManager::ResetAll()");
m_pNoticelayer->HideNotifyDlg();
}
for (int j = 0; j < 2; j++)
{
if (m_pKingCardSprite[j])
{
m_pKingCardSprite[j]->removeFromParentAndCleanup(true);
m_pKingCardSprite[j] = nullptr;
}
}
}
// 设置玩家状态
void WN_CardManager::SetActiveStatus(bool bActiveStatus[], WORD wArrViewChairID[], WORD wRealChairCount)
{
m_wRealChairCount = wRealChairCount;
for (int i = 0; i < GAME_PLAYER; i++)
{
WORD wViewChairID = wArrViewChairID[i];
if (wViewChairID == INVALID_CHAIR) continue;
m_bActiveStatus[wViewChairID] = bActiveStatus[i];
//m_wRealChairCount++; // 统计游戏玩家数量;
}
}
// 设置当前玩家
void WN_CardManager::SetCurrentUser(WORD wChairID)
{
m_wCurrentUser = wChairID;
if (m_pNoticelayer)
{
m_pNoticelayer->m_wCurrentUser = wChairID;
}
m_bOutCardStatus = (m_wCurrentUser == SELF_VIEW_CHAIRID);
}
// 设置录像模式;
void WN_CardManager::SetGameRecord(bool isGameRecord)
{
m_IsGameRecord = isGameRecord;
}
// 设置高级操作界面
void WN_CardManager::SetNoticeData(CMD_S_OperateNotify &OperateNotify)
{
if (m_pNoticelayer)
{
CCLOG("WN_NotifyDlg SetNoticeData...WN_CardManager::SetNoticeData()");
m_pNoticelayer->SetNoticeData(&OperateNotify);
}
}
void WN_CardManager::HideNoticeDlg()
{
if (m_pNoticelayer)
{
CCLOG("WN_NotifyDlg HideNotifyDlg...WN_CardManager::HideNoticeDlg()");
m_pNoticelayer->HideNotifyDlg();
}
}
//是否有高级操作
bool WN_CardManager::IsHaveOperateCard(DWORD dwUserAction)
{
if ((dwUserAction&WIK_WN_CHI) != 0 || (dwUserAction&WIK_WN_PENG) != 0 || (dwUserAction&WIK_WN_GANG) != 0 || (dwUserAction&WIK_WN_CHI_HU) != 0)
{
return true;
}
return false;
}
// 检查操作牌是否正确;
bool WN_CardManager::CheckOperateCard(uint8 cbOperateCard)
{
if (!WN_CGameLogic::IsValidCard(cbOperateCard))
{
return false;
}
// 是不杠(组合牌里有个碰,手里还有一张);
for (int i = 0; i < MAX_WEAVE; i++)
{
if (m_pWeaveCard[SELF_VIEW_CHAIRID][i] && (m_pWeaveCard[SELF_VIEW_CHAIRID][i]->m_dwOperateCode == WIK_WN_PENG)
&& (m_pWeaveCard[SELF_VIEW_CHAIRID][i]->m_cbCardData == cbOperateCard))
{
return true;
}
}
// 暗杠校验(手里有四张);
uint8 cbCardCount = 0;
for (std::list<WN_SparrowCard*>::iterator it = m_SelfHandCardList.begin(); it != m_SelfHandCardList.end(); it++)
{
WN_SparrowCard* card = *it;
if (card && (card->GetCardData() == cbOperateCard))
{
cbCardCount++;
}
}
// 第十四张牌;
if (m_pLastHandCard[SELF_VIEW_CHAIRID] && (m_pLastHandCard[SELF_VIEW_CHAIRID]->GetCardData() == cbOperateCard))
{
cbCardCount++;
}
// 暗杠必须4张牌
if (cbCardCount == 4)
{
return true;
}
//// 明杠看其他玩家打出牌是否和操作牌相同;
//else if (cbCardCount == 3)
//{
// if (m_pCurrentOutCard && (m_pCurrentOutCard->GetCardData() == cbOperateCard))
// {
// return true;
// }
//}
//
//// 摸牌时,未杠下次摸牌提醒杠操作;
//// 补杠:查看手中是否有碰组合;
//for (int l = 0; l < MAX_WEAVE; l++)
//{
// if (m_pWeaveCard[SELF_VIEW_CHAIRID][l] && (m_pWeaveCard[SELF_VIEW_CHAIRID][l]->m_dwOperateCode == WIK_WN_PENG))
// {
// for (std::list<WN_SparrowCard*>::iterator it = m_SelfHandCardList.begin(); it != m_SelfHandCardList.end(); it++)
// {
// WN_SparrowCard* card = *it;
// if (card && (card->GetCardData() == m_pWeaveCard[SELF_VIEW_CHAIRID][l]->m_cbCardData))
// {
// return m_pWeaveCard[SELF_VIEW_CHAIRID][l]->m_cbCardData;
// }
// }
// }
//}
//
//// 暗杠:查看手中是否有四张一样牌;
//uint8 cbIndexArr[MAX_INDEX] = {0};
//for (std::list<WN_SparrowCard*>::iterator it = m_SelfHandCardList.begin(); it != m_SelfHandCardList.end(); it++)
//{
// WN_SparrowCard* card = *it;
// if (card)
// {
// uint8 cbIndex = WN_CGameLogic::getInstance()->SwitchToCardIndex(card->GetCardData());
// cbIndexArr[cbIndex]++;
// }
//}
//
//for (int i = 0; i < MAX_INDEX; i++)
//{
// if (cbIndexArr[i] == 4)
// {
// return WN_CGameLogic::getInstance()->SwitchToCardData(i);
// }
//}
return false;
}
/******************************* 麻将牌操作 *****************************************/
// 发所有牌
float WN_CardManager::SetAllCard(uint8 cbCardData[], WORD wStartID)
{
// 自己发明牌,其他玩家暗牌,调整每个牌属性
for (int i = 0; i < GAME_PLAYER; i++)
{
if (!m_bActiveStatus[i]) continue;
// 没人发13张牌
for (int j = 0; j < MAX_COUNT - 1; j++)
{
WN_SparrowCard* card = nullptr;
// 自己牌
if (i == SELF_VIEW_CHAIRID)
{
uint8 CardValue = cbCardData[j];
if (WN_CGameLogic::getInstance()->IsValidCard(CardValue))
{
card = WN_SparrowCard::createWithDirection(CardValue, SP_SELFSTAND);
card->addClickEventListener(CC_CALLBACK_2(WN_CardManager::onSendCardEvent, this));
card->setPosition(GetCardPoint(i, j));
this->addChild(card);
m_SelfHandCardList.push_back(card);
}
// 打印自己牌
log("DEBUG CARD game start my card_%d = 0x%0x ", j, CardValue);
}
// 对家牌
else if (i == 0)
{
card = WN_SparrowCard::createWithDirection(0xff, SP_OPPSTAND);
card->setPosition(GetCardPoint(i, j));
this->addChild(card);
m_OppHandCardList.push_back(card);
}
// 左边牌
else if (i == 3)
{
card = WN_SparrowCard::createWithDirection(0xff, SP_LSTAND);
card->setPosition(GetCardPoint(i, j));
this->addChild(card, j + SP_LSTAND);
m_LeftHandCardList.push_back(card);
}
// 右边牌
else
{
card = WN_SparrowCard::createWithDirection(0xff, SP_RSTAND);
card->setPosition(GetCardPoint(i, j));
this->addChild(card, SP_RSTAND + MAX_COUNT - j);
m_RightHandCardList.push_back(card);
}
m_cbHandCardCount[i]++;
//if (card)card->setVisible(false);
}
}
SortSelfCard();
return 0.0f;
}
// 发所有牌
float WN_CardManager::SendAllCard(WORD wStartID)
{
// 发牌从庄家开始先发三轮每人4张然后每人发一张
float fDelaytimer = 0.0f; // 延迟时间
for (int i = 0; i < GAME_PLAYER; i++)
{
std::list<WN_SparrowCard*>* __list = GetCardList(i);
for (std::list<WN_SparrowCard*>::iterator it = __list->begin(); it != __list->end(); it++)
{
WN_SparrowCard* card = *it;
if (card)
{
card->setVisible(true);
}
}
}
return fDelaytimer;
}
// 得到手牌坐标
Point WN_CardManager::GetCardPoint(WORD wChairID, uint8 cbIndex)
{
// 根据组合牌数量进行偏移
Point pos = GetWaveCardPoint(wChairID);
// 自己牌
if (wChairID == SELF_VIEW_CHAIRID)
{
pos.x = pos.x + NCMJ_SELF_HAND_CARD_WIDHT*cbIndex;
pos.y = pos.y;
}
// 对家牌
else if (wChairID == 0)
{
pos.x = pos.x - NCMJ_OPP_HAND_CARD_WIDHT*cbIndex;
pos.y = pos.y;
}
// 左边牌
else if (wChairID == 3)
{
pos.x = pos.x;
pos.y = pos.y - NCMJ_LR_HAND_CARD_HIGHT*cbIndex;
}
// 右边牌
else
{
pos.x = pos.x;
pos.y = pos.y + NCMJ_LR_HAND_CARD_HIGHT*cbIndex;
}
return pos;
}
// 发第十四张牌 牌数据,抓牌玩家,前后抓牌
void WN_CardManager::SendCard(uint8 cbCardData, WORD wGetCardUser)
{
// 打印自己牌
log("DEBUG CARD send card wGetCardUser = %d, card = 0x%0x ", wGetCardUser, cbCardData);
WN_SparrowCard* pCard = nullptr;
pCard = WN_SparrowCard::createWithDirection(cbCardData, (EN_SPARROW_TYPE)wGetCardUser);
if (pCard == nullptr) return;
// 录像模式明牌;
if (m_IsGameRecord)
{
pCard->ShowCardValue(cbCardData);
}
// 清除第十四张牌;
if (m_pLastHandCard[wGetCardUser] != nullptr)
{
m_pLastHandCard[wGetCardUser]->removeFromParentAndCleanup(true);
m_pLastHandCard[wGetCardUser] = nullptr;
}
m_pLastHandCard[wGetCardUser] = pCard; // 未选择出牌之前,不放入玩家手牌中
// 控制添加后的层次关系和坐标
int localZOrder = 0;
Point pos;
switch (wGetCardUser)
{
case 0:
{
int _ind = m_OppHandCardList.size();
pos = GetCardPoint(wGetCardUser, _ind);
pos.x = pos.x - NCMJ_OPP_HAND_CARD_WIDHT / 3;
localZOrder = 0;
break;
}
case 3:
{
int _ind = m_LeftHandCardList.size();
pos = GetCardPoint(wGetCardUser, _ind);
pos.y = pos.y - NCMJ_LR_HAND_CARD_HIGHT / 3;
localZOrder = (MAX_COUNT - 1) + SP_LSTAND;
break;
}
case 2:
{
int _ind = m_SelfHandCardList.size();
pos = GetCardPoint(wGetCardUser, _ind);
pos.x = pos.x + NCMJ_SELF_HAND_CARD_WIDHT / 3;
localZOrder = 0;
pCard->addClickEventListener(CC_CALLBACK_2(WN_CardManager::onSendCardEvent, this));
break;
}
case 1:
{
int _ind = m_RightHandCardList.size();
pos = GetCardPoint(wGetCardUser, _ind);
pos.y = pos.y + NCMJ_LR_HAND_CARD_HIGHT / 3;
localZOrder = SP_RSTAND + 1;
break;
}
default:
ASSERT(false);
break;
}
pCard->setPosition(pos);
this->addChild(pCard, localZOrder);
auto moveto = MoveTo::create(0.2f, pos);
auto ani = EaseBackOut::create(moveto);
pCard->runAction(ani);
log("send card pos.x = %f, pos.y = %f, z = %d", pos.x, pos.y, localZOrder);
}
//排序牌
void WN_CardManager::SortSelfCard(WORD wChairID/* = SELF_VIEW_CHAIRID*/)
{
function<bool(WN_SparrowCard*, WN_SparrowCard*)> funSort;
funSort = [](WN_SparrowCard* cardA, WN_SparrowCard* cardB){
if (cardA->GetCardData() < cardB->GetCardData())
{
return true;
}
return false;
};
std::list<WN_SparrowCard*>* __list = GetCardList(wChairID);
if (__list)
{
__list->sort(funSort);
// 填放位置
ResetHandCard(wChairID);
}
}
// 点击出牌
bool WN_CardManager::onSendCardEvent(cocos2d::Ref *pSender, Vec2 pos)
{
if (pSender == nullptr) return false;
//ImageView* btnRoot = (ImageView*)pSender;
WN_SparrowCard* pCardSprite = (WN_SparrowCard*)pSender;
if (pCardSprite == nullptr) return false;
// 滑动出牌
if (pos.y < (pCardSprite->getPositionY() + pCardSprite->getContentSize().height + TOP_CARD_HEIGHT - 5))
{
if (pCardSprite->getPositionY() < TOP_CARD_HEIGHT - 5)
{
pCardSprite->setPositionY(pCardSprite->getPositionY() + TOP_CARD_HEIGHT);
// 把其他已点击的牌落下
for (std::list<WN_SparrowCard*>::iterator it = m_SelfHandCardList.begin(); it != m_SelfHandCardList.end(); it++)
{
WN_SparrowCard* card = *it;
if (card != pCardSprite)
{
if (card->getPositionY() >= (TOP_CARD_HEIGHT - 5))
{
card->setPositionY(card->getPositionY() - TOP_CARD_HEIGHT);
}
}
}
return false;
}
}
// 已经弹起,但当前出牌玩家不是自己,麻将收回
if (m_wCurrentUser != SELF_VIEW_CHAIRID)
{
if (pCardSprite->getPositionY() > TOP_CARD_HEIGHT - 5)
{
pCardSprite->setPositionY(pCardSprite->getPositionY() - TOP_CARD_HEIGHT);
}
return false;
}
else if (m_bOutCardStatus)
{
// 如果高级界面限制,执行过处理
if (m_pNoticelayer->isVisible())
{
m_pNoticelayer->onEventGuo(nullptr);
}
// 得到出牌值;
uint8 cbCardData = pCardSprite->GetCardData();
// 检测是否是杠牌;
if (CheckOperateCard(cbCardData))
{
auto callback = [cbCardData, this](){
//发送数据
CMD_C_OutCard OutCard;
OutCard.cbCardData = cbCardData;
EventCustom event(CUSTOM_EVENT_OUT_CARD);
event.setUserData(&OutCard);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
m_bOutCardStatus = false;
};
PopScene::Instance().show(utility::a_u8("确定要丢弃杠吗?"), callback, nullptr);
}
else
{
//发送数据
CMD_C_OutCard OutCard;
OutCard.cbCardData = cbCardData;
EventCustom event(CUSTOM_EVENT_OUT_CARD);
event.setUserData(&OutCard);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
m_bOutCardStatus = false;
}
log("self out card %d", pCardSprite->GetCardData());
}
return true;
}
// 用户出牌
void WN_CardManager::SubOutCard(uint8 cbCardData, WORD wOutCardUser, bool isShow/* = true*/)
{
if (wOutCardUser == INVALID_CHAIR) return;
if (!WN_CGameLogic::getInstance()->IsValidCard(cbCardData)) return;
std::list<WN_SparrowCard*>* __list = GetCardList(wOutCardUser);
if (__list)
{
// 插入新牌
if (m_pLastHandCard[wOutCardUser])
{
__list->push_back(m_pLastHandCard[wOutCardUser]);
m_pLastHandCard[wOutCardUser] = nullptr;
}
uint8 cbDelCardData = cbCardData;
// 游戏模式,删除其他人手牌;
if (!m_IsGameRecord && (wOutCardUser != SELF_VIEW_CHAIRID))
{
cbDelCardData = 0x0;
}
// 遍历手牌删除
for (std::list<WN_SparrowCard*>::iterator it = __list->begin(); it != __list->end(); it++)
{
WN_SparrowCard* card = *it;
if (card && (card->GetCardData() == cbDelCardData))
{
card->removeFromParentAndCleanup(true);
card = nullptr;
__list->remove(*it);
break;
}
}
// 排序
SortSelfCard(wOutCardUser);
}
if (isShow)
{
ShowCurrentCard(wOutCardUser, cbCardData);
}
}
// 组合牌
void WN_CardManager::SubWeaveCard(CMD_S_OperateResult *pOperateResult)
{
if (m_pNoticelayer->isVisible())
{
CCLOG("WN_NotifyDlg HideNotifyDlg...WN_CardManager::SubWeaveCard()");
m_pNoticelayer->HideNotifyDlg();
}
if (pOperateResult == nullptr) return;
if ((pOperateResult->dwOperateCode&WIK_WN_GANG) != 0)
{
SetGangWeave(pOperateResult);
}
else if ((pOperateResult->dwOperateCode&WIK_WN_PENG) != 0)
{
SetPengWeave(pOperateResult);
}
else
{
CCLOG("no operate code %d", pOperateResult->dwOperateCode);
}
// 重置位置
ResetHandCard(pOperateResult->wOperateUser);
// 提供者出的最后一张牌就是操作牌
DelOutCard(pOperateResult->wProvideUser, pOperateResult->cbOperateCard);
}
void WN_CardManager::SetGangWeave(CMD_S_OperateResult *pOperateResult)
{
if (pOperateResult == nullptr) return;
if ((pOperateResult->dwOperateCode&WIK_WN_GANG) == 0) return;
WN_WeaveCard* pWeaveCard = nullptr;
bool IsBuGang = false;
uint8 cbWeaveCount = m_cbWeaveCount[pOperateResult->wOperateUser];
// 先看是否是补杠
for (uint8 i = 0; i < cbWeaveCount; i++)
{
if (m_pWeaveCard[pOperateResult->wOperateUser] != nullptr)
{
WN_WeaveCard* pTmpWeaveCard = m_pWeaveCard[pOperateResult->wOperateUser][i];
if ((pTmpWeaveCard != nullptr) && ((pTmpWeaveCard->m_dwOperateCode&WIK_WN_PENG) != 0) && (pTmpWeaveCard->m_cbCardData == pOperateResult->cbOperateCard))
{
pWeaveCard = pTmpWeaveCard;
IsBuGang = true;
break;
}
}
}
// 补杠
if (nullptr != pWeaveCard)
{
pWeaveCard->SetBuGang(pOperateResult->cbOperateCard);
// 补杠:一般情况删除第十四张牌即可,二般情况别人打出的牌可以杠,却选择了碰,碰完之后又选择补杠
SubOutCard(pOperateResult->cbOperateCard, pOperateResult->wOperateUser, false);
}
else
{
pWeaveCard = WN_WeaveCard::create();
if (pWeaveCard == nullptr) return;
// 设置杠组合;
pWeaveCard->ShowCardData(pOperateResult->wOperateUser, pOperateResult->cbOperateCard, pOperateResult->dwOperateCode, pOperateResult->wProvideUser);
// 位置计算
Point pos = GetWaveCardPoint(pOperateResult->wOperateUser);
pWeaveCard->setPosition(pos);
// 右手边玩家注意控制Z轴
if (pOperateResult->wOperateUser == 1)
{
this->addChild(pWeaveCard, SP_RSTAND + MAX_COUNT - cbWeaveCount);
}
else
{
this->addChild(pWeaveCard);
}
// 记录组合牌
m_pWeaveCard[pOperateResult->wOperateUser][cbWeaveCount] = pWeaveCard;
m_cbWeaveCount[pOperateResult->wOperateUser]++;
// 删除手牌(杠的时候只需要三张手牌,另一种是别人出牌,如果自己抓牌杠,需要三张手牌,第十四张牌会被新发的牌覆盖)
for (int i = 0; i < 3; i++)
{
SubOutCard(pOperateResult->cbOperateCard, pOperateResult->wOperateUser, false);
}
// 暗杠再删一张;
if (pOperateResult->wProvideUser == pOperateResult->wOperateUser)
{
SubOutCard(pOperateResult->cbOperateCard, pOperateResult->wOperateUser, false);
}
}
}
void WN_CardManager::SetPengWeave(CMD_S_OperateResult *pOperateResult)
{
if (pOperateResult == nullptr) return;
if ((pOperateResult->dwOperateCode&WIK_WN_PENG) == 0) return;
WN_WeaveCard* pWeaveCard = WN_WeaveCard::create();
//pWeaveCard->SetCardData(pOperateResult);
pWeaveCard->ShowCardData(pOperateResult->wOperateUser, pOperateResult->cbOperateCard, pOperateResult->dwOperateCode, pOperateResult->wProvideUser);
// 位置计算
Point pos = GetWaveCardPoint(pOperateResult->wOperateUser);
pWeaveCard->setPosition(pos);
uint8 cbWeaveCount = m_cbWeaveCount[pOperateResult->wOperateUser];
// 右手边玩家注意控制Z轴
if (pOperateResult->wOperateUser == 1)
{
this->addChild(pWeaveCard, SP_RSTAND + MAX_COUNT - cbWeaveCount);
}
else
{
this->addChild(pWeaveCard);
}
// 记录组合牌
m_pWeaveCard[pOperateResult->wOperateUser][cbWeaveCount] = pWeaveCard;
m_cbWeaveCount[pOperateResult->wOperateUser]++;
// 删除手牌(碰的时候只需要删除两张手牌,另一种是别人出牌)
//DelHandCard(pOperateResult->wOperateUser, pOperateResult->cbOperateCard, 2);
for (int i = 0; i < 2; i++)
{
SubOutCard(pOperateResult->cbOperateCard, pOperateResult->wOperateUser, false);
}
}
// 组合牌坐标
Point WN_CardManager::GetWaveCardPoint(WORD wChairID)
{
uint8 cbWeaveCount = m_cbWeaveCount[wChairID];
// 位置计算
Point pos;
pos.x = m_ptWeaveCard[wChairID].x;
pos.y = m_ptWeaveCard[wChairID].y;
// 自己合对家
if (0 == wChairID)
{
pos.x = pos.x - NCMJ_WEAVE_OPP*cbWeaveCount;
}
else if (1 == wChairID)
{
pos.y = pos.y + NCMJ_WEAVE_RIGHT*cbWeaveCount; // 位置偏移
}
else if (2 == wChairID)
{
pos.x = pos.x + NCMJ_WEAVE_SELF*cbWeaveCount;
}
else if (3 == wChairID)
{
pos.y = pos.y - NCMJ_WEAVE_LEFT*cbWeaveCount; // 位置偏移
}
return pos;
}
// 删除出牌
void WN_CardManager::DelOutCard(WORD wChairID, uint8 cbCardData)
{
// 提供者出的最后一张牌就是操作牌
if (m_pCurrentOutCard && m_pCurrentOutCard->GetCardData() == cbCardData)
{
m_pCurrentOutCard->removeFromParentAndCleanup(true);
m_pCurrentOutCard = nullptr;
m_cbOutCarCount[wChairID]--;
}
}
// 重置手牌坐标
void WN_CardManager::ResetHandCard(WORD wChairID)
{
std::list<WN_SparrowCard*>* __list = GetCardList(wChairID);
if (__list)
{
uint8 cbWeaveCout = m_cbWeaveCount[wChairID];
int _Cout = 0; // 非空牌个数
for (std::list<WN_SparrowCard*>::iterator it = __list->begin(); it != __list->end(); it++)
{
WN_SparrowCard* card = *it;
if (card)
{
Point pos = GetCardPoint(wChairID, _Cout);
card->setPosition(pos);
// 右边牌
if (wChairID == SP_RSTAND)
{
card->setLocalZOrder(SP_RSTAND + MAX_COUNT - _Cout - cbWeaveCout);
}
else if (wChairID == SP_LSTAND)
{
card->setLocalZOrder(cbWeaveCout + _Cout);
}
_Cout++;
}
}
}
}
// 显示当前打出的牌
void WN_CardManager::ShowCurrentCard(WORD wChairID, uint8 cbCardData)
{
if (wChairID < 0 || wChairID >= GAME_PLAYER) return;
if (!WN_CGameLogic::IsValidCard(cbCardData)) return;
log("DEBUG CARD wChairID = %d out card = 0x%0x", wChairID, cbCardData);
if (m_pCurrentOutCard != nullptr)
{
m_pCurrentOutCard->SetCurrentOutCard(false);
m_pCurrentOutCard = nullptr;
}
// 显示出牌
WN_SparrowCard* pOutCard = WN_SparrowCard::createWithDirection(cbCardData, (EN_SPARROW_TYPE)(SP_O_OUT + wChairID));
if (pOutCard == nullptr) return;
Point endpos = GetOutPoint(wChairID);
pOutCard->setPosition(endpos);
m_pOutCardSprite.push_back(pOutCard);
m_cbOutCarCount[wChairID]++;
if (wChairID == SELF_VIEW_CHAIRID)
{
auto localZ = NCMJ_MAX_DISCARD_COUNT * 4 - m_cbOutCarCount[SELF_VIEW_CHAIRID];
this->addChild(pOutCard, localZ);
}
else
{
this->addChild(pOutCard);
}
pOutCard->SetCurrentOutCard(true);
// 当前出牌
m_pCurrentOutCard = pOutCard;
}
// 显示单个玩家牌
void WN_CardManager::ShowAllHandCard(WORD wChairID, uint8 cbCardCount, const uint8 cbCardData[MAX_COUNT])
{
if (cbCardCount <= 0) return;
cocos2d::log("game end Chair = %d, Hand card number = %d", wChairID, cbCardCount);
// 暴力清空;
ClearCardList(wChairID);
if (m_pLastHandCard[wChairID] != nullptr)
{
m_pLastHandCard[wChairID]->removeFromParentAndCleanup(true);
m_pLastHandCard[wChairID] = nullptr;
}
// 重新创建;
std::list<WN_SparrowCard*>* __list = GetCardList(wChairID);
if (__list)
{
int __index = 0;
uint8 cbWeaveCout = m_cbWeaveCount[wChairID];
for (int i = 0; i < cbCardCount; i++)
{
// 不是有效值;
if (!WN_CGameLogic::IsValidCard(cbCardData[i]))
{
continue;
}
WN_SparrowCard* card = nullptr;
if (SELF_VIEW_CHAIRID == wChairID)
{
card = WN_SparrowCard::createWithDirection(cbCardData[i], (EN_SPARROW_TYPE)wChairID);
}
else
{
card = WN_SparrowCard::createWithDirection(0, (EN_SPARROW_TYPE)wChairID);
}
if (card)
{
card->ShowCardValue(cbCardData[i]);
card->setPosition(GetCardPoint(wChairID, __index));
// 右边牌
if (wChairID == SP_RSTAND)
{
this->addChild(card, SP_RSTAND + MAX_COUNT - __index - cbWeaveCout);
}
else
{
this->addChild(card);
}
__list->push_back(card);
__index++;
}
}
}
}
// 显示最后牌
void WN_CardManager::ShowLastCard(uint8 cbCardData, WORD wGetCardUser, uint8 cbDirection)
{
if (wGetCardUser == SELF_VIEW_CHAIRID)
{
SendCard(cbCardData, wGetCardUser);
}
else
{
SendCard(0x00, wGetCardUser);
}
if (m_pLastHandCard[wGetCardUser] != nullptr)
{
m_pLastHandCard[wGetCardUser]->ShowCardValue(cbCardData);
}
}
/****************************************** 场景恢复 **********************************************************************/
// 组合牌处理
void WN_CardManager::SceneWeaveCard(WORD wViewChairID, uint8 cbWeaveCount, tagWeaveItem WeaveItemArray[MAX_WEAVE], WORD wArrViewChairID[GAME_PLAYER])
{
ASSERT(cbWeaveCount <= MAX_WEAVE);
for (int i = 0; i < cbWeaveCount; i++)
{
DWORD dwOperateCode = WeaveItemArray[i].wWeaveKind;
uint8 cbTmpWeaveCount = m_cbWeaveCount[wViewChairID];
WN_WeaveCard* pWeaveCard = WN_WeaveCard::create();
if (nullptr == pWeaveCard) continue;
// 提供者视图装换;
WeaveItemArray[i].wProvideUser = wArrViewChairID[WeaveItemArray[i].wProvideUser];
pWeaveCard->ShowCardData(wViewChairID, WeaveItemArray[i].cbCenterCard, WeaveItemArray[i].wWeaveKind, WeaveItemArray[i].wProvideUser);
// 位置计算
Point pos = GetWaveCardPoint(wViewChairID);
pWeaveCard->setPosition(pos);
// 右手边玩家注意控制Z轴
if (1 == wViewChairID)
{
this->addChild(pWeaveCard, SP_RSTAND + MAX_COUNT - cbTmpWeaveCount);
}
else
{
this->addChild(pWeaveCard);
}
// 记录组合牌
m_pWeaveCard[wViewChairID][cbTmpWeaveCount] = pWeaveCard;
m_cbWeaveCount[wViewChairID]++;
}
}
// 玩家手牌
void WN_CardManager::SceneHandCard(WORD wViewChairID, uint8 cbCardCount, uint8 cbCardData[])
{
uint8 cbAllCount = m_cbWeaveCount[wViewChairID] * 3 + cbCardCount;
ASSERT((cbAllCount == MAX_COUNT) || (cbAllCount == MAX_COUNT - 1));
if ((cbAllCount != MAX_COUNT) && (cbAllCount != MAX_COUNT - 1))
{
return;
}
int _ind = m_cbWeaveCount[wViewChairID] * 3; // 每个组合都算3张牌
// 显示手牌
for (int j = 0; j < cbCardCount; j++)
{
// 自己牌处理
if (wViewChairID == 2)
{
uint8 CardValue = cbCardData[j];
WN_SparrowCard* card = WN_SparrowCard::createWithDirection(CardValue, SP_SELFSTAND);
card->addClickEventListener(CC_CALLBACK_2(WN_CardManager::onSendCardEvent, this));
card->setPosition(GetCardPoint(wViewChairID, j));
this->addChild(card);
m_SelfHandCardList.push_back(card);
}
// 对家牌
else if (wViewChairID == 0)
{
WN_SparrowCard* card = WN_SparrowCard::createWithDirection(0xff, SP_OPPSTAND);
card->setPosition(GetCardPoint(wViewChairID, j));
this->addChild(card);
m_OppHandCardList.push_back(card);
}
// 左边牌
else if (wViewChairID == 3)
{
WN_SparrowCard* card = WN_SparrowCard::createWithDirection(0xff, SP_LSTAND);
card->setPosition(GetCardPoint(wViewChairID, j));
this->addChild(card, j + _ind + SP_LSTAND);
m_LeftHandCardList.push_back(card);
}
// 右边牌
else
{
WN_SparrowCard* card = WN_SparrowCard::createWithDirection(0xff, SP_RSTAND);
card->setPosition(GetCardPoint(wViewChairID, j));
this->addChild(card, SP_RSTAND + MAX_COUNT - j - _ind);
m_RightHandCardList.push_back(card);
}
}
}
// 玩家出牌
void WN_CardManager::SceneOutCard(WORD wViewChairID, uint8 cbCardCount, uint8 cbOutCardData[])
{
if (wViewChairID == INVALID_CHAIR) return;
// 显示出牌
for (int i = 0; i < cbCardCount; i++)
{
if (!WN_CGameLogic::getInstance()->IsValidCard(cbOutCardData[i])) continue;
// 显示出牌
WN_SparrowCard* pOutCard = WN_SparrowCard::createWithDirection(cbOutCardData[i], (EN_SPARROW_TYPE)((int)SP_O_OUT + wViewChairID));
if (pOutCard == nullptr) continue;
Point pos = GetOutPoint(wViewChairID);
pOutCard->setPosition(pos);
if (wViewChairID == SELF_VIEW_CHAIRID)
{
auto localZ = NCMJ_MAX_DISCARD_COUNT * 2 - m_cbOutCarCount[SELF_VIEW_CHAIRID];
this->addChild(pOutCard, localZ);
}
else
{
this->addChild(pOutCard);
}
//m_pOutCardSprite[wViewChairID][m_cbOutCarCount[wViewChairID]++] = pOutCard;
m_pOutCardSprite.push_back(pOutCard);
m_cbOutCarCount[wViewChairID]++;
}
}
// 出牌坐标
Point WN_CardManager::GetOutPoint(WORD wViewChairID)
{
uint8 cbOutCardCount = m_cbOutCarCount[wViewChairID];
// 根据真实玩家数量,调整出牌排列;
WORD wSelfDisCardCount = NCMJ_MAX_DISCARD_COUNT;
WORD wOppDisCardCount = NCMJ_MAX_DISCARD_COUNT + 1;
WORD wLRDisCardCount = NCMJ_LR_DISCARD_COUNT;
int nROutCardY = m_ptOutCard[3].y;
int nLOutCardY = m_ptOutCard[1].y;
int nSOutCardX = m_ptOutCard[2].x;
//// 2人;
//if (m_wRealChairCount == 2)
//{
// wSelfDisCardCount = NCMJ_MAX_DISCARD_COUNT + 3;
//}
//else if (m_wRealChairCount == 3) // 3人;
//{
// wSelfDisCardCount = NCMJ_MAX_DISCARD_COUNT + 3;
// wLRDisCardCount = NCMJ_LR_DISCARD_COUNT + 4;
// // 偏移四张牌;
// nLOutCardY += NCMJ_LROUT_CARD_HIGHT * 4;
// nROutCardY += NCMJ_LROUT_CARD_HIGHT * 4;
//}
// 两人情况;
if (m_wRealChairCount == 2)
{
// 对家没人左右可加牌;
if (!m_bActiveStatus[0])
{
wLRDisCardCount = NCMJ_LR_DISCARD_COUNT + 4;
// 偏移四张牌;
nLOutCardY += NCMJ_LROUT_CARD_HIGHT * 6 + NCMJ_LROUT_CARD_HIGHT / 2;
nROutCardY += NCMJ_LROUT_CARD_HIGHT * 6 + NCMJ_LROUT_CARD_HIGHT / 2;
}
wSelfDisCardCount = NCMJ_MAX_DISCARD_COUNT + 5;
// 左侧无人调整起始位置;
if (!m_bActiveStatus[3])
{
nSOutCardX -= NCMJ_OUT_CARD_WIDHT * 2;
}
}
else if (m_wRealChairCount == 3) // 3;
{
wSelfDisCardCount = NCMJ_MAX_DISCARD_COUNT + 3;
// 对家没人左右可加牌;
if (!m_bActiveStatus[0])
{
wLRDisCardCount = NCMJ_LR_DISCARD_COUNT + 4;
// 偏移四张牌;
nLOutCardY += NCMJ_LROUT_CARD_HIGHT * 6;
nROutCardY += NCMJ_LROUT_CARD_HIGHT * 6;
}
}
// 控制添加后的层次关系和坐标
int x = 0;
int y = 0;
switch (wViewChairID)
{
case 0:
// 出牌数量不过半, 第一排
x = m_ptOutCard[0].x - NCMJ_OUT_CARD_WIDHT * (cbOutCardCount % wOppDisCardCount)*OUT_CARD_SCALE;
y = m_ptOutCard[0].y - NCMJ_OUT_CARD_HIGHT * (cbOutCardCount / wOppDisCardCount)*OUT_CARD_SCALE;
break;
case 3:
x = m_ptOutCard[3].x + NCMJ_LROUT_CARD_WIDHT*(cbOutCardCount / wLRDisCardCount)*OUT_CARD_SCALE;
y = nROutCardY - NCMJ_LROUT_CARD_HIGHT * (cbOutCardCount % wLRDisCardCount)*OUT_CARD_SCALE;
break;
case 2:
x = nSOutCardX + NCMJ_OUT_CARD_WIDHT * (cbOutCardCount % wSelfDisCardCount)*OUT_CARD_SCALE;
y = m_ptOutCard[2].y + NCMJ_OUT_CARD_HIGHT * (cbOutCardCount / wSelfDisCardCount)*OUT_CARD_SCALE;
break;
case 1:
x = m_ptOutCard[1].x - NCMJ_LROUT_CARD_WIDHT*(cbOutCardCount / wLRDisCardCount)*OUT_CARD_SCALE;
y = nLOutCardY - NCMJ_LROUT_CARD_HIGHT * (cbOutCardCount % wLRDisCardCount)*OUT_CARD_SCALE;
break;
default:
ASSERT(false);
break;
}
return Point(x, y);
}
std::list<WN_SparrowCard*> * WN_CardManager::GetCardList(WORD wChairID)
{
switch (wChairID)
{
case 0:
return &m_OppHandCardList;
case 1:
return &m_RightHandCardList;
case 2:
return &m_SelfHandCardList;
case 3:
return &m_LeftHandCardList;
default:
break;
}
return nullptr;
}
void WN_CardManager::ClearCardList(WORD wChairID)
{
std::list<WN_SparrowCard*>* __list = GetCardList(wChairID);
if (__list == nullptr) return;
for (std::list<WN_SparrowCard*>::iterator it = __list->begin(); it != __list->end(); it++)
{
WN_SparrowCard* card = *it;
if (card)
{
card->removeFromParentAndCleanup(true);
card = nullptr;
}
}
__list->clear();
}