//**************************************************************************** //Copyright (C) 2005-2006 Beijing BlueDJ Technology Co.,Ltd. All rights reserved. //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License //as published by the Free Software Foundation; either version 2 //of the License, or (at your option) any later version. //This program is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. //You should have received a copy of the GNU General Public License //along with this program (in the file LICENSE.GPL); if not, write to the Free Software //Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //Please visit http://www.bluedj.com for more infomation about us. //Contact us at ggwizard@gmail.com or darkdong@gmail.com. //****************************************************************************/ #include #include "DJGameController.h" #include "DJClientRequest.h" #include "DJGameUser.h" #include "DJGameRoom.h" #include "DJTreeWidget.h" #include "jdebug.h" #include "panelbase.h" #include "DJTopWidget.h" #include "Utility.h" #include "DJTreeItemDelegate.h" #include "xqpanel.h" #include "xqrule.h" #include "xqprofile.h" #include "DJGamePlayerItem.h" void HandleMoveACL( const QByteArray& buf, const QList& parameters ); ////////////////////////////////////////////////////////////////////// XiangqiRuleItem::XiangqiRuleItem(Q3Canvas * canvas, QWidget* parent,XiangqiRule *prule): QObject(parent) { c_Canvas = canvas; c_Desktop= (XiangqiDesktop *)parent; if(prule != NULL) { memcpy(&rule,prule,sizeof(XiangqiRule)); rule.shBaseTime = ltoh2(prule->shBaseTime); }else { memset(&rule,0,sizeof(XiangqiRule)); } c_basictext = NULL; c_basictime = NULL; c_dumiaotext = NULL; c_dumiaotime = NULL; c_timestext = NULL; c_times = NULL; CreateItems(); c_timer = new QTimer(parent); connect(c_timer,SIGNAL(timeout()),this,SLOT(HandleTimeout())); } void XiangqiRuleItem::setRule(XiangqiRule *prule) { if(prule != NULL) { memcpy(&rule,prule,sizeof(XiangqiRule)); rule.shBaseTime = ltoh2(prule->shBaseTime); }else { memset(&rule,0,sizeof(XiangqiRule)); } char buffer[100]; sprintf(buffer,"%d:%d:%d",rule.shBaseTime/3600, (rule.shBaseTime%3600)/60,(rule.shBaseTime%3600)%60); c_basictime->setText(QString(buffer)); sprintf(buffer,"%d:%d",rule.chTimeAfterBaseTime/60, rule.chTimeAfterBaseTime%60); c_dumiaotime->setText(QString(buffer)); sprintf(buffer,"%d-%d:%d",rule.chTimes, rule.chTimeAfterTimeout/60,rule.chTimeAfterTimeout%60); c_times->setText(QString(buffer)); } void XiangqiRuleItem::CreateItems() { char buffer[100]; if(c_basictext != NULL) delete c_basictext; if(c_basictime != NULL) delete c_basictime; if(c_dumiaotext != NULL) delete c_dumiaotext; if(c_dumiaotime != NULL) delete c_dumiaotime; if(c_timestext != NULL) delete c_timestext; if(c_times != NULL) delete c_times; QFont f; c_basictext = new Q3CanvasText(tr("Basic"),c_Canvas); c_basictext->setColor(QColor(0,0,0xFF)); f = c_basictext->font(); f.setPointSize(10); f.setBold(false); c_basictext->setFont(f); sprintf(buffer,"%d:%d:%d",rule.shBaseTime/3600, (rule.shBaseTime%3600)/60,(rule.shBaseTime%3600)%60); c_basictime = new Q3CanvasText(QString(buffer),c_Canvas); c_basictime->setColor(QColor(0xFF,0,0)); c_basictime->setFont(f); c_dumiaotext = new Q3CanvasText(tr("Fast"),c_Canvas); c_dumiaotext->setColor(QColor(0,0,0xFF)); c_dumiaotext->setFont(f); sprintf(buffer,"%d:%d",rule.chTimeAfterBaseTime/60, rule.chTimeAfterBaseTime%60); c_dumiaotime = new Q3CanvasText(QString(buffer),c_Canvas); c_dumiaotime->setColor(QColor(0xFF,0,0)); c_dumiaotime->setFont(f); c_timestext = new Q3CanvasText(tr("Reserve"),c_Canvas); c_timestext->setColor(QColor(0,0,0xFF)); c_timestext->setFont(f); sprintf(buffer,"%d-%d:%d",rule.chTimes, rule.chTimeAfterTimeout/60,rule.chTimeAfterTimeout%60); c_times = new Q3CanvasText(QString(buffer),c_Canvas); c_times->setColor(QColor(0xFF,0,0)); c_times->setFont(f); } void XiangqiRuleItem::move(int x,int y) { c_X = x; c_Y = y; QRect rect; int w = c_Desktop->width()-x; rect = c_basictext->boundingRect(); c_basictext->move(x+((w-rect.width())>>1),y); y += 15; rect = c_basictime->boundingRect(); c_basictime->move(x+((w-rect.width())>>1),y); y += 15; rect = c_dumiaotext->boundingRect(); c_dumiaotext->move(x+((w-rect.width())>>1),y); y += 15; rect = c_dumiaotime->boundingRect(); c_dumiaotime->move(x+((w-rect.width())>>1),y); y += 15; rect = c_timestext->boundingRect(); c_timestext->move(x+((w-rect.width())>>1),y); y += 15; rect = c_times->boundingRect(); c_times->move(x+((w-rect.width())>>1),y); } void XiangqiRuleItem::show() { c_basictext->show(); c_basictime->show(); c_dumiaotext->show(); c_dumiaotime->show(); c_timestext->show(); c_times->show(); } void XiangqiRuleItem::hide() { c_basictext->hide(); c_basictime->hide(); c_dumiaotext->hide(); c_dumiaotime->hide(); c_timestext->hide(); c_times->hide(); } void XiangqiRuleItem::startTimer() { c_iStart = time(NULL); c_iElps = 0; c_timer->start(1000,false); } void XiangqiRuleItem::stopTimer() { c_timer->stop(); } void XiangqiRuleItem::HandleTimeout() { char buffer[100]; int ispace = time(NULL)-c_iStart; if(ispace > c_iElps) ispace = ispace-c_iElps; else return; c_iElps += ispace; if(rule.shBaseTime > ispace) { rule.shBaseTime -= ispace; }else { if(rule.shBaseTime != 0) { ispace -= rule.shBaseTime; rule.shBaseTime = 0; } if(rule.chTimeAfterBaseTime > ispace) { rule.chTimeAfterBaseTime -= ispace; if ( rule.chTimeAfterBaseTime <= 10 ) c_Desktop->c_Panel->playWave( QString("number%1.wav").arg(rule.chTimeAfterBaseTime) ); }else if(rule.chTimes > 0) { ispace -= rule.chTimeAfterBaseTime; rule.chTimeAfterBaseTime = 0; rule.chTimes --; rule.chTimeAfterBaseTime += (rule.chTimeAfterTimeout-ispace); } } sprintf(buffer,"%d:%d:%d",rule.shBaseTime/3600, (rule.shBaseTime%3600)/60,(rule.shBaseTime%3600)%60); c_basictime->setText(QString(buffer)); sprintf(buffer,"%d:%d",rule.chTimeAfterBaseTime/60, rule.chTimeAfterBaseTime%60); c_dumiaotime->setText(QString(buffer)); sprintf(buffer,"%d-%d:%d",rule.chTimes, rule.chTimeAfterTimeout/60,rule.chTimeAfterTimeout%60); c_times->setText(QString(buffer)); c_timer->start(1000,false); } XiangqiRuleItem::~XiangqiRuleItem() { } //////////////////////////////////////////////////////////////////////// #define XIANGQI_BOARD_MAX_HEIGHT 750 #define XIANGQI_BOARD_MAX_WIDTH 675 #define XIANGQI_CHIP_MAX_SIZE 75 #define DESKTOP_IMAGE_TYPE_AVATOR 0x101 #define DESKTOP_IMAGE_TYPE_BOARD 0x102 #define DESKTOP_IMAGE_TYPE_CHIP 0x110 #define DESKTOP_IMAGE_TYPE_RED 0x110 #define DESKTOP_IMAGE_TYPE_BLACK 0x111 #define DESKTOP_IMAGE_TYPE_FOCUS 0x120 #define DESKTOP_IMAGE_ISCHIP(__type) ((__type)== DESKTOP_IMAGE_TYPE_RED || (__type)==DESKTOP_IMAGE_TYPE_BLACK) XiangqiDesktop::XiangqiDesktop(Q3Canvas * canvas, QWidget* parent,XiangqiPanel *panel): Q3CanvasView(canvas,parent) { c_Canvas = canvas; c_Panel = panel; c_pbStart = new QPushButton(tr("Start"),this); connect(c_pbStart,SIGNAL(released()),this,SLOT(ClickStart())); c_pbStart->hide(); c_pbSur = new QPushButton(tr("Surrender"),this); connect(c_pbSur,SIGNAL(released()),this,SLOT(ClickSurrender())); c_pbSur->hide(); c_pbDues = new QPushButton(tr("Request Dues"),this); connect(c_pbDues,SIGNAL(released()),this,SLOT(ClickDues())); c_pbDues->hide(); c_Canvas->setDoubleBuffering(TRUE); c_Canvas->setAdvancePeriod(300); setVScrollBarMode(AlwaysOff); setHScrollBarMode(AlwaysOff); c_paTimer = InitTimerMovie(); itemTimer = new Q3CanvasSprite( c_paTimer,c_Canvas); itemTimer->hide(); itemTimer->setFrameAnimation ( ); itemTimer->setAnimated(TRUE); itemTimer->setZ(2000); c_MoveTimer = new QTimer(this); connect(c_MoveTimer,SIGNAL(timeout()),this,SLOT(HandleMoveTimeout())); c_shSkin = 1; memset(&c_Board,0,sizeof(XiangQiBoard)); c_itemBoard = NULL; c_selfRule = new XiangqiRuleItem(c_Canvas,this,NULL); c_comRule = new XiangqiRuleItem(c_Canvas,this,NULL); memset(c_itemAvatar,0,sizeof(CChessImageItem*)*5); memset(c_itemName,0,sizeof(Q3CanvasText*)*5); c_bRequestDuce[1] = false; c_bRequestDuce[2] = false; c_bRequestDuce[0] = false; c_itemFocus = NULL; c_itemStartPos = NULL; c_Canvas->setBackgroundColor(QColor(75,130,170)); QPalette pal = palette(); pal.setBrush(QPalette::Background,QColor(75,130,170)); setPalette(pal); } void XiangqiDesktop::GameWait() { int x = width()-102,y; if(c_Panel->WaittingForMe()) { y = height()-64; }else { y = 32; } itemTimer->move(x,y); itemTimer->show(); } void XiangqiDesktop::SetRule(unsigned char chSite,XiangqiRule *prule) { if(chSite == c_Panel->selfSeatId()) c_selfRule->setRule(prule); else c_comRule->setRule(prule); } void XiangqiDesktop::RequestDuels(unsigned char chSite) { c_bRequestDuce[chSite] = true; RepaintAvatar(); } void XiangqiDesktop::AdjustBoard(const GeneralGameTrace2Head *gameTrace) { memcpy(&c_Board,gameTrace->chBuf,sizeof(XiangQiBoard)); ClearAllChips(); int i,j; for(i=1;i<=9;i++) { for(j=1;j<=10;j++) { DrawChip(i,j); } } } void XiangqiDesktop::RepaintAvatar() { int i,x,y; quint32 uid; DJGameUser *puser; QFont f; QPixmap pix; QImage img; for(i=1;i<=2;i++) { if(c_itemAvatar[i] != NULL) delete c_itemAvatar[i]; if(c_itemName[i] != NULL) delete c_itemName[i]; c_itemAvatar[i] = NULL; c_itemName[i] = NULL; GetAvatarPosition(i,&x,&y); if(i == c_Panel->selfSeatId()) { c_selfRule->move(x,y-95); c_selfRule->show(); }else { c_comRule->move(x,y+70); c_comRule->show(); } uid = c_Panel->userIdOfSeat(i); puser = c_Panel->gameUser(uid,false); if(puser != NULL) { c_itemName[i] = new Q3CanvasText(puser->userName(),c_Canvas); c_itemName[i]->setColor(QColor(0,0,0)); f = c_itemName[i]->font(); f.setPointSize(14); f.setBold(true); c_itemName[i]->setFont(f); x = 0;y=0; GetUserNamePosition(i,c_itemName[i],&x,&y); c_itemName[i]->move(x,y); c_itemName[i]->show(); if(c_bRequestDuce[i]) pix = QPixmap(QString(":/ChineseChessRes/image/pigeon.png")); else pix = puser->avatar(); img = pix.convertToImage(); img = img.smoothScale(64,64); GetAvatarPosition(i,&x,&y); c_itemAvatar[i] = new CChessImageItem(img,c_Canvas,0,i,DESKTOP_IMAGE_TYPE_AVATOR); c_itemAvatar[i]->move(x,y); c_itemAvatar[i]->show(); } } } void XiangqiDesktop::RepaintBoard() { int w,h,w1,h1; if(c_itemBoard != NULL) delete c_itemBoard; ClearAllChips(); w = width(); h = height(); w1 = w-64; h1 = (w1*10)/9; if(h1 > h-60) { h1 = h-60; w1 = (h1*9)/10; } if(h1 > XIANGQI_BOARD_MAX_HEIGHT) { h1 = XIANGQI_BOARD_MAX_HEIGHT; w1 = XIANGQI_BOARD_MAX_WIDTH; } c_Fx = (w1*100)/XIANGQI_BOARD_MAX_WIDTH; w1 = XIANGQI_BOARD_MAX_WIDTH*c_Fx/100; h1 = XIANGQI_BOARD_MAX_HEIGHT*c_Fx/100; c_X = (w-64-w1)>>1; c_Y = (h-h1)>>1; QPixmap pix = QPixmap(QString(":/ChineseChessRes/image/cchessb%1.png").arg(c_shSkin)); if(pix.isNull()) { DEBUG_OUTPUT(("no board%d\n",c_shSkin)); return; } QImage img = pix.convertToImage(); img = img.smoothScale(w1,h1); c_itemBoard = new CChessImageItem(img,c_Canvas,0,0,DESKTOP_IMAGE_TYPE_BOARD); c_itemBoard->move(c_X,c_Y); c_itemBoard->setZ(100); c_itemBoard->show(); int i,j; for(i=1;i<=9;i++) { for(j=1;j<=10;j++) { DrawChip(i,j); } } if(c_itemFocus != NULL) delete c_itemFocus; pix = QPixmap(QString(":/ChineseChessRes/image/focus.png")); img = pix.convertToImage(); img = img.smoothScale(XIANGQI_CHIP_MAX_SIZE*c_Fx/100,XIANGQI_CHIP_MAX_SIZE*c_Fx/100); c_itemFocus = new CChessImageItem(img,c_Canvas,0,0,DESKTOP_IMAGE_TYPE_FOCUS); c_itemFocus->setZ(3000); c_itemFocus->hide(); if(c_itemStartPos != NULL) delete c_itemStartPos; pix = QPixmap(QString(":/ChineseChessRes/image/start.png")); img = pix.convertToImage(); img = img.smoothScale(XIANGQI_CHIP_MAX_SIZE*c_Fx/100,XIANGQI_CHIP_MAX_SIZE*c_Fx/100); c_itemStartPos = new CChessImageItem(img,c_Canvas,0,0,DESKTOP_IMAGE_TYPE_FOCUS); c_itemStartPos->setZ(3000); c_itemStartPos->hide(); } void XiangqiDesktop::DrawChip(unsigned char x,unsigned char y) { int s,nx,ny; unsigned char chChip; char pixname[255]; chChip = XiangQi_GetNode(&c_Board,x,y); if(chChip != 0) { QPixmap pix; QImage img; s = XIANGQI_CHIP_MAX_SIZE*c_Fx/100; GetNodeXY(x,y,&nx,&ny); nx -= (s>>1); ny -= (s>>1); sprintf(pixname,":/ChineseChessRes/image/chips%d/%02x.png",c_shSkin,chChip); pix = QPixmap(QString(pixname)); img = pix.convertToImage(); img = img.smoothScale(s,s); CChessImageItem *item = new CChessImageItem(img,c_Canvas,x,y,DESKTOP_IMAGE_TYPE_CHIP+(chChip>>3)); item->move(nx,ny); item->setZ(200); item->show(); } } void XiangqiDesktop::ClearChip(unsigned char x,unsigned char y) { CChessImageItem * item=GetChipOfNode(x,y); if(item != NULL) delete item; } void XiangqiDesktop::ClearAllChips() { Q3CanvasItemList list = c_Canvas->allItems(); Q3CanvasItemList::Iterator it = list.begin(); CChessImageItem *item; while(it != list.end()) { if((*it)->rtti() == imageRTTI ) { item = (CChessImageItem *)(*it); if ( DESKTOP_IMAGE_ISCHIP(item->c_chType) ) delete item; } it++; } } CChessImageItem * XiangqiDesktop::GetChipOfNode(unsigned char x,unsigned char y) { int nx,ny; CChessImageItem *item; GetNodeXY(x,y,&nx,&ny); QPoint p(nx,ny); Q3CanvasItemList l=canvas()->collisions(p); Q3CanvasItemList::Iterator it=l.begin(); while(it != l.end()) { if((*it)->rtti() == imageRTTI ) { item = (CChessImageItem *)(*it); if(DESKTOP_IMAGE_ISCHIP(item->c_chType)) { return item; } } it ++; } return NULL; } void XiangqiDesktop::GetNodeXY(unsigned char x,unsigned char y,int *px,int *py) { int nx,ny; nx = XIANGQI_CHIP_MAX_SIZE*(x-1)+(XIANGQI_CHIP_MAX_SIZE>>1); ny = XIANGQI_CHIP_MAX_SIZE*(10-y)+(XIANGQI_CHIP_MAX_SIZE>>1); if(c_Panel->selfSeatId() != c_Panel->c_Current.chRed) { nx = XIANGQI_BOARD_MAX_WIDTH-nx; ny = XIANGQI_BOARD_MAX_HEIGHT-ny; } nx = nx * c_Fx/100; ny = ny * c_Fx/100; if(nx < 0 || nx > XIANGQI_BOARD_MAX_WIDTH || ny < 0 || ny >XIANGQI_BOARD_MAX_HEIGHT) { *px = 0; *py = 0; }else { *px = nx+c_X; *py = ny+c_Y; } } void XiangqiDesktop::resizeEvent( QResizeEvent * ) { c_Canvas->resize(width(),height()); //c_pbStart->setGeometry( (width()-64)>>1,(height()>>1)+35,80,30); //c_pbDues->setGeometry((width()-70),(height()>>1)-30,65,25); //c_pbSur->setGeometry((width()-70),(height()>>1)+5,65,25); c_pbStart->move( (width()-c_pbStart->width())>>1,(height()>>1)+35); c_pbDues->move((width()-c_pbDues->width()),(height()>>1)-30); c_pbSur->move((width()-c_pbSur->width()),(height()>>1)+5); RepaintAvatar(); RepaintBoard(); } void XiangqiDesktop::contentsMouseReleaseEvent(QMouseEvent* e) { CChessImageItem *item; if(c_Panel->isLookingOn() || !c_Panel->IsWaitMove() || !c_bMove || c_bWaitACL) return; QPoint pp = inverseWorldMatrix().map(e->pos()); // if (e->button() == Qt::LeftButton) { unsigned char x,y; if(pp.x()hide(); if(c_itemStartPos != NULL) c_itemStartPos->hide(); return ; } x = (pp.x()-c_X)/(XIANGQI_CHIP_MAX_SIZE*c_Fx/100)+1; y = ((pp.y()-c_Y)/(XIANGQI_CHIP_MAX_SIZE*c_Fx/100)+1); if(x > 9 || y > 10) { if(c_itemFocus != NULL) c_itemFocus->hide(); if(c_itemStartPos != NULL) c_itemStartPos->hide(); return ; } y = 11-y; if(c_Panel->selfSeatId() != c_Panel->c_Current.chRed) { x = 10-x; y = 11-y; } DEBUG_OUTPUT(("x=%d,y=%d ",x,y)); unsigned char chChip = XiangQi_GetNode(&c_Board,x,y); DEBUG_OUTPUT(("%02x\n",chChip)); if(chChip != 0 && ( (XIANGQI_GETOWNER(chChip) == DJGAME_XIANGQI_RED && c_Panel->selfSeatId() == c_Panel->c_Current.chRed) || (XIANGQI_GETOWNER(chChip) == DJGAME_XIANGQI_BLACK && c_Panel->selfSeatId() == c_Panel->c_Current.chBlack)) ) {//自己的棋子 c_chStartPoint = 0; item = GetChipOfNode(x,y); if(item != NULL) { c_chStartPoint = XIANGQI_RULE_GETNODEID(x,y); c_Panel->playWave("click.wav"); if(c_itemFocus != NULL) { int nx,ny; GetNodeXY(x,y,&nx,&ny); c_itemFocus->move(nx-(c_itemFocus->width()>>1), ny-(c_itemFocus->height()>>1) ); c_itemFocus->show(); } } }else if(c_chStartPoint != 0) {//目标点 unsigned char chEndID = XIANGQI_RULE_GETNODEID(x,y); unsigned char owner; if(c_Panel->selfSeatId() == c_Panel->c_Current.chRed) owner = DJGAME_XIANGQI_RED; else if(c_Panel->selfSeatId() == c_Panel->c_Current.chBlack) owner = DJGAME_XIANGQI_BLACK; else return; if(XIANGQI_SUCCESS(XiangQi_Move(&c_Board,owner,c_chStartPoint,chEndID))) {//发送 DEBUG_OUTPUT(("move success\n")); unsigned char buffer[30]; GeneralGameTrace2Head *pmovet; PXiangQiMove pmove; pmovet = (GeneralGameTrace2Head *)buffer; pmovet->chTable = c_Panel->selfTableId(); pmovet->chSite = c_Panel->selfSeatId(); pmovet->chType = XIANGQI_GAMETRACE_MOVE; pmovet->chBufLen = sizeof(XiangQiMove); pmove = (PXiangQiMove )pmovet->chBuf; pmove->chStart = c_chStartPoint; pmove->chEnd = chEndID; c_bWaitACL = true; QByteArray buf = c_Panel->makeGameData( DJGAME_PROTOCOL_SUBTYPE_GAMETRACE2,QByteArray((char *)buffer,sizeof(GeneralGameTrace2Head)+pmovet->chBufLen) ); QList parameters; parameters << this; DJClientRequest request( buf ,HandleMoveACL,parameters); item = GetChipOfNode(XIANGQI_RULE_GETX(c_chStartPoint),XIANGQI_RULE_GETY(c_chStartPoint)); if(c_itemFocus != NULL) c_itemFocus->hide(); if(c_itemStartPos != NULL) c_itemStartPos->hide(); c_Panel->sendRequest( request ,false); //c_bWaitACL = true; }else { DEBUG_OUTPUT(("invalid move\n")); } } } } void HandleMoveACL( const QByteArray& buf, const QList& parameters ) { PDJGameProtocol pacl = (PDJGameProtocol)buf.data(); XiangqiDesktop *desktop = (XiangqiDesktop *)parameters.at(0); desktop->c_bWaitACL = false; if(buf.size() == 0) { return ; } if( DJGAME_SUCCESS(pacl->chBuf[0]) ) { desktop->c_bMove = false; } } void XiangqiDesktop::PlayerMove(unsigned char chSite,unsigned char chStart,unsigned char chEnd) { unsigned char chStartChip = XiangQi_GetNode(&c_Board,XIANGQI_RULE_GETX(chStart),XIANGQI_RULE_GETY(chStart)); unsigned char chEndChip = XiangQi_GetNode(&c_Board,XIANGQI_RULE_GETX(chEnd),XIANGQI_RULE_GETY(chEnd)); ClearChip(XIANGQI_RULE_GETX(chStart),XIANGQI_RULE_GETY(chStart)); ClearChip(XIANGQI_RULE_GETX(chEnd),XIANGQI_RULE_GETY(chEnd)); XiangQi_SetNodeByID(&c_Board,chStart,0,0); XiangQi_SetNodeByID(&c_Board,chEnd,chStartChip&0x07,chStartChip&0x08); DrawChip(XIANGQI_RULE_GETX(chEnd),XIANGQI_RULE_GETY(chEnd)); if(c_itemFocus != NULL) { int nx,ny; GetNodeXY(XIANGQI_RULE_GETX(chEnd),XIANGQI_RULE_GETY(chEnd),&nx,&ny); c_itemFocus->move(nx-(c_itemFocus->width()>>1), ny-(c_itemFocus->height()>>1) ); c_itemFocus->show(); GetNodeXY(XIANGQI_RULE_GETX(chStart),XIANGQI_RULE_GETY(chStart),&nx,&ny); c_itemStartPos->move(nx-(c_itemStartPos->width()>>1), ny-(c_itemStartPos->height()>>1) ); c_itemStartPos->show(); } if(IsJiangJun(chEnd) ) c_Panel->playWave("jiang.wav"); else if(chEndChip != 0) c_Panel->playWave("kill.wav"); else c_Panel->playWave("move.wav"); } bool XiangqiDesktop::IsJiangJun(unsigned char chEnd) { unsigned char chChip = XiangQi_GetNodeByID(&c_Board,chEnd); unsigned char owner = (XIANGQI_GETOWNER(chChip)==DJGAME_XIANGQI_RED)?DJGAME_XIANGQI_BLACK:DJGAME_XIANGQI_RED; bool bFind=false; unsigned char i=8,x,y,j,chJiangPos; if(owner == DJGAME_XIANGQI_RED) { i = 1; } //先找到老将的位置 for(x=4;x<=6;x++) { for(y=i;y<=i+2;y++) { chChip = XiangQi_GetNode(&c_Board,x,y); if(chChip == (XIANGQI_CHIP_JIANG | owner) ) { bFind = true; break; } } if(bFind) break; } if(bFind) { //printf("jiang pos %d,%d\n",x,y); chJiangPos = XIANGQI_RULE_GETNODEID(x,y); chChip = XiangQi_GetNodeByID(&c_Board,chEnd); if(XIANGQI_SUCCESS(XiangQi_Move(&c_Board,XIANGQI_GETOWNER(chChip),chEnd,chJiangPos))) { //printf("jiang!\n"); return true; } } return false; } void XiangqiDesktop::contentsDragMoveEvent ( QDragMoveEvent * e ) { } void XiangqiDesktop::WaitMove() { c_pbSur->show(); c_pbDues->show(); if(c_Panel->WaittingForMe()) { c_selfRule->startTimer(); c_comRule->stopTimer(); c_bMove = true; c_bWaitACL = false; c_chStartPoint = 0; }else { c_comRule->startTimer(); c_selfRule->stopTimer(); } } void XiangqiDesktop::WaitStart() { c_pbSur->hide(); c_pbDues->hide(); if(c_Panel->WaittingForMe()) { c_pbStart->show(); c_bRequestDuce[1] = false; c_bRequestDuce[2] = false; c_bRequestDuce[0] = false; RepaintAvatar(); }else c_pbStart->hide(); } void XiangqiDesktop::ClickStart() { c_pbStart->hide(); //c_wHelp->setText( tr("waiting for other player")); QByteArray buf = c_Panel->makeGameData( DJGAME_PROTOCOL_SUBTYPE_START, QByteArray() ); DJClientRequest request( buf ); c_Panel->sendRequest( request,false ); if(c_strSaveFile.isEmpty()) c_strSaveFile = GetTempSaveFileName(DJGAME_XIANGQI); InitSaveFileHead(c_Panel,c_strSaveFile,DJGAME_XIANGQI,XIANGQI_GAMETRACE_MOVE); } bool XiangqiDesktop::hasStarted() { return !c_pbStart->isVisible(); } void XiangqiDesktop::ClickSurrender() { GeneralGameTrace2Head sur; sur.chTable = c_Panel->selfTableId(); sur.chType = XIANGQI_GAMETRACE_SURRENDER; sur.chSite = c_Panel->selfSeatId(); sur.chBufLen = 0; QByteArray buf = c_Panel->makeGameData( DJGAME_PROTOCOL_SUBTYPE_GAMETRACE2,QByteArray((char *)&sur,sizeof(GeneralGameTrace2Head)) ); DJClientRequest request( buf); c_Panel->sendRequest( request ,false); } void XiangqiDesktop::ClickDues() { GeneralGameTrace2Head sur; sur.chTable = c_Panel->selfTableId(); sur.chType = XIANGQI_GAMETRACE_REQUESTDUELS; sur.chSite = c_Panel->selfSeatId(); sur.chBufLen = 0; QByteArray buf = c_Panel->makeGameData( DJGAME_PROTOCOL_SUBTYPE_GAMETRACE2,QByteArray((char *)&sur,sizeof(GeneralGameTrace2Head)) ); DJClientRequest request( buf); c_Panel->sendRequest( request ,false); } void XiangqiDesktop::HandleTimeout() { } void XiangqiDesktop::HandleMoveTimeout() { } void XiangqiDesktop::GetAvatarPosition(unsigned char chSite,int *x,int *y) { *x = width()-70; if(c_Panel->selfSeatId() == chSite) { *y = height()-70; }else { *y = 5; } } void XiangqiDesktop::GetUserNamePosition(unsigned char chSite,Q3CanvasText *item,int *x,int *y) { QRect rect = item->boundingRect(); *x = width()-75-rect.width(); if(c_Panel->selfSeatId() == chSite) { *y = height()-5-rect.height(); }else { *y = 5; } } void XiangqiDesktop::GetTimerPosition(unsigned char chSite,int *x,int *y) { } XiangqiDesktop::~XiangqiDesktop() { if(!c_strSaveFile.isNull()) { QFile file(c_strSaveFile); file.remove(); } } ////////////////////////////////////////////////////////////////////////// XiangqiPanel::XiangqiPanel( DJGameController *gameController, DJGameRoom *room, const QList& userIds, quint8 tableId, quint8 seatId, QWidget * parent, Qt::WFlags f) : DJGamePanel( gameController, room, userIds, tableId, seatId, parent, f ) { //char chDbgFile[60]; //sprintf(chDbgFile,"Xiangqi_%d_%d.dbg",tableId,seatId); //DEBUG_INITFILE((chDbgFile)); QSplitter* mainSplitter = new QSplitter(Qt::Horizontal , this); setCentralWidget( mainSplitter ); m_leftSplitter = new QSplitter(Qt::Vertical , mainSplitter); QSplitter *rightSplitter = new QSplitter(Qt::Vertical , mainSplitter); c_Ad = new DJTopWidget(rightSplitter); c_DesktopCanvas = new Q3Canvas(this); c_DesktopCanvas->resize(100,100); c_Desktop = new XiangqiDesktop(c_DesktopCanvas,rightSplitter,this); /* QList selfColor; PosColor pc1 = { 0, QColor(224,238,255) }; PosColor pc2 = { 0.5, QColor(144,194,255) }; PosColor pc3 = { 1, QColor(224,238,255) }; selfColor << pc1 << pc2 << pc3; QList otherColor; PosColor pc5 = { 0, Qt::white }; PosColor pc6 = { 1, QColor(225,225,225) }; otherColor << pc5 << pc6; c_PlayerList->setItemDelegate(new DJTreeItemDelegate(selfUserId(),selfColor,otherColor,this)); c_PlayerList->setMinimumWidth(150); c_PlayerList->setMaximumWidth(300); c_PlayerList->setMinimumHeight(200); c_PlayerList->setRootIsDecorated(false); QStringList headerSections; headerSections << tr("name") << tr("score")<< tr("seat") <<"-"; c_PlayerList->setColumnCount( headerSections.size() ); QTreeWidgetItem* headerItem = new QTreeWidgetItem; for ( int i = 0; i < headerSections.size(); i++) { headerItem->setTextAlignment( i, Qt::AlignHCenter ); headerItem->setText( i, headerSections.at(i) ); } c_PlayerList->header()->setClickable(false); c_PlayerList->setHeaderItem( headerItem ); c_PlayerList->setSortingEnabled( false ); */ memset(&c_Current,0,sizeof(XiangqiCurrent)); c_Current.chRed = 1; c_Current.chBlack = 2; /* quint32 uid, i; for(i=1;i<=room->numberOfSeats();i++) { uid = userIdOfSeat(i); if(c_Current.chRed == i) AppendUser2List(this,c_PlayerList,1,uid,XIANGQI_COLOR_RED); else AppendUser2List(this,c_PlayerList,1,uid,XIANGQI_COLOR_BLACK); SetUserScore(this,c_PlayerList,uid,0,2,true); } createChatWidget( s2 ); //showMaximized(); */ //c_Desktop->RepaintAvatar(); //c_Desktop->RepaintBoard(); c_chTableStatus = 0; } void XiangqiPanel::initialize() { createPlayersWidget( m_leftSplitter ); createChatWidget( m_leftSplitter ); } DJGamePlayerItem* XiangqiPanel::addPlayer( quint32 userId, bool isPlayer ) { qDebug() << "XiangqiPanel::addPlayer" << userId; if ( 0 == userId || 0 == m_playersTreeWidget ) return 0; DJGameUser* user = gameUser( userId,true ); DJGamePlayerItem* playerItem = gamePlayerItem( userId ); if ( 0 == playerItem ) { playerItem = createPlayerItem( userId, m_playersTreeWidget ); } if ( isPlayer ) { quint8 seatId = user->seatId(); QString suffix; if( c_Current.chRed == seatId ) suffix = tr("[red]"); else suffix = tr("[black]"); playerItem->setNameAndSuffix( user->userName(), suffix ); playerItem->setScore( 0 ); playerItem->setSeat( user->seatId() ); }else { playerItem->setNameAndSuffix( user->userName(), tr("(looker)") ); playerItem->setScore( 0 ); playerItem->setSeat( 0 ); } return playerItem; } /* void XiangqiPanel::lookerIn( quint32 userId, bool in ) { DJGamePanel::lookerIn( userId, in ); if ( in ) AddUser(this,c_PlayerList,1,userId,0); else RemoveUser(this,c_PlayerList,userId); } */ void XiangqiPanel::userArrived( quint32 userId, quint8 seatId ) { DJGamePanel::userArrived( userId, seatId ); c_Desktop->RepaintAvatar(); } void XiangqiPanel::gameInfo( const unsigned char *buf ) { bool bRepaint=false; XiangqiCurrent *pnc =(XiangqiCurrent*)buf; if(pnc->chRed != c_Current.chRed) bRepaint = true; memcpy(&c_Current,buf,sizeof(XiangqiCurrent)); if(bRepaint) { c_Desktop->RepaintBoard(); for(int i=1;i<=gameRoom()->numberOfSeats();i++) { quint32 userId = userIdOfSeat(i); DJGamePlayerItem* playerItem = gamePlayerItem( userId ); if ( playerItem ) { if(c_Current.chRed == i) playerItem->setNameAndSuffix( QString(), tr("[red]")); else if ( c_Current.chBlack == i ) playerItem->setNameAndSuffix( QString(), tr("[black]")); } } } } void XiangqiPanel::gameWait( quint16 mask, quint8 status ,quint16 timeout ) { c_chTableStatus = status; c_shWaitMask = mask; c_iTimeLin = time(NULL)+timeout; c_Desktop->GameWait(); switch(status) { case DJGAME_TABLE_STATUS_WAITSTART : c_Desktop->WaitStart(); break; case DJGAME_XIANGQI_TABLE_STATUS_WAIT_MOVE : c_Desktop->WaitMove(); break; } } void XiangqiPanel::gameTrace( const GeneralGameTrace2Head *gameTrace ) { GeneralGameTrace2Head *trace = const_cast(gameTrace); switch( gameTrace->chType ) { case XIANGQI_GAMETRACE_ADJUST: AppendData2SaveFile(c_Desktop->c_strSaveFile,(char *)gameTrace,sizeof(GeneralGameTrace2Head)+gameTrace->chBufLen); c_Desktop->AdjustBoard(gameTrace); break; case XIANGQI_GAMETRACE_SETRULE : AppendData2SaveFile(c_Desktop->c_strSaveFile,(char *)gameTrace,sizeof(GeneralGameTrace2Head)+gameTrace->chBufLen); c_Desktop->SetRule(gameTrace->chSite,(XiangqiRule*)gameTrace->chBuf); break; case XIANGQI_GAMETRACE_MOVE : { AppendData2SaveFile(c_Desktop->c_strSaveFile,(char *)gameTrace,sizeof(GeneralGameTrace2Head)+gameTrace->chBufLen); PXiangQiMove pmove = (PXiangQiMove)gameTrace->chBuf; c_Desktop->PlayerMove(gameTrace->chSite,pmove->chStart,pmove->chEnd); break; } case XIANGQI_GAMETRACE_REQUESTDUELS : { AppendData2SaveFile(c_Desktop->c_strSaveFile,(char *)gameTrace,sizeof(GeneralGameTrace2Head)+gameTrace->chBufLen); c_Desktop->RequestDuels(gameTrace->chSite); break; } case XIANGQI_GAMETRACE_REQUESTRULE : { PXiangqiRule prule = (PXiangqiRule)gameTrace->chBuf; //exec rule dialog, and send new rule 2 server // by XIANGQI_GAMETRACE_REQUESTRULE break; } case XIANGQI_GAMETRACE_REPEAT : { AppendData2SaveFile(c_Desktop->c_strSaveFile,(char *)gameTrace,sizeof(GeneralGameTrace2Head)+gameTrace->chBufLen); DEBUG_OUTPUT(("repeat %d\n",gameTrace->chBuf[0])); break; } } } void XiangqiPanel::magicResult( const MagicResult* magicResult ) { } void XiangqiPanel::gameOver( const DJGameOver* gameOver ) { QString res; int i,score; quint32 uid; DJGameUser *puser; if(gameOver->chSites == 2 && gameOver->site[0].score == gameOver->site[1].score) { res = tr("dues."); }else { for(i=0;ichSites;i++) { uid = userIdOfSeat(gameOver->site[i].chSite); score = (int)(ltoh4(gameOver->site[i].score)); //SetUserScore(this,c_PlayerList,uid,score,2,false); deltaPlayerScore( uid, score ); if(uid != 0) { puser = gameUser(uid,false); if(puser != NULL) { res += puser->userName(); res += QString(" : %1\n").arg(score); puser->changeScore(score); if ( score > 0 ) puser->increaseWins(); else if ( score < 0 ) puser->increaseLoses(); } } } } appendContent2Browser( res ); res = tr("Do you want save the battle ?"); if( QMessageBox::Yes == QMessageBox::information(this,tr("game over"),res,QMessageBox::Yes,QMessageBox::No) ) { QDir dir = QDir::home(); if (!dir.exists(QString("DJGameSave"))) { dir.mkdir("DJGameSave"); } dir.cd("DJGameSave"); QString filename = QFileDialog::getSaveFileName( this, tr("Save the Battle"), dir.path(), tr("DJGame Save Files(*.sav)")); if(filename.isNull()) return; if(!filename.endsWith(QString(".sav")) ) filename += QString(".sav"); InitSaveFileHead(this,filename,DJGAME_XIANGQI,XIANGQI_GAMETRACE_MOVE); unsigned int iLen = 0; char *p = GetSaveData(c_Desktop->c_strSaveFile,DJGAME_XIANGQI,XIANGQI_GAMETRACE_MOVE,&iLen); if(p == NULL || iLen == 0) { DEBUG_OUTPUT(("Cant save the movies\n")); return; } AppendData2SaveFile(filename,p,iLen); } } bool XiangqiPanel::IsWaitMove() { if(!WaittingForMe()) return false; return (c_chTableStatus == DJGAME_XIANGQI_TABLE_STATUS_WAIT_MOVE); } /////////////////////////////////////////////////////// bool XiangqiPanel::WaittingForMe() { if(c_chTableStatus != DJGAME_TABLE_STATUS_WAITSTART && c_chTableStatus != DJGAME_XIANGQI_TABLE_STATUS_WAIT_RULE && c_chTableStatus != DJGAME_XIANGQI_TABLE_STATUS_WAIT_MOVE ) return false; quint16 shMyMask = 1<<(selfSeatId()-1); return (shMyMask & c_shWaitMask); } /* void XiangqiPanel::resizeEvent( QResizeEvent * ) { s1->setGeometry(0,0,width(),height()); } */ void XiangqiPanel::closeEvent( QCloseEvent *e) { if ( isLookingOn() ) { //look on QByteArray data; data.append( selfTableId() ); QByteArray buf = makeGameData( DJGAME_PROTOCOL_SUBTYPE_QUITVIEW, data ); DJClientRequest request( buf ); sendRequest( request, false ); e->accept(); return; } if( (c_chTableStatus == DJGAME_TABLE_STATUS_WAITSTART || c_chTableStatus == DJGAME_XIANGQI_TABLE_STATUS_WAIT_RULE ) && !c_Desktop->hasStarted() ) { QByteArray buf = makeGameData( DJGAME_PROTOCOL_SUBTYPE_QUIT, QByteArray() ); DJClientRequest request( buf ); sendRequest( request, false ); e->accept(); }else { e->ignore(); } } XiangqiPanel::~XiangqiPanel() { }