#include #include #include #include #include "serverplayer.h" #include "game.h" #include "servereventdata.h" #include "client.h" #include "tablezone.h" #include "handzone.h" #include "carddatabase.h" #include "dlg_startgame.h" #include "playerarea.h" #include "counter.h" Game::Game(CardDatabase *_db, Client *_client, QGraphicsScene *_scene, QMenu *_actionsMenu, QMenu *_cardMenu, int playerId, const QString &playerName, QObject *parent) : QObject(parent), actionsMenu(_actionsMenu), cardMenu(_cardMenu), db(_db), client(_client), scene(_scene), started(false) { QRectF sr = scene->sceneRect(); localPlayer = addPlayer(playerId, playerName, QPointF(0, sr.y() + sr.height() / 2 + 2), true); connect(client, SIGNAL(gameEvent(const ServerEventData &)), this, SLOT(gameEvent(const ServerEventData &))); connect(client, SIGNAL(playerListReceived(QList)), this, SLOT(playerListReceived(QList))); aUntapAll = new QAction(tr("&Untap all permanents"), this); aUntapAll->setShortcut(tr("Ctrl+U")); connect(aUntapAll, SIGNAL(triggered()), this, SLOT(actUntapAll())); aDecLife = new QAction(tr("&Decrement life"), this); aDecLife->setShortcut(tr("F11")); connect(aDecLife, SIGNAL(triggered()), this, SLOT(actDecLife())); aIncLife = new QAction(tr("&Increment life"), this); aIncLife->setShortcut(tr("F12")); connect(aIncLife, SIGNAL(triggered()), this, SLOT(actIncLife())); aSetLife = new QAction(tr("&Set life"), this); aSetLife->setShortcut(tr("Ctrl+L")); connect(aSetLife, SIGNAL(triggered()), this, SLOT(actSetLife())); aShuffle = new QAction(tr("&Shuffle"), this); aShuffle->setShortcut(tr("Ctrl+S")); connect(aShuffle, SIGNAL(triggered()), this, SLOT(actShuffle())); aDraw = new QAction(tr("&Draw a card"), this); aDraw->setShortcut(tr("Ctrl+D")); connect(aDraw, SIGNAL(triggered()), this, SLOT(actDrawCard())); aDrawCards = new QAction(tr("D&raw cards..."), this); connect(aDrawCards, SIGNAL(triggered()), this, SLOT(actDrawCards())); aDrawCards->setShortcut(tr("Ctrl+E")); aRollDice = new QAction(tr("R&oll dice..."), this); aRollDice->setShortcut(tr("Ctrl+I")); connect(aRollDice, SIGNAL(triggered()), this, SLOT(actRollDice())); aCreateToken = new QAction(tr("&Create token..."), this); aCreateToken->setShortcut(tr("Ctrl+T")); connect(aCreateToken, SIGNAL(triggered()), this, SLOT(actCreateToken())); actionsMenu->addAction(aUntapAll); actionsMenu->addSeparator(); actionsMenu->addAction(aDecLife); actionsMenu->addAction(aIncLife); actionsMenu->addAction(aSetLife); actionsMenu->addSeparator(); actionsMenu->addAction(aShuffle); actionsMenu->addAction(aDraw); actionsMenu->addAction(aDrawCards); actionsMenu->addAction(aRollDice); actionsMenu->addSeparator(); actionsMenu->addAction(aCreateToken); actionsMenu->addSeparator(); sayMenu = actionsMenu->addMenu(tr("S&ay")); initSayMenu(); aTap = new QAction(tr("&Tap"), this); connect(aTap, SIGNAL(triggered()), this, SLOT(actTap())); aUntap = new QAction(tr("&Untap"), this); connect(aUntap, SIGNAL(triggered()), this, SLOT(actUntap())); aDoesntUntap = new QAction(tr("Toggle &normal untapping"), this); connect(aDoesntUntap, SIGNAL(triggered()), this, SLOT(actDoesntUntap())); aFlip = new QAction(tr("&Flip"), this); connect(aFlip, SIGNAL(triggered()), this, SLOT(actFlip())); aAddCounter = new QAction(tr("&Add counter"), this); connect(aAddCounter, SIGNAL(triggered()), this, SLOT(actAddCounter())); aRemoveCounter = new QAction(tr("&Remove counter"), this); connect(aRemoveCounter, SIGNAL(triggered()), this, SLOT(actRemoveCounter())); aSetCounters = new QAction(tr("&Set counters..."), this); connect(aSetCounters, SIGNAL(triggered()), this, SLOT(actSetCounters())); cardMenu->addAction(aTap); cardMenu->addAction(aUntap); cardMenu->addAction(aDoesntUntap); cardMenu->addSeparator(); cardMenu->addAction(aFlip); cardMenu->addSeparator(); cardMenu->addAction(aAddCounter); cardMenu->addAction(aRemoveCounter); cardMenu->addAction(aSetCounters); dlgStartGame = new DlgStartGame(db); connect(dlgStartGame, SIGNAL(newDeckLoaded(const QStringList &)), client, SLOT(submitDeck(const QStringList &))); connect(dlgStartGame, SIGNAL(finished(int)), this, SLOT(readyStart())); } Game::~Game() { qDebug("Game destructor"); for (int i = 0; i < players.size(); i++) { emit playerRemoved(players.at(i)); delete players.at(i); } } void Game::initSayMenu() { sayMenu->clear(); QSettings settings; settings.beginGroup("messages"); int count = settings.value("count", 0).toInt(); for (int i = 0; i < count; i++) { QAction *newAction = new QAction(settings.value(QString("msg%1").arg(i)).toString(), this); QString shortcut; switch (i) { case 0: shortcut = tr("F5"); break; case 1: shortcut = tr("F6"); break; case 2: shortcut = tr("F7"); break; case 3: shortcut = tr("F8"); break; case 4: shortcut = tr("F9"); break; case 5: shortcut = tr("F10"); break; } newAction->setShortcut(shortcut); connect(newAction, SIGNAL(triggered()), this, SLOT(actSayMessage())); sayMenu->addAction(newAction); } } Player *Game::addPlayer(int playerId, const QString &playerName, QPointF base, bool local) { Player *newPlayer = new Player(playerName, playerId, base, local, db, client, scene, this); connect(newPlayer, SIGNAL(hoverCard(QString)), this, SIGNAL(hoverCard(QString))); connect(newPlayer, SIGNAL(sigShowCardMenu(QPoint)), this, SLOT(showCardMenu(QPoint))); connect(newPlayer, SIGNAL(logMoveCard(QString, QString, QString, QString)), this, SIGNAL(logMoveCard(QString, QString, QString, QString))); connect(newPlayer, SIGNAL(logCreateToken(QString, QString)), this, SIGNAL(logCreateToken(QString, QString))); connect(newPlayer, SIGNAL(logSetCardCounters(QString, QString, int, int)), this, SIGNAL(logSetCardCounters(QString, QString, int, int))); connect(newPlayer, SIGNAL(logSetTapped(QString, QString, bool)), this, SIGNAL(logSetTapped(QString, QString, bool))); connect(newPlayer, SIGNAL(logSetCounter(QString, QString, int, int)), this, SIGNAL(logSetCounter(QString, QString, int, int))); connect(newPlayer, SIGNAL(logSetDoesntUntap(QString, QString, bool)), this, SIGNAL(logSetDoesntUntap(QString, QString, bool))); players << newPlayer; emit playerAdded(newPlayer); return newPlayer; } void Game::playerListReceived(QList playerList) { QListIterator i(playerList); QStringList nameList; while (i.hasNext()) { ServerPlayer *temp = i.next(); nameList << temp->getName(); int id = temp->getPlayerId(); if (id != localPlayer->getId()) addPlayer(id, temp->getName(), QPointF(0, 0), false); delete temp; } emit logPlayerListReceived(nameList); restartGameDialog(); } void Game::readyStart() { client->readyStart(); } void Game::restartGameDialog() { dlgStartGame->show(); } void Game::gameEvent(const ServerEventData &msg) { qDebug(QString("game::gameEvent: public=%1, player=%2, name=%3, type=%4, data=%5").arg(msg.getPublic()).arg(msg.getPlayerId()).arg(msg.getPlayerName()).arg(msg.getEventType()).arg(msg.getEventData().join("/")).toLatin1()); if (!msg.getPublic()) localPlayer->gameEvent(msg); else { Player *p = players.findPlayer(msg.getPlayerId()); if (!p) { // XXX } switch(msg.getEventType()) { case eventSay: emit logSay(p->getName(), msg.getEventData()[0]); break; case eventJoin: { emit logJoin(msg.getPlayerName()); addPlayer(msg.getPlayerId(), msg.getPlayerName(), QPointF(0, 0), false); break; } case eventLeave: emit logLeave(msg.getPlayerName()); // XXX Spieler natürlich noch rauswerfen break; case eventReadyStart: if (started) { started = false; emit logReadyStart(p->getName()); if (!p->getLocal()) restartGameDialog(); } break; case eventGameStart: started = true; emit logGameStart(); break; case eventShuffle: emit logShuffle(p->getName()); break; case eventRollDice: { QStringList data = msg.getEventData(); int sides = data[0].toInt(); int roll = data[1].toInt(); emit logRollDice(p->getName(), sides, roll); break; } case eventSetActivePlayer: break; case eventSetActivePhase: break; case eventName: case eventCreateToken: case eventSetupZones: case eventSetCardAttr: case eventAddCounter: case eventSetCounter: case eventDelCounter: case eventPlayerId: { p->gameEvent(msg); break; } case eventDumpZone: { QStringList data = msg.getEventData(); emit logDumpZone(p->getName(), data[1], players.findPlayer(data[0].toInt())->getName(), data[2].toInt()); break; } case eventMoveCard: { if (msg.getPlayerId() == localPlayer->getId()) break; p->gameEvent(msg); break; } case eventDraw: { emit logDraw(p->getName(), msg.getEventData()[0].toInt()); if (msg.getPlayerId() == localPlayer->getId()) break; p->gameEvent(msg); break; } case eventInvalid: qDebug("Unhandled global event"); } } } void Game::actUntapAll() { client->setCardAttr("table", -1, "tapped", "false"); } void Game::actIncLife() { client->incCounter("life", 1); } void Game::actDecLife() { client->incCounter("life", -1); } void Game::actSetLife() { bool ok; int life = QInputDialog::getInteger(0, tr("Set life"), tr("New life total:"), localPlayer->area->getCounter("life")->getValue(), 0, 2000000000, 1, &ok); if (ok) client->setCounter("life", life); } void Game::actShuffle() { client->shuffle(); } void Game::actRollDice() { bool ok; int sides = QInputDialog::getInteger(0, tr("Roll dice"), tr("Number of sides:"), 20, 2, 1000, 1, &ok); if (ok) client->rollDice(sides); } void Game::actDrawCard() { client->drawCards(1); } void Game::actDrawCards() { int number = QInputDialog::getInteger(0, tr("Draw cards"), tr("Number:")); if (number) client->drawCards(number); } void Game::actCreateToken() { QString cardname = QInputDialog::getText(0, tr("Create token"), tr("Name:")); client->createToken("table", cardname, QString(), 0, 0); } void Game::showCardMenu(QPoint p) { cardMenu->exec(p); } void Game::actTap() { QListIterator i(scene->selectedItems()); while (i.hasNext()) { CardItem *temp = (CardItem *) i.next(); if (!temp->getTapped()) client->setCardAttr(qgraphicsitem_cast(temp->parentItem())->getName(), temp->getId(), "tapped", "1"); } } void Game::actUntap() { QListIterator i(scene->selectedItems()); while (i.hasNext()) { CardItem *temp = (CardItem *) i.next(); if (temp->getTapped()) client->setCardAttr(qgraphicsitem_cast(temp->parentItem())->getName(), temp->getId(), "tapped", "0"); } } void Game::actDoesntUntap() { QListIterator i(scene->selectedItems()); while (i.hasNext()) { CardItem *temp = (CardItem *) i.next(); client->setCardAttr(qgraphicsitem_cast(temp->parentItem())->getName(), temp->getId(), "doesnt_untap", QString::number(!temp->getDoesntUntap())); } } void Game::actFlip() { QListIterator i(scene->selectedItems()); while (i.hasNext()) { CardItem *temp = (CardItem *) i.next(); QString zone = qgraphicsitem_cast(temp->parentItem())->getName(); client->moveCard(temp->getId(), zone, zone, temp->getGridPoint().x(), temp->getGridPoint().y(), !temp->getFaceDown()); } } void Game::actAddCounter() { QListIterator i(scene->selectedItems()); while (i.hasNext()) { CardItem *temp = (CardItem *) i.next(); if (temp->getCounters() < MAX_COUNTERS_ON_CARD) client->setCardAttr(qgraphicsitem_cast(temp->parentItem())->getName(), temp->getId(), "counters", QString::number(temp->getCounters() + 1)); } } void Game::actRemoveCounter() { QListIterator i(scene->selectedItems()); while (i.hasNext()) { CardItem *temp = (CardItem *) i.next(); if (temp->getCounters()) client->setCardAttr(qgraphicsitem_cast(temp->parentItem())->getName(), temp->getId(), "counters", QString::number(temp->getCounters() - 1)); } } void Game::actSetCounters() { bool ok; int number = QInputDialog::getInteger(0, tr("Set counters"), tr("Number:"), 0, 0, MAX_COUNTERS_ON_CARD, 1, &ok); if (!ok) return; QListIterator i(scene->selectedItems()); while (i.hasNext()) { CardItem *temp = (CardItem *) i.next(); client->setCardAttr(qgraphicsitem_cast(temp->parentItem())->getName(), temp->getId(), "counters", QString::number(number)); } } void Game::actSayMessage() { QAction *a = qobject_cast(sender()); client->say(a->text()); }