/* lskat.cpp - description ------------------- begin : Tue May 2 15:47:11 CEST 2000 copyright : (C) 2000 by Martin Heni email : martin@heni-online.de ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ // include files for QT #include // include files for TDE #include #include #include #include #include #include #include #include #include // application specific includes #include "lskat.h" #include "lskatview.h" #include "lskatdoc.h" #include "namedlg.h" #include "networkdlg.h" #include "msgdlg.h" #include #include #include #define ACTION(x) (actionCollection()->action(x)) #define ID_STATUS_MSG 1003 #define ID_STATUS_MOVER 1002 LSkatApp::LSkatApp() : TDEMainWindow(0) { config=kapp->config(); // localise data file TQString file=TQString::fromLatin1("lskat/grafix/t1.png"); mGrafix=kapp->dirs()->findResourceDir("data", file); if (mGrafix.isNull()) mGrafix = TQCString("grafix/"); else mGrafix+=TQCString("lskat/grafix/"); if (global_debug>3) printf("Localised datafile=%s\n",mGrafix.latin1()); /////////////////////////////////////////////////////////////////// // call inits to invoke all other construction parts initGUI(); initStatusBar(); setupGUI(TDEMainWindow::StatusBar | Save); createGUI(TQString(), false); initDocument(); initView(); doc->ReadConfig(config); // Needs to be after readOptions as we read in default paths doc->LoadGrafix(mGrafix); mInput=new KEInput(this); doc->SetInputHandler(mInput); connect(mInput,TQ_SIGNAL(signalPrepareProcessMove(KEMessage *)), this,TQ_SLOT(slotPrepareProcessMove(KEMessage *))); connect(mInput,TQ_SIGNAL(signalPrepareRemoteMove(KEMessage *)), this,TQ_SLOT(slotPrepareRemoteMove(KEMessage *))); connect(mInput,TQ_SIGNAL(signalPrepareInteractiveMove(KEMessage *)), this,TQ_SLOT(slotPrepareInteractiveMove(KEMessage *))); connect(mInput,TQ_SIGNAL(signalReceiveInput(KEMessage *, int)), this,TQ_SLOT(slotReceiveInput(KEMessage *,int ))); setMinimumSize(640,480); setMaximumSize(800,600); resize( 640, 480 ); // better be last in init checkMenus(); } LSkatApp::~LSkatApp() { delete mInput; } void LSkatApp::checkMenus(int menu) { if (!menu || (menu&CheckFileMenu)) { if (doc->IsRunning()) disableAction("new_game"); else enableAction("new_game"); if (!doc->IsRunning()) disableAction("end_game"); else enableAction("end_game"); if (doc->GetPlayedBy(0)==KG_INPUTTYPE_REMOTE || doc->GetPlayedBy(0)==KG_INPUTTYPE_REMOTE ) { enableAction("send_message"); } else { disableAction("send_message"); } } if (!menu || (menu&CheckOptionsMenu)) { ((TDESelectAction *)ACTION("startplayer"))->setCurrentItem(doc->GetStartPlayer()); if (doc->IsRunning()) disableAction("startplayer"); else enableAction("startplayer"); if (doc->GetPlayedBy(0)==KG_INPUTTYPE_INTERACTIVE) ((TDESelectAction *)ACTION("player1"))->setCurrentItem(0); else if (doc->GetPlayedBy(0)==KG_INPUTTYPE_PROCESS) ((TDESelectAction *)ACTION("player1"))->setCurrentItem(1); else ((TDESelectAction *)ACTION("player1"))->setCurrentItem(2); /* if (doc->IsRunning()) disableAction("player1"); else enableAction("player1"); */ if (doc->GetPlayedBy(1)==KG_INPUTTYPE_INTERACTIVE) ((TDESelectAction *)ACTION("player2"))->setCurrentItem(0); else if (doc->GetPlayedBy(1)==KG_INPUTTYPE_PROCESS) ((TDESelectAction *)ACTION("player2"))->setCurrentItem(1); else ((TDESelectAction *)ACTION("player2"))->setCurrentItem(2); /* if (doc->IsRunning()) disableAction("player2"); else enableAction("player2"); */ ((TDESelectAction *)ACTION("choose_level"))->setCurrentItem(doc->GetComputerLevel()-1); } } void LSkatApp::initGUI() { TQStringList list; (void)KStdAction::openNew(this, TQ_SLOT(slotFileNew()), actionCollection(), "new_game"); ACTION("new_game")->setStatusText(i18n("Starting a new game...")); ACTION("new_game")->setWhatsThis(i18n("Starting a new game...")); (void)new TDEAction(i18n("&End Game"),"process-stop", 0, this, TQ_SLOT(slotFileEnd()), actionCollection(), "end_game"); ACTION("end_game")->setStatusText(i18n("Ending the current game...")); ACTION("end_game")->setWhatsThis(i18n("Aborts a currently played game. No winner will be declared.")); (void)new TDEAction(i18n("&Clear Statistics"),"flag", 0, this, TQ_SLOT(slotFileStatistics()), actionCollection(), "clear_statistics"); ACTION("clear_statistics")->setStatusText(i18n("Delete all time statistics...")); ACTION("clear_statistics")->setWhatsThis(i18n("Clears the all time statistics which is kept in all sessions.")); (void)new TDEAction(i18n("Send &Message..."), CTRL+Key_M, this, TQ_SLOT(slotFileMessage()), actionCollection(), "send_message"); ACTION("send_message")->setStatusText(i18n("Sending message to remote player...")); ACTION("send_message")->setWhatsThis(i18n("Allows you to talk with a remote player.")); (void)KStdAction::quit(this, TQ_SLOT(slotFileQuit()), actionCollection(), "game_exit"); ACTION("game_exit")->setStatusText(i18n("Exiting...")); ACTION("game_exit")->setWhatsThis(i18n("Quits the program.")); (void)new TDESelectAction(i18n("Starting Player"),0,this,TQ_SLOT(slotStartplayer()), actionCollection(), "startplayer"); ACTION("startplayer")->setStatusText(i18n("Changing starting player...")); ACTION("startplayer")->setWhatsThis(i18n("Chooses which player begins the next game.")); list.clear(); list.append(i18n("Player &1")); list.append(i18n("Player &2")); ((TDESelectAction *)ACTION("startplayer"))->setItems(list); (void)new TDESelectAction(i18n("Player &1 Played By"),0,this,TQ_SLOT(slotPlayer1By()), actionCollection(), "player1"); ACTION("player1")->setStatusText(i18n("Changing who plays player 1...")); ACTION("player1")->setWhatsThis(i18n("Changing who plays player 1...")); list.clear(); list.append(i18n("&Player")); list.append(i18n("&Computer")); list.append(i18n("&Remote")); ((TDESelectAction *)ACTION("player1"))->setItems(list); (void)new TDESelectAction(i18n("Player &2 Played By"),0,this,TQ_SLOT(slotPlayer2By()), actionCollection(), "player2"); ACTION("player1")->setStatusText(i18n("Changing who plays player 2...")); ACTION("player1")->setWhatsThis(i18n("Changing who plays player 2...")); ((TDESelectAction *)ACTION("player2"))->setItems(list); (void)new TDESelectAction(i18n("&Level"),0,this,TQ_SLOT(slotLevel()), actionCollection(), "choose_level"); ACTION("choose_level")->setStatusText(i18n("Change level...")); ACTION("choose_level")->setWhatsThis(i18n("Change the strength of the computer player.")); list.clear(); list.append(i18n("&Normal")); list.append(i18n("&Advanced")); list.append(i18n("&Hard")); ((TDESelectAction *)ACTION("choose_level"))->setItems(list); (void)new TDEAction(i18n("Select &Card Deck..."), 0, this, TQ_SLOT(slotOptionsCardDeck()), actionCollection(), "select_carddeck"); ACTION("select_carddeck")->setStatusText(i18n("Configure card decks...")); ACTION("select_carddeck")->setWhatsThis(i18n("Choose how the cards should look.")); (void)new TDEAction(i18n("Change &Names..."), 0, this, TQ_SLOT(slotOptionsNames()), actionCollection(), "change_names"); ACTION("change_names")->setStatusText(i18n("Configure player names...")); ACTION("change_names")->setWhatsThis(i18n("Configure player names...")); actionCollection()->setHighlightingEnabled(true); connect(actionCollection(), TQ_SIGNAL(actionStatusText(const TQString &)), TQ_SLOT(slotStatusMsg(const TQString &))); connect(actionCollection(), TQ_SIGNAL(clearStatusText()), TQ_SLOT(slotClearStatusMsg())); KStdAction::keyBindings(guiFactory(), TQ_SLOT(configureShortcuts()), actionCollection()); } void LSkatApp::initStatusBar() { /////////////////////////////////////////////////////////////////// // STATUSBAR // statusBar()->setInsertOrder(KStatusBar::RightToLeft); statusBar()->insertItem(i18n("This leaves space for the mover"),ID_STATUS_MOVER,0,true); statusBar()->insertItem(i18n("Ready"), ID_STATUS_MSG); slotStatusMover(i18n("(c) Martin Heni ")); slotStatusMsg(i18n("Welcome to Lieutenant Skat")); // computer move timer procTimer=new TQTimer(this); connect(procTimer,TQ_SIGNAL(timeout()),this,TQ_SLOT(slotProcTimer())); } void LSkatApp::initDocument() { doc = new LSkatDoc(this); // TODO check for return false !!! doc->newDocument(config,mGrafix); } void LSkatApp::initView() { //////////////////////////////////////////////////////////////////// // create the main widget here that is managed by TDEMainWindow's view-region and // connect the widget to your document to display document contents. view = new LSkatView(this); doc->addView(view); setCentralWidget(view); setCaption(i18n("Lieutenant Skat")); } void LSkatApp::enableAction(const char *s) { if (s) { TDEAction *act=actionCollection()->action(s); if (act) act->setEnabled(true); } } void LSkatApp::disableAction(const char *s) { if (s) { TDEAction *act=actionCollection()->action(s); if (act) act->setEnabled(false); } } LSkatDoc *LSkatApp::getDocument() const { return doc; } void LSkatApp::saveProperties(TDEConfig *_cfg) { if(doc->getTitle()!=i18n("Untitled") && !doc->isModified()) { // saving to tempfile not necessary } else { TQString filename=doc->getAbsFilePath(); _cfg->writePathEntry("filename", filename); _cfg->writeEntry("modified", doc->isModified()); TQString tempname = kapp->tempSaveName(filename); doc->saveDocument(tempname); } } void LSkatApp::readProperties(TDEConfig* _cfg) { TQString filename = _cfg->readPathEntry("filename"); bool modified = _cfg->readBoolEntry("modified", false); if(modified) { bool canRecover; TQString tempname = kapp->checkRecoverFile(filename, canRecover); if(canRecover) { doc->openDocument(tempname); doc->setModified(); TQFileInfo info(filename); doc->setAbsFilePath(info.absFilePath()); doc->setTitle(info.fileName()); TQFile::remove(tempname); } } else { if(!filename.isEmpty()) { doc->openDocument(filename); } } //TQString caption=kapp->caption(); setCaption(i18n("Lieutenant Skat")); } bool LSkatApp::queryClose() { return true; return doc->saveModified(); } bool LSkatApp::queryExit() { doc->WriteConfig(config); return true; } ///////////////////////////////////////////////////////////////////// // SLOT IMPLEMENTATION ///////////////////////////////////////////////////////////////////// void LSkatApp::slotFileStatistics() { TQString message; message=i18n("Do you really want to clear the all time " "statistical data?"); if (KMessageBox::Yes==KMessageBox::questionYesNo(this,message,TQString(),KStdGuiItem::clear())) { doc->ClearStats(); doc->slotUpdateAllViews(0); } } /** send message */ void LSkatApp::slotFileMessage() { int res; MsgDlg *dlg=new MsgDlg(this,TQCString("Send message...")); res=dlg->exec(); if (res==TQDialog::Accepted) { TQString s; s=dlg->GetMsg(); if (!s || s.length()<1) s=TQCString("..."); KEMessage *msg=new KEMessage; // printf("Msg: %s\n",(char *)msg); msg->AddData(TQCString("Message"),(char *)(s.latin1())); if (mInput->QueryType(0)==KG_INPUTTYPE_REMOTE) mInput->SendMsg(msg,0); if (mInput->QueryType(1)==KG_INPUTTYPE_REMOTE) mInput->SendMsg(msg,1); delete msg; } } void LSkatApp::slotFileNew() { NewGame(); checkMenus(CheckFileMenu|CheckOptionsMenu); } void LSkatApp::slotFileEnd() { doc->EndGame(true); doc->slotUpdateAllViews(0); slotStatusMsg(i18n("Game ended...start a new one...")); KEMessage *msg=new KEMessage; msg->AddData(TQCString("EndGame"),(short)1); if (mInput->QueryType(0)==KG_INPUTTYPE_REMOTE) mInput->SendMsg(msg,0); if (mInput->QueryType(1)==KG_INPUTTYPE_REMOTE) mInput->SendMsg(msg,1); msg->RemoveAll(); msg->AddData(TQCString("Terminate"),(short)1); if (mInput->QueryType(0)==KG_INPUTTYPE_PROCESS) mInput->SendMsg(msg,0); if (mInput->QueryType(1)==KG_INPUTTYPE_PROCESS) mInput->SendMsg(msg,1); delete msg; checkMenus(CheckFileMenu|CheckOptionsMenu); slotStatusNames(); } void LSkatApp::slotFileQuit() { doc->WriteConfig(config); if (view) view->close(); close(); kdDebug() << "slotFileQuit done"<currentItem(); doc->SetStartPlayer(i); doc->UpdateViews(UPDATE_STATUS); } void LSkatApp::slotPlayer1By() { switch(((TDESelectAction *)ACTION("player1"))->currentItem()) { case 0: slotPlayer1(KG_INPUTTYPE_INTERACTIVE); break; case 1: slotPlayer1(KG_INPUTTYPE_PROCESS); break; case 2: slotPlayer1(KG_INPUTTYPE_REMOTE); break; } } void LSkatApp::slotPlayer2By() { switch(((TDESelectAction *)ACTION("player2"))->currentItem()) { case 0: slotPlayer2(KG_INPUTTYPE_INTERACTIVE); break; case 1: slotPlayer2(KG_INPUTTYPE_PROCESS); break; case 2: slotPlayer2(KG_INPUTTYPE_REMOTE); break; } } void LSkatApp::slotPlayer1(KG_INPUTTYPE i) { doc->SetPlayedBy(0,i); if (doc->IsRunning()) { MakeInputDevice(0); // New: Start computer when switched during game if (mInput->QueryType(0)!=KG_INPUTTYPE_REMOTE && doc->GetCurrentPlayer()==0 ) { mInput->Unlock(); mInput->Next(doc->GetCurrentPlayer()); } } doc->UpdateViews(UPDATE_STATUS); } void LSkatApp::slotPlayer2(KG_INPUTTYPE i) { doc->SetPlayedBy(1,i); if (doc->IsRunning()) { MakeInputDevice(1); // New: Start computer when switched during game if (mInput->QueryType(0)!=KG_INPUTTYPE_REMOTE && doc->GetCurrentPlayer()==1 ) { mInput->Unlock(); mInput->Next(doc->GetCurrentPlayer()); } } doc->UpdateViews(UPDATE_STATUS); } void LSkatApp::slotOptionsNames() { NameDlg *dlg=new NameDlg(this,TQCString("Enter your name...")); dlg->SetNames(doc->GetName(0),doc->GetName(1)); if (dlg->exec()==TQDialog::Accepted) { TQString n1,n2; dlg->GetNames(n1,n2); doc->SetName(0,n1); doc->SetName(1,n2); doc->UpdateViews(UPDATE_STATUS); slotStatusNames(); } } void LSkatApp::slotOptionsCardDeck() { TQString s1,s2; int result; s1=doc->GetDeckpath(); s2=doc->GetCardpath(); result=KCardDialog::getCardDeck(s1,s2); if (result==TQDialog::Accepted) { doc->SetCardDeckPath(s1,s2); doc->slotUpdateAllViews(0); } } void LSkatApp::slotLevel() { int i=((TDESelectAction *)ACTION("choose_level"))->currentItem(); i++; // we start at 1 doc->SetComputerLevel(i); doc->UpdateViews(UPDATE_STATUS); printf("Level set to %d\n",i); } void LSkatApp::slotClearStatusMsg() { slotStatusMsg(i18n("Ready")); } void LSkatApp::slotStatusMsg(const TQString &text) { /////////////////////////////////////////////////////////////////// // change status message permanently statusBar()->clear(); statusBar()->changeItem(text, ID_STATUS_MSG); } void LSkatApp::slotStatusMover(const TQString &text) { /////////////////////////////////////////////////////////////////// // change status mover permanently statusBar()->clear(); statusBar()->changeItem(text, ID_STATUS_MOVER); } void LSkatApp::slotStatusHelpMsg(const TQString &text) { /////////////////////////////////////////////////////////////////// // change status message of whole statusbar temporary (text, msec) statusBar()->message(text, 2000); } /** Triggers the processmove timer */ void LSkatApp::slotProcTimer(void) { mInput->Unlock(); mInput->Next(doc->GetCurrentPlayer()); /* printf("Delayed setting Next=%d ->%d\n", doc->GetCurrentPlayer(),mInput->QueryNext()); */ } /** Set the names in the mover field */ void LSkatApp::slotStatusNames(){ TQString msg; if (!doc->IsRunning()) msg=i18n("No game running"); else { msg=i18n("%1 to move...").arg(doc->GetName(doc->GetCurrentPlayer())); } slotStatusMover(msg); } void LSkatApp::NewGame() { bool res; // doc->SetIntro(0); doc->NewGame(); doc->slotUpdateAllViews(0); res=MakeInputDevice(0); if (!res) { KMessageBox::error(this, i18n("Cannot start player 1. Maybe the network connection " "failed or the computer player process file is not " "found.")); return ; } res=MakeInputDevice(1); if (!res) { KMessageBox::error(this, i18n("Cannot start player 2. Maybe the network connection " "failed or the computer player process file is not " "found.")); return ; } // Remote game is started when receiving the start mesage .. not here! if (mInput->QueryType(0)!=KG_INPUTTYPE_REMOTE && mInput->QueryType(1)!=KG_INPUTTYPE_REMOTE ) { mInput->Unlock(); mInput->Next(doc->GetStartPlayer()); } // Connected 0 and we are server else if (mInput->QueryType(0)==KG_INPUTTYPE_REMOTE && mInput->QueryStatus()>0 && doc->IsServer()) { mInput->Unlock(); mInput->Next(doc->GetStartPlayer()); } // Connected 1 and we are server else if (mInput->QueryType(1)==KG_INPUTTYPE_REMOTE && mInput->QueryStatus()>1 && doc->IsServer()) { mInput->Unlock(); mInput->Next(doc->GetStartPlayer()); } slotStatusNames(); } bool LSkatApp::MakeInputDevice(int no) { bool res=true; KEMessage *msg; disableAction("send_message"); KG_INPUTTYPE type=doc->GetPlayedBy(no); if (type==KG_INPUTTYPE_INTERACTIVE) { if (mInput->QueryType(no)!=type) res=mInput->SetInputDevice(no,type); } else if (type==KG_INPUTTYPE_REMOTE) { TQString host; short port; TQString Name; msg=new KEMessage; PrepareGame(msg); // Build new connection if ( mInput->QueryType(no)!=type || mInput->QueryStatus(no)<=0) { OptionsNetwork(); port=doc->QueryPort(); host=doc->QueryHost(); Name=doc->QueryName(); msg->AddData(TQCString("Port"),(short)port); msg->AddData(TQCString("IP"),(char *)(host.latin1())); msg->AddData(TQCString("Name"),(const char *)(Name.utf8())); res=mInput->SetInputDevice(no,type,msg); if (!res) { TQProgressDialog *progress; TQString s; int tim,j; tim=10000; if (!host.isEmpty()) { s=i18n("Remote connection to %1:%2...").arg(host).arg(port); } else { s=i18n("Offering remote connection on port %1...").arg(port); } progress=new TQProgressDialog(s, i18n("Abort"), tim, this,0,true ); progress->setCaption(i18n("Lieutenant Skat")); for (j=0; jsetProgress( j ); if ( progress->wasCancelled() ) break; if (mInput->QueryStatus(no)>0) break; usleep(100); } // progress.setProgress(tim); delete progress; } } else // we are already connected { // force the other one to be client usleep(1000); if (doc->IsServer()) { if (global_debug>10) printf("We want the other one to be client\n"); msg->AddData(TQCString("Client"),(short)-1); // force client mInput->SendMsg(msg,no); } // resp server else { if (global_debug>10) printf("We want the other one to be server\n"); msg->AddData(TQCString("Server"),(short)-1); // force server mInput->SendMsg(msg,no); } } delete msg; if (mInput->QueryStatus(no)>0) { res=true; } else res=false; enableAction("send_message"); } else if (type==KG_INPUTTYPE_PROCESS) { if (mInput->QueryType(no)!=type) { // TQString path=kapp->dirs()->findExe(doc->QueryProcessName()); TQString path=doc->GetProcess(); if (global_debug>5) { printf("Make Process %d\n",no); printf("Exe file found: %s\n",path.latin1()); } if (path.isNull()) return false; msg=new KEMessage; msg->AddData(TQCString("ProcessName"),(char *)(path.latin1())); // msg->AddData("ProcessName",doc->QueryProcessName()); res=mInput->SetInputDevice(no,KG_INPUTTYPE_PROCESS,msg); delete msg; } } return res; } void LSkatApp::OptionsNetwork() { int res; NetworkDlg *dlg=new NetworkDlg(this,TQCString("Configure a network game...")); dlg->SetPort(doc->QueryPort()); dlg->SetHost(doc->QueryHost()); dlg->SetName(doc->QueryName()); res=dlg->exec(); doc->SetPort(dlg->QueryPort()); doc->SetHost(dlg->QueryHost()); doc->SetName(dlg->QueryName()); delete dlg; } void LSkatApp::slotPrepareProcessMove(KEMessage *msg) { if (global_debug>3) printf("+++ main should prepare process move\n"); slotStatusMsg(i18n("Waiting for the computer to move...")); msg->AddData(TQCString("Hint"),(short)0); msg->AddData(TQCString("Move"),(short)1); if (global_debug>3) printf("PREPARE GAME in processmove\n"); if (global_debug>1) msg->AddData(TQCString("KLogSendMsg"),"process.log"); PrepareGame(msg); } void LSkatApp::slotPrepareRemoteMove(KEMessage *) { if (global_debug>3) printf("+++ main should prepare remote move\n"); slotStatusMsg(i18n("Waiting for remote player...")); } void LSkatApp::slotPrepareInteractiveMove(KEMessage *) { if (global_debug>3) printf("+++ main should prepare interactive move\n"); slotStatusMsg(i18n("Please make your move...")); } void LSkatApp::slotReceiveInput(KEMessage *msg,int ) { /* if (global_debug>=0) { TQStrList *keys=msg->QueryKeys(); char *it; printf(" MESSAGESIZE=%u\n",msg->QueryNumberOfKeys()); for (it=keys->first();it!=0;it=keys->next()) { printf(" Key '%s' type=%d\n",it,msg->QueryType(it)); } } */ short move; TQString message; short x,y,player; bool remotesend; int size; if (msg->HasKey(TQCString("Debug"))) { char *debug; msg->GetData(TQCString("Debug"),debug,size); printf("Received Debug: %d <%s>\n",size,debug); } if (msg->HasKey(TQCString("ConnectionLost"))) { if (msg->GetData(TQCString("ConnectionLost"),move)) { if (move==0) { message=i18n("Remote connection lost for player 1..."); KMessageBox::information(this,message); slotStatusMsg(message); slotPlayer1(KG_INPUTTYPE_INTERACTIVE); } else { message=i18n("Remote connection lost for player 2..."); KMessageBox::information(this,message); slotStatusMsg(message); slotPlayer2(KG_INPUTTYPE_INTERACTIVE); } } } if (msg->HasKey(TQCString("Message"))) { char *p; if (msg->GetData(TQCString("Message"),p,size)) { message=i18n("Message from remote player:\n")+p; KMessageBox::information(this,message); if (global_debug>3) printf("MESSAGE **** %s ****\n",message.latin1()); } } if (msg->HasKey(TQCString("EndGame"))) { KEMessage *msg2=new KEMessage; msg2->AddData(TQCString("Terminate"),(short)1); if (mInput->QueryType(0)==KG_INPUTTYPE_PROCESS) mInput->SendMsg(msg2,0); if (mInput->QueryType(1)==KG_INPUTTYPE_PROCESS) mInput->SendMsg(msg2,1); delete msg2; msg->GetData(TQCString("EndGame"),move); message=i18n("Remote player ended game..."); KMessageBox::information(this,message); slotStatusMsg(message); doc->EndGame(true); doc->slotUpdateAllViews(0); slotStatusNames(); } if (msg->HasKey(TQCString("Move"))) { slotStatusMsg(i18n("Ready")); msg->GetData(TQCString("Move"),player); msg->GetData(TQCString("MoveX"),x); msg->GetData(TQCString("MoveY"),y); remotesend=msg->HasKey(TQCString("RemoteMove")); if (remotesend && doc->IsRemoteSwitch()) player=1-player; Move((int)x,(int)y,(int)player,remotesend); } // Client key is automatically added by message system !!! if (msg->HasKey(TQCString("Client"))) { if (global_debug>5) printf("We are client and extracting game data now.\n"); slotStatusMsg(i18n("You are network client...loading remote game...")); doc->NewGame(); ExtractGame(msg); doc->SetServer(false); doc->slotUpdateAllViews(0); mInput->Unlock(); mInput->Next(doc->GetStartPlayer()); } // Server key is automatically added by message system !!! if (msg->HasKey(TQCString("Server"))) { if (global_debug>5) printf("We are server now.\n"); slotStatusMsg(i18n("You are network server...")); doc->SetServer(true); mInput->Unlock(); mInput->Next(doc->GetStartPlayer()); } } // Called after the move animation done void LSkatApp::MoveFinished() { int res=doc->MakeMove(); TQString ld,s; if (res==2) // end game { doc->EvaluateGame(); doc->slotUpdateAllViews(0); // m->SetStatusBar(i18n("Game over"),3); //doc->SwitchStartPlayer(); doc->slotUpdateAllViews(0); checkMenus(CheckFileMenu|CheckOptionsMenu); } else if (doc->IsRunning()) // continue game { // Delay fast playing of the computer ! /* printf("*** next=%d current=%d playedby=%d\n", mInput->QueryNext(),doc->GetCurrentPlayer() , doc->GetPlayedBy(doc->GetCurrentPlayer())); */ // Maybe we do not need to distinquish these two cases? // Computer was last and is next if (doc->GetPlayedBy(mInput->QueryNext())==KG_INPUTTYPE_PROCESS && doc->GetPlayedBy(doc->GetCurrentPlayer())==KG_INPUTTYPE_PROCESS) { procTimer->start(1000,true); } // Computer is next else if (doc->GetPlayedBy(doc->GetCurrentPlayer())==KG_INPUTTYPE_PROCESS) { procTimer->start(1000,true); } else { mInput->Unlock(); mInput->Next(doc->GetCurrentPlayer()); } } slotStatusNames(); } void LSkatApp::Move(int x,int y,int player,bool remote) { KEMessage *msg; if (global_debug>1) printf("Move of %d to x=%d y=%d\n",player,x,y); if (x<0 || y<0 || x>7 || y>1 || player <0 || player>1) { KMessageBox::error(this, i18n("Severe internal error. Move to illegal position.\n" "Restart game and report bug to the developer.\n")); return ; } int res=doc->PrepareMove(player,y*4+x); if (res>0) { doc->InitMove(0,player,x,y); if (mInput->QueryType()!=KG_INPUTTYPE_REMOTE && !remote ) { msg=new KEMessage; if (doc->IsRemoteSwitch()) player=1-player; msg->AddData(TQCString("Move"),(short)player); msg->AddData(TQCString("MoveX"),(short)x); msg->AddData(TQCString("MoveY"),(short)y); msg->AddData(TQCString("RemoteMove"),(short)1); if (mInput->QueryType(0)==KG_INPUTTYPE_REMOTE) mInput->SendMsg(msg,0); if (mInput->QueryType(1)==KG_INPUTTYPE_REMOTE) mInput->SendMsg(msg,1); delete msg; } } else if (res==-3) { KMessageBox::information(this, i18n("This move would not follow the rulebook.\n" "Better think again!\n")); return ; } else if (res==-2) { KMessageBox::information(this,i18n("It is not your turn.\n")); return ; } else { KMessageBox::information(this, i18n("This move is not possible.\n")); return ; } } void LSkatApp::PrepareGame(KEMessage *msg) { if (!msg) return; msg->AddData(TQCString("Cards"),(char *)doc->GetCardP(),NO_OF_CARDS*sizeof(int)); msg->AddData(TQCString("Startplayer"),(short)doc->GetStartPlayer()); msg->AddData(TQCString("CurrentPlayer"),(short)doc->GetCurrentPlayer()); if (doc->GetPlayedBy(0)==KG_INPUTTYPE_REMOTE) msg->AddData(TQCString("RemoteIs"),(short)0); else if (doc->GetPlayedBy(1)==KG_INPUTTYPE_REMOTE) msg->AddData(TQCString("RemoteIs"),(short)1); msg->AddData(TQCString("Trump"),(short)doc->GetTrump()); // For computer player // -1 or the current played card msg->AddData(TQCString("CurrentMove"),(short)doc->GetMove(doc->GetStartPlayer())); msg->AddData(TQCString("Height"),(char *)doc->GetCardHeightP(),NO_OF_CARDS/2*sizeof(int)); msg->AddData(TQCString("No"),(short)doc->GetMoveNo()); msg->AddData(TQCString("Sc1"),(short)doc->GetScore(0)); msg->AddData(TQCString("Sc2"),(short)doc->GetScore(1)); msg->AddData(TQCString("Level"),(short)doc->GetComputerLevel()); } void LSkatApp::ExtractGame(KEMessage *msg) { if (!msg) return; // Do we have to switch players? bool switchit; short remote; msg->GetData(TQCString("RemoteIs"),remote); if (doc->GetPlayedBy(remote)==KG_INPUTTYPE_REMOTE) switchit=true; else switchit=false; short start; int i,size; int *cards; char *p; short trump; msg->GetData(TQCString("Startplayer"),start); msg->GetData(TQCString("Cards"),p,size); cards=(int *)p; msg->GetData(TQCString("Trump"),trump); if (size!=NO_OF_CARDS*sizeof(int)) { printf("Error: Transmission of cards failed..wrong sizes\n"); } doc->SetRemoteSwitch(switchit); if (switchit) { start=1-start; for (i=0;i=NO_OF_CARDS/2) doc->SetCard(i-NO_OF_CARDS/2,cards[i]); else doc->SetCard(i+NO_OF_CARDS/2,cards[i]); } } else { for (i=0;iSetCard(i,cards[i]); } } doc->SetStartPlayer(start); doc->SetCurrentPlayer(start); doc->SetTrump((CCOLOUR)trump); } void LSkatApp::SetGrafix(TQString s) { mGrafix=s; } #include "lskat.moc"