📄 machiavelli.cpp
字号:
//-----------------------------------------------------------------------------/// Enables the cards the human can pick up./// \returns \c 0//-----------------------------------------------------------------------------bool Machiavelli::enableHuman () { TRACE4 ("Machiavelli::enableHuman ()"); Check3 (staple.size ()); Check3 (activeCards.empty ()); if (staple.size ()) activeCards.push_back (staple.getTopCard ().signal_clicked ().connect (mem_fun (*this, (&Machiavelli::endTurn)))); nextTurn.set_sensitive (true); for (unsigned int i (0); i < hands[0].size (); ++i) registerHandDND (i); Check3 (aDNDHand.size () == hands[0].size ()); newPile.drag_dest_set (dndTypeBoth, Gtk::DEST_DEFAULT_ALL, Gdk::ACTION_MOVE); aDNDTable[NULL].connReceive = newPile.signal_drag_data_received ().connect (bind (mem_fun (*this, &Machiavelli::cardDroppedOnTable), -1U)); for (unsigned int i (0); i < tablePiles.size (); ++i) { MachiPile& pile (*tablePiles[i]); unsigned int value (i << 8); for (unsigned int j (0); j < pile.size (); ++j) registerTableDND (*pile[j], value++); } return Game::enableHuman ();}//-----------------------------------------------------------------------------/// Disables the cards the human player can select//-----------------------------------------------------------------------------void Machiavelli::disableHuman () { TRACE2 ("Machiavelli::disableHuman () - DND: " << aDNDHand.size () << "; " << aDNDTable.size ()); Game::disableHuman (); newPile.drag_dest_unset (); if (aDNDHand.size ()) for (unsigned int i (0); i < hands[0].size (); ++i) unregisterHandDND (*hands[0][i]); Check3 (aDNDHand.empty ()); unregisterTableDND (); nextTurn.set_sensitive (false);}//----------------------------------------------------------------------------/// Changes the names of the playing people/// \param newPlayer: Array holding the new player//----------------------------------------------------------------------------void Machiavelli::changeNames (const std::vector<Player*>& newPlayer) { Game::changeNames (newPlayer); for (unsigned int i (0); i < NUM_PLAYERS; ++i) { TRACE1 ("Machiavelli::changeNames () " << i << ": " << newPlayer[i]->getName ()); names[i].set_text (newPlayer[i]->getName ()); }}//----------------------------------------------------------------------------/// Sets the startplayer; including showing it in the status bar/// \param player: Player to start the game//----------------------------------------------------------------------------void Machiavelli::setStartPlayer () { if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::CLIENT) { setNextPlayer (startPlayer); broadcastStartPlayer (startPlayer); } dealCard (startPlayer); displayTurn (startPlayer++); startPlayer &= 0x3; makeNextMoves ();}//-----------------------------------------------------------------------------/// Callback to end a turn//-----------------------------------------------------------------------------void Machiavelli::endTurn () { TRACE5 ("Machiavelli::endTurn ()"); Check1 (gameStatus () == PLAYING); Check3 (staple.size ()); Check3 (activeCards.size ()); // Show error, if any YGP::StatusObject obj; checkPiles (obj); if (obj.getType () != YGP::StatusObject::UNDEFINED) { obj.generalize (_("Can't end turn: The piles are not valid!")); undoDlg = XGP::MessageDlg::create (obj); undoDlg->set_title (PACKAGE); undoDlg->get_window ()->set_transient_for (this->get_window ()); // Add undo-buttons Gtk::Button* undoAll (manage (new Gtk::Button (_("_Undo all"), true))); Gtk::Button* undoLast (manage (new Gtk::Button (_("Undo _last"), true))); undoAll->show (); undoLast->show (); undoDlg->get_action_area ()->pack_end (*undoAll, Gtk::PACK_SHRINK, 5); undoDlg->get_action_area ()->pack_end (*undoLast, Gtk::PACK_SHRINK, 5); undoAll->signal_clicked ().connect (bind (mem_fun (*this, &Machiavelli::undoMove), -1U)); undoLast->signal_clicked ().connect (bind (mem_fun (*this, &Machiavelli::undoMove), 1)); return; } while (undo.size ()) undo.pop (); if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::NONE) { // Send played card to all clients (if any) if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) ++ignoreNextMsg; broadcastMessage ("EndTurn"); } disableHuman (); unsigned int nextPlayer (findNextPlayer (currentPlayer ())); setNextPlayer (nextPlayer); if (nextPlayer == findNextPlayer (nextPlayer)) endGame (nextPlayer); else { displayTurn (nextPlayer); dealCard (nextPlayer); makeNextMoves (); }}//-----------------------------------------------------------------------------/// Prepares the passed region of cards for drag磏磀rop/// \param start: Number of first card to prepare for DND/// \param end: Number of last card to prepare for DND/// \pre \c start < \c end; \c end <= Nr. ofcards//-----------------------------------------------------------------------------void Machiavelli::registerHandDND (unsigned int start, unsigned int end) { TRACE5 ("Machiavelli::registerHandDND (unsigned int, unsigned int) - [" << start << '-' << end << ']'); Check1 (start <= end); Check1 (end < hands[0].size ()); for (; start <= end; ++start) { unregisterHandDND (*hands[0][start]); registerHandDND (start); }}//-----------------------------------------------------------------------------/// Prepares the card for drag磏磀rop/// \param iCard: Number of card in hand//-----------------------------------------------------------------------------void Machiavelli::registerHandDND (unsigned int iCard) { Check1 (iCard < hands[0].size ()); TRACE9 ("Machiavelli::registerHandDND (unsigned int) - Card: " << iCard << " (" << *hands[0][iCard] << ')'); CardWidget& card (*hands[0][iCard]); Check3 (aDNDHand.find (&card) == aDNDHand.end ()); // Card accepts drops from hand and drags from table card.drag_dest_set (dndTypeHand, Gtk::DEST_DEFAULT_ALL, Gdk::ACTION_MOVE); card.drag_source_set (dndTypeHand, Gdk::ModifierType (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK), Gdk::ACTION_MOVE); card.drag_source_set_icon (card.getImage ()); aDNDHand[&card].connReceive = card.signal_drag_data_received ().connect (bind (mem_fun (*this, &Machiavelli::cardDropped), iCard)); aDNDHand[&card].connGet = card.signal_drag_data_get ().connect (bind (mem_fun (*this, &Machiavelli::getDropData), iCard));}//-----------------------------------------------------------------------------/// Stops the drag磏磀rop abilities of the passed card/// \param card: Card to unregister of dnd//-----------------------------------------------------------------------------void Machiavelli::unregisterHandDND (CardWidget& card) { TRACE9 ("Machiavelli::unregisterHandDND (CardWidget&) - Card: " << card); Check1 (aDNDHand.size ()); std::map<CardWidget*, CONNECTIONS>::iterator i (aDNDHand.find (&card)); Check1 (i != aDNDHand.end ()); card.drag_dest_unset (); card.drag_source_unset (); i->second.connReceive.disconnect (); i->second.connGet.disconnect (); aDNDHand.erase (i);}//-----------------------------------------------------------------------------/// Prepares the passed region of cards for drag磏磀rop/// \param pile: Pile whose cards should be registered. This value is calcualated/// like (row << 4) + column/// \param start: Number of first card to prepare for DND/// \param end: Number of last card to prepare for DND/// \pre: \c start < \c end; \c end <= Number of cards//-----------------------------------------------------------------------------void Machiavelli::registerTableDND (unsigned int pile, unsigned int start, unsigned int end) { TRACE9 ("Machiavelli::registerTableDND (unsigned int, unsigned int, unsigned int)" << " - " << pile << '[' << start << '-' << end << ']'); Check1 (pile < tablePiles.size ()); Check1 (start <= end); Check1 (end < tablePiles[pile]->size ()); ICardPile& tmp (*tablePiles[pile]); pile <<= 8; for (; start <= end; ++start) { CardWidget& card (*tmp[start]); unregisterTableDND (card); registerTableDND (card, pile + start); }}//-----------------------------------------------------------------------------/// Prepares the card for drag磏磀rop/// \param card: Card to register/// \param nr: Number of card in pile//-----------------------------------------------------------------------------void Machiavelli::registerTableDND (CardWidget& card, unsigned int nr) { TRACE9 ("Machiavelli::registerTableDND (CardWidget&, unsigned int) - " << card << " = " << std::hex << nr << std::dec); // Card accepts drops from hand and drags from table card.drag_dest_set (dndTypeBoth, Gtk::DEST_DEFAULT_ALL, Gdk::ACTION_MOVE); card.drag_source_set (dndTypeTable, Gdk::ModifierType (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK), Gdk::ACTION_MOVE); card.drag_source_set_icon (card.getImage ()); aDNDTable[&card].connReceive = card.signal_drag_data_received ().connect (bind (mem_fun (*this, &Machiavelli::cardDroppedOnTable), nr)); aDNDTable[&card].connGet = card.signal_drag_data_get ().connect (bind (mem_fun (*this, &Machiavelli::getDropData), nr));}//-----------------------------------------------------------------------------/// Stops the drag磏磀rop abilities of the passed card/// \param card: Card to de-register//-----------------------------------------------------------------------------void Machiavelli::unregisterTableDND (CardWidget& card) { TRACE9 ("Machiavelli::unregisterTableDND (unsigned int) - Card: " << card << " - " << &card ); Check1 (aDNDTable.size () > 1); std::map<CardWidget*, CONNECTIONS>::iterator i (aDNDTable.find (&card)); Check1 (i != aDNDTable.end ()); card.drag_dest_unset (); i->second.connGet.disconnect (); i->second.connReceive.disconnect (); aDNDTable.erase (i);}//-----------------------------------------------------------------------------/// Stops the drag磏磀rop abilities of all cards on the table//-----------------------------------------------------------------------------void Machiavelli::unregisterTableDND () { for (std::map<CardWidget*, CONNECTIONS>::iterator i (aDNDTable.begin ()); i != aDNDTable.end (); ++i) { i->second.connGet.disconnect (); i->second.connReceive.disconnect (); } aDNDTable.clear ();}//-----------------------------------------------------------------------------/// Callback after dropping a card (within the hand)/// \param pContext: Context of the drag (contains things like source,/// \param target, action, ...)/// \param data: Describes the thing which was dropped/// \param time: Timestamp of the drag/// \param card: Number of card where something was dropped at/// \pre \c pContext not NULL; Expects \c info to be 0//-----------------------------------------------------------------------------void Machiavelli::cardDropped (const Glib::RefPtr<Gdk::DragContext>& context, gint, gint, const Gtk::SelectionData& data, guint, guint32 time, unsigned int card) { Check3 (!context->get_is_source ()); Check3 (data.get_length () == sizeof (int)); Check3 (data.get_format () == 8); Check3 (card < hands[0].size ()); unsigned int* pValue (reinterpret_cast <unsigned int*> (const_cast<guint8*> (data.get_data ()))); Check3 (pValue); Check3 (*pValue < hands[0].size ()); TRACE1 ("Machiavelli::cardDropped (...) - Inserting card " << *pValue << " at pos " << card); context->drag_finish (true, false, time); // End old DND CardWidget& cardMoved (hands[0].remove (*pValue)); hands[0].insert (cardMoved, card); // Insert moved card // Adapt dnd-settigns if (*pValue < card) { unsigned int temp (card); card = *pValue; *pValue = temp; } Glib::signal_idle ().connect (bind (mem_fun (*this, &Machiavelli::doRegisterHand), card, *pValue));}//-----------------------------------------------------------------------------/// Checks if the piles on the table are valid (have at least 3 cards)/// \param except: Pile which can be invalid/// \returns \c True, if the piles are OK//-----------------------------------------------------------------------------bool Machiavelli::doRegisterHand (unsigned int first, unsigned int last) { TRACE9 ("Buraco::doRegisterHand (unsigned int, unsigned int) - [" << first << '-' << last); Check1 (last < hands[0].size ()); Check1 (first <= last); registerHandDND (first, last); Check3 (aDNDHand.size () == hands[0].size ()); return false;}//-----------------------------------------------------------------------------/// Callback to query the data to drop/// \param pContext: Context of the drag (contains things like source,/// \param target, action, ...)/// \param data: Describes the thing which was dropped/// \param time: Timestamp of the drag/// \param cardPos: Position of card (either in hand or pile on table)/// \pre \c pContext not NULL; Expects \c info to be 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -