prepareGeometryChange bugfix; more arrows code

This commit is contained in:
Max-Wilhelm Bruker 2009-10-20 23:20:07 +02:00
parent 961b42f734
commit c57e138a78
13 changed files with 289 additions and 87 deletions

View file

@ -7,8 +7,8 @@
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsScene>
ArrowItem::ArrowItem(CardItem *_startItem, CardItem *_targetItem)
: QGraphicsItem(), startItem(_startItem), targetItem(_targetItem)
ArrowItem::ArrowItem(int _id, CardItem *_startItem, CardItem *_targetItem, const QColor &_color)
: QGraphicsItem(), id(_id), startItem(_startItem), targetItem(_targetItem), color(_color), fullColor(true)
{
setZValue(2000000005);
if (startItem && targetItem)
@ -17,7 +17,6 @@ ArrowItem::ArrowItem(CardItem *_startItem, CardItem *_targetItem)
void ArrowItem::updatePath()
{
color = QColor(255, 0, 0, 200);
QPointF endPoint = targetItem->mapToScene(QPointF(targetItem->boundingRect().width() / 2, targetItem->boundingRect().height() / 2));
updatePath(endPoint);
}
@ -32,6 +31,7 @@ void ArrowItem::updatePath(const QPointF &endPoint)
QLineF line(startPoint, endPoint);
qreal lineLength = line.length();
prepareGeometryChange();
if (lineLength < headLength)
path = QPainterPath();
else {
@ -51,12 +51,17 @@ void ArrowItem::updatePath(const QPointF &endPoint)
void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
painter->setBrush(color);
QColor paintColor(color);
if (fullColor)
paintColor.setAlpha(200);
else
paintColor.setAlpha(150);
painter->setBrush(paintColor);
painter->drawPath(path);
}
ArrowDragItem::ArrowDragItem(CardItem *_startItem)
: ArrowItem(_startItem)
: ArrowItem(-1, _startItem)
{
}
@ -71,10 +76,11 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if ((cursorItem = qgraphicsitem_cast<CardItem *>(colliding.at(i))))
break;
if (!cursorItem) {
fullColor = false;
targetItem = 0;
updatePath(endPos);
color = QColor(190, 0, 0, 150);
} else {
fullColor = true;
targetItem = cursorItem;
updatePath();
}
@ -92,7 +98,8 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
startItem->getId(),
targetZone->getPlayer()->getId(),
targetZone->getName(),
targetItem->getId()
targetItem->getId(),
color
);
}
deleteLater();

View file

@ -11,14 +11,22 @@ class ArrowItem : public QObject, public QGraphicsItem {
private:
QPainterPath path;
protected:
QColor color;
int id;
CardItem *startItem, *targetItem;
QColor color;
bool fullColor;
public:
ArrowItem(CardItem *_startItem = 0, CardItem *_targetItem = 0);
ArrowItem(int id, CardItem *_startItem = 0, CardItem *_targetItem = 0, const QColor &color = Qt::red);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QRectF boundingRect() const { return path.boundingRect(); }
void updatePath();
void updatePath(const QPointF &endPoint);
int getId() const { return id; }
void setStartItem(CardItem *_item) { startItem = _item; }
void setTargetItem(CardItem *_item) { targetItem = _item; }
CardItem *getStartItem() const { return startItem; }
CardItem *getTargetItem() const { return targetItem; }
};
class ArrowDragItem : public ArrowItem {

View file

@ -23,6 +23,7 @@ ServerEventData::ServerEventData(const QString &line)
eventHash.insert("move_card", eventMoveCard);
eventHash.insert("create_token", eventCreateToken);
eventHash.insert("create_arrow", eventCreateArrow);
eventHash.insert("delete_arrow", eventDeleteArrow);
eventHash.insert("set_card_attr", eventSetCardAttr);
eventHash.insert("add_counter", eventAddCounter);
eventHash.insert("set_counter", eventSetCounter);
@ -110,6 +111,7 @@ void PendingCommand_DumpAll::responseReceived(ServerResponse resp)
emit zoneListReceived(zoneList);
emit cardListReceived(cardList);
emit counterListReceived(counterList);
emit arrowListReceived(arrowList);
}
PendingCommand::responseReceived(resp);
}
@ -319,8 +321,7 @@ void Client::readLine()
}
int cmdid = values.takeFirst().toInt();
PendingCommand *pc = pendingCommands.value(cmdid, 0);
int colorValue = values[3].toInt();
ServerCounter sc(values[0].toInt(), values[1].toInt(), values[2], QColor(colorValue / 65536, (colorValue % 65536) / 256, colorValue % 256), values[4].toInt(), values[5].toInt());
ServerCounter sc(values[0].toInt(), values[1].toInt(), values[2], numberToColor(values[3].toInt()), values[4].toInt(), values[5].toInt());
PendingCommand_ListCounters *pcLC = qobject_cast<PendingCommand_ListCounters *>(pc);
if (pcLC)
@ -332,6 +333,20 @@ void Client::readLine()
else
emit protocolError();
}
} else if (prefix == "list_arrows") {
if (values.size() != 10) {
emit protocolError();
continue;
}
int cmdid = values.takeFirst().toInt();
PendingCommand *pc = pendingCommands.value(cmdid, 0);
ServerArrow sa(values[0].toInt(), values[1].toInt(), values[2].toInt(), values[3], values[4].toInt(), values[5].toInt(), values[6], values[7].toInt(), numberToColor(values[8].toInt()));
PendingCommand_DumpAll *pcDA = qobject_cast<PendingCommand_DumpAll *>(pc);
if (pcDA)
pcDA->addArrow(sa);
else
emit protocolError();
} else
emit protocolError();
}
@ -498,9 +513,9 @@ PendingCommand *Client::createToken(const QString &zone, const QString &name, co
return cmd(QString("create_token|%1|%2|%3|%4|%5").arg(zone).arg(name).arg(powtough).arg(x).arg(y));
}
PendingCommand *Client::createArrow(int startPlayerId, const QString &startZone, int startCardId, int targetPlayerId, const QString &targetPlayerZone, int targetCardId)
PendingCommand *Client::createArrow(int startPlayerId, const QString &startZone, int startCardId, int targetPlayerId, const QString &targetPlayerZone, int targetCardId, const QColor &color)
{
return cmd(QString("create_arrow|%1|%2|%3|%4|%5|%6").arg(startPlayerId).arg(startZone).arg(startCardId).arg(targetPlayerId).arg(targetPlayerZone).arg(targetCardId));
return cmd(QString("create_arrow|%1|%2|%3|%4|%5|%6|%7").arg(startPlayerId).arg(startZone).arg(startCardId).arg(targetPlayerId).arg(targetPlayerZone).arg(targetCardId).arg(colorToNumber(color)));
}
PendingCommand *Client::setCardAttr(const QString &zone, int cardid, const QString &aname, const QString &avalue)
@ -529,7 +544,7 @@ PendingCommand *Client::incCounter(int counterId, int delta)
PendingCommand *Client::addCounter(const QString &counterName, QColor color, int radius, int value)
{
return cmd(QString("add_counter|%1|%2|%3|%4").arg(counterName).arg(color.red() * 65536 + color.green() * 256 + color.blue()).arg(radius).arg(value));
return cmd(QString("add_counter|%1|%2|%3|%4").arg(counterName).arg(colorToNumber(color)).arg(radius).arg(value));
}
PendingCommand *Client::setCounter(int counterId, int value)
@ -584,3 +599,13 @@ PendingCommand_DumpAll *Client::dumpAll()
cmd("dump_all", pc);
return pc;
}
QColor Client::numberToColor(int colorValue) const
{
return QColor(colorValue / 65536, (colorValue % 65536) / 256, colorValue % 256);
}
int Client::colorToNumber(const QColor &color) const
{
return color.red() * 65536 + color.green() * 256 + color.blue();
}

View file

@ -45,6 +45,7 @@ enum ServerEventType {
eventMoveCard,
eventCreateToken,
eventCreateArrow,
eventDeleteArrow,
eventSetCardAttr,
eventAddCounter,
eventSetCounter,
@ -195,6 +196,31 @@ public:
int getCount() const { return count; }
};
class ServerArrow {
private:
int id;
int playerId;
int startPlayerId;
QString startZone;
int startCardId;
int targetPlayerId;
QString targetZone;
int targetCardId;
QColor color;
public:
ServerArrow(int _playerId, int _id, int _startPlayerId, const QString &_startZone, int _startCardId, int _targetPlayerId, const QString &_targetZone, int _targetCardId, const QColor &_color)
: id(_id), playerId(_playerId), startPlayerId(_startPlayerId), startZone(_startZone), startCardId(_startCardId), targetPlayerId(_targetPlayerId), targetZone(_targetZone), targetCardId(_targetCardId), color(_color) { }
int getId() const { return id; }
int getPlayerId() const { return playerId; }
int getStartPlayerId() const { return startPlayerId; }
QString getStartZone() const { return startZone; }
int getStartCardId() const { return startCardId; }
int getTargetPlayerId() const { return targetPlayerId; }
QString getTargetZone() const { return targetZone; }
int getTargetCardId() const { return targetCardId; }
QColor getColor() const { return color; }
};
class PendingCommand : public QObject {
Q_OBJECT
private:
@ -288,17 +314,20 @@ private:
QList<ServerZone> zoneList;
QList<ServerZoneCard> cardList;
QList<ServerCounter> counterList;
QList<ServerArrow> arrowList;
signals:
void playerListReceived(QList<ServerPlayer> _playerList);
void zoneListReceived(QList<ServerZone> _zoneList);
void cardListReceived(QList<ServerZoneCard> _cardList);
void counterListReceived(QList<ServerCounter> _counterList);
void arrowListReceived(QList<ServerArrow> _arrowList);
public:
void responseReceived(ServerResponse resp);
void addPlayer(const ServerPlayer &player) { playerList.append(player); }
void addZone(const ServerZone &zone) { zoneList.append(zone); }
void addCard(const ServerZoneCard &card) { cardList.append(card); }
void addCounter(const ServerCounter &counter) { counterList.append(counter); }
void addArrow(const ServerArrow &arrow) { arrowList.append(arrow); }
};
class Client : public QObject {
@ -346,6 +375,9 @@ public:
void connectToServer(const QString &hostname, unsigned int port, const QString &_playerName, const QString &_password);
void disconnectFromServer();
QColor numberToColor(int colorValue) const;
int colorToNumber(const QColor &color) const;
public slots:
PendingCommand *chatListChannels();
PendingCommand_ChatJoinChannel *chatJoinChannel(const QString &name);
@ -364,7 +396,7 @@ public slots:
PendingCommand *drawCards(unsigned int number);
PendingCommand *moveCard(int cardid, const QString &startzone, const QString &targetzone, int x, int y = 0, bool faceDown = false);
PendingCommand *createToken(const QString &zone, const QString &name, const QString &powtough, int x, int y);
PendingCommand *createArrow(int startPlayerId, const QString &startZone, int startCardId, int targetPlayerId, const QString &targetPlayerZone, int targetCardId);
PendingCommand *createArrow(int startPlayerId, const QString &startZone, int startCardId, int targetPlayerId, const QString &targetPlayerZone, int targetCardId, const QColor &color);
PendingCommand *setCardAttr(const QString &zone, int cardid, const QString &aname, const QString &avalue);
PendingCommand *readyStart();
PendingCommand *incCounter(int counterId, int delta);

View file

@ -137,6 +137,7 @@ Player *Game::addPlayer(int playerId, const QString &playerName, bool local)
connect(newPlayer, SIGNAL(logSetCardCounters(Player *, QString, int, int)), this, SIGNAL(logSetCardCounters(Player *, QString, int, int)));
connect(newPlayer, SIGNAL(logSetTapped(Player *, QString, bool)), this, SIGNAL(logSetTapped(Player *, QString, bool)));
connect(newPlayer, SIGNAL(logSetCounter(Player *, QString, int, int)), this, SIGNAL(logSetCounter(Player *, QString, int, int)));
connect(newPlayer, SIGNAL(logCreateArrow(Player *, Player *, QString, Player *, QString)), this, SIGNAL(logCreateArrow(Player *, Player *, QString, Player *, QString)));
connect(newPlayer, SIGNAL(logSetDoesntUntap(Player *, QString, bool)), this, SIGNAL(logSetDoesntUntap(Player *, QString, bool)));
players.insert(playerId, newPlayer);
@ -203,6 +204,36 @@ void Game::counterListReceived(QList<ServerCounter> list)
}
}
void Game::arrowListReceived(QList<ServerArrow> list)
{
QMapIterator<int, Player *> i(players);
while (i.hasNext())
i.next().value()->clearArrows();
for (int i = 0; i < list.size(); ++i) {
Player *p = players.value(list[i].getPlayerId(), 0);
if (!p)
continue;
Player *startPlayer = players.value(list[i].getStartPlayerId(), 0);
Player *targetPlayer = players.value(list[i].getTargetPlayerId(), 0);
if (!startPlayer || !targetPlayer)
continue;
CardZone *startZone = startPlayer->getZones().value(list[i].getStartZone(), 0);
CardZone *targetZone = targetPlayer->getZones().value(list[i].getTargetZone(), 0);
if (!startZone || !targetZone)
continue;
CardItem *startCard = startZone->getCard(list[i].getStartCardId(), QString());
CardItem *targetCard = targetZone->getCard(list[i].getTargetCardId(), QString());
if (!startCard || !targetCard)
continue;
p->addArrow(list[i].getId(), startCard, targetCard, list[i].getColor());
}
}
void Game::playerListReceived(QList<ServerPlayer> playerList)
{
QStringList nameList;
@ -321,26 +352,8 @@ void Game::gameEvent(const ServerEventData &msg)
}
break;
}
case eventCreateArrow: {
const QStringList &data = msg.getEventData();
Player *startPlayer = players.value(data[0].toInt(), 0);
Player *targetPlayer = players.value(data[3].toInt(), 0);
if (!startPlayer || !targetPlayer)
break;
CardZone *startZone = startPlayer->getZones().value(data[1], 0);
CardZone *targetZone = targetPlayer->getZones().value(data[4], 0);
if (!startZone || !targetZone)
break;
CardItem *startCard = startZone->getCard(data[2].toInt(), QString());
CardItem *targetCard = targetZone->getCard(data[5].toInt(), QString());
if (!startCard || !targetCard)
break;
emit logCreateArrow(p, startPlayer, startCard->getName(), targetPlayer, targetCard->getName());
ArrowItem *arrow = new ArrowItem(startCard, targetCard);
scene->addItem(arrow);
break;
}
case eventCreateArrow:
case eventDeleteArrow:
case eventCreateToken:
case eventSetupZones:
case eventSetCardAttr:
@ -512,6 +525,7 @@ void Game::queryGameState()
connect(pc, SIGNAL(zoneListReceived(QList<ServerZone>)), this, SLOT(zoneListReceived(QList<ServerZone>)));
connect(pc, SIGNAL(cardListReceived(QList<ServerZoneCard>)), this, SLOT(cardListReceived(QList<ServerZoneCard>)));
connect(pc, SIGNAL(counterListReceived(QList<ServerCounter>)), this, SLOT(counterListReceived(QList<ServerCounter>)));
connect(pc, SIGNAL(arrowListReceived(QList<ServerArrow>)), this, SLOT(arrowListReceived(QList<ServerArrow>)));
}
void Game::activePlayerDrawCard()
@ -543,4 +557,4 @@ Player *Game::getActiveLocalPlayer() const
return p;
}
return 0;
}
}

View file

@ -68,6 +68,7 @@ private slots:
void cardListReceived(QList<ServerZoneCard> list);
void zoneListReceived(QList<ServerZone> list);
void counterListReceived(QList<ServerCounter> list);
void arrowListReceived(QList<ServerArrow> list);
void readyStart();
signals:
@ -107,6 +108,7 @@ public:
void restartGameDialog();
void hoverCardEvent(CardItem *card);
Player *addPlayer(int playerId, const QString &playerName, bool local);
const QMap<int, Player *> &getPlayers() const { return players; }
void queryGameState();
};

View file

@ -2,6 +2,7 @@
#include "client.h"
#include "cardzone.h"
#include "counter.h"
#include "arrowitem.h"
#include "zoneviewzone.h"
#include "zoneviewwidget.h"
#include "game.h"
@ -205,6 +206,7 @@ Player::~Player()
delete i.next().value();
clearCounters();
clearArrows();
delete playerMenu;
}
@ -428,6 +430,7 @@ void Player::gameEvent(const ServerEventData &event)
}
clearCounters();
clearArrows();
CardZone *deck = zones.value("deck");
for (; deck_cards; deck_cards--)
@ -486,11 +489,9 @@ void Player::gameEvent(const ServerEventData &event)
break;
}
int x = data[5].toInt();
int y = data[6].toInt();
bool facedown = data[7].toInt();
// XXX Mehr Fehlerbehandlung
int logPosition = position;
int logX = x;
@ -499,9 +500,11 @@ void Player::gameEvent(const ServerEventData &event)
if (x == -1)
x = 0;
CardItem *card = startZone->takeCard(position, cardId, cardName, startZone != targetZone);
if (!card) // XXX
if (!card) {
qDebug("moveCard: card not found");
break;
}
card->deleteDragItem();
card->setFaceDown(facedown);
@ -512,6 +515,27 @@ void Player::gameEvent(const ServerEventData &event)
targetZone->addCard(card, true, x, y);
// Look at all arrows from and to the card.
// If the card was moved to another zone, delete the arrows, otherwise update them.
QMapIterator<int, Player *> playerIterator(static_cast<Game *>(parent())->getPlayers());
while (playerIterator.hasNext()) {
Player *p = playerIterator.next().value();
QList<int> arrowsToDelete;
QMapIterator<int, ArrowItem *> arrowIterator(p->getArrows());
while (arrowIterator.hasNext()) {
ArrowItem *arrow = arrowIterator.next().value();
if ((arrow->getStartItem() == card) || (arrow->getTargetItem() == card)) {
if (startZone == targetZone)
arrow->updatePath();
else
arrowsToDelete.append(arrow->getId());
}
}
for (int i = 0; i < arrowsToDelete.size(); ++i)
p->delArrow(arrowsToDelete[i]);
}
break;
}
case eventCreateToken: {
@ -582,6 +606,39 @@ void Player::gameEvent(const ServerEventData &event)
emit logSetCounter(this, c->getName(), value, oldValue);
break;
}
case eventCreateArrow: {
if (data.size() != 8)
break;
const QMap<int, Player *> &playerList = static_cast<Game *>(parent())->getPlayers();
Player *startPlayer = playerList.value(data[1].toInt(), 0);
Player *targetPlayer = playerList.value(data[4].toInt(), 0);
if (!startPlayer || !targetPlayer)
return;
CardZone *startZone = startPlayer->getZones().value(data[2], 0);
CardZone *targetZone = targetPlayer->getZones().value(data[5], 0);
if (!startZone || !targetZone)
return;
CardItem *startCard = startZone->getCard(data[3].toInt(), QString());
CardItem *targetCard = targetZone->getCard(data[6].toInt(), QString());
if (!startCard || !targetCard)
return;
addArrow(data[0].toInt(), startCard, targetCard, client->numberToColor(data[7].toInt()));
emit logCreateArrow(this, startPlayer, startCard->getName(), targetPlayer, targetCard->getName());
break;
}
case eventDeleteArrow: {
if (data.size() != 1)
break;
delArrow(data[0].toInt());
break;
}
default:
qDebug("unhandled player event");
}
@ -666,6 +723,30 @@ void Player::clearCounters()
counters.clear();
}
void Player::addArrow(int arrowId, CardItem *startCard, CardItem *targetCard, const QColor &color)
{
ArrowItem *arrow = new ArrowItem(arrowId, startCard, targetCard, color);
arrows.insert(arrowId, arrow);
scene()->addItem(arrow);
}
void Player::delArrow(int arrowId)
{
ArrowItem *a = arrows.value(arrowId, 0);
if (!a)
return;
arrows.remove(arrowId);
delete a;
}
void Player::clearArrows()
{
QMapIterator<int, ArrowItem *> arrowIterator(arrows);
while (arrowIterator.hasNext())
delete arrowIterator.next().value();
arrows.clear();
}
void Player::rearrangeCounters()
{
qreal marginTop = 50;

View file

@ -14,6 +14,7 @@ class QAction;
class ZoneViewZone;
class Game;
class Counter;
class ArrowItem;
class CardZone;
class TableZone;
class HandZone;
@ -32,6 +33,7 @@ signals:
void logSetCardCounters(Player *player, QString cardName, int value, int oldValue);
void logSetTapped(Player *player, QString cardName, bool tapped);
void logSetCounter(Player *player, QString counterName, int value, int oldValue);
void logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard);
void logSetDoesntUntap(Player *player, QString cardName, bool doesntUntap);
void sizeChanged();
@ -80,6 +82,7 @@ private:
QRectF bRect;
QMap<int, Counter *> counters;
QMap<int, ArrowItem *> arrows;
void rearrangeCounters();
void initSayMenu();
@ -94,6 +97,10 @@ public:
void addCounter(int counterId, const QString &name, QColor color, int radius, int value);
void delCounter(int counterId);
void clearCounters();
void addArrow(int arrowId, CardItem *startCard, CardItem *targetCard, const QColor &color);
void delArrow(int arrowId);
void clearArrows();
Client *client;
void addZone(CardZone *z);
@ -105,6 +112,7 @@ public:
QString getName() const { return name; }
bool getLocal() const { return local; }
const QMap<QString, CardZone *> &getZones() const { return zones; }
const QMap<int, ArrowItem *> &getArrows() const { return arrows; }
TableZone *getTable() const { return table; }
void gameEvent(const ServerEventData &event);
CardDatabase *getDb() const { return db; }

View file

@ -109,6 +109,7 @@ void TableZone::resizeToContents()
xMax = minWidth;
int newWidth = xMax + 2 * marginX;
if (newWidth != width) {
prepareGeometryChange();
width = newWidth;
emit sizeChanged();
}

View file

@ -5,11 +5,13 @@ class Card;
class Arrow {
private:
int id;
Card *startCard, *targetCard;
int color;
public:
Arrow(Card *_startCard, Card *_targetCard, int _color)
: startCard(_startCard), targetCard(_targetCard), color(_color) { }
Arrow(int _id, Card *_startCard, Card *_targetCard, int _color)
: id(_id), startCard(_startCard), targetCard(_targetCard), color(_color) { }
int getId() const { return id; }
Card *getStartCard() const { return startCard; }
Card *getTargetCard() const { return targetCard; }
int getColor() const { return color; }

View file

@ -49,13 +49,13 @@ public:
bool getGameStarted() const { return gameStarted; }
int getPlayerCount() const { return players.size(); }
const QList<ServerSocket *> &getPlayers() const { return players; }
ServerSocket *getPlayer(int playerId);
int getGameId() const { return gameId; }
QString getDescription() const { return description; }
QString getPassword() const { return password; }
int getMaxPlayers() const { return maxPlayers; }
bool getSpectatorsAllowed() const { return spectatorsAllowed; }
QString getGameListLine() const;
ServerSocket *getPlayer(int playerId);
ReturnMessage::ReturnCode checkJoin(const QString &_password, bool spectator);
void addPlayer(ServerSocket *player, bool spectator);
void removePlayer(ServerSocket *player);

View file

@ -93,11 +93,6 @@ ServerSocket::ServerSocket(Server *_server, QObject *parent)
<< QVariant::Int
<< QVariant::Int, &ServerSocket::cmdCreateArrow));
commandHash.insert("delete_arrow", CommandProperties(true, true, true, false, QList<QVariant::Type>()
<< QVariant::Int
<< QVariant::String
<< QVariant::Int
<< QVariant::Int
<< QVariant::String
<< QVariant::Int, &ServerSocket::cmdDeleteArrow));
commandHash.insert("set_card_attr", CommandProperties(true, true, true, false, QList<QVariant::Type>()
<< QVariant::String
@ -173,6 +168,18 @@ int ServerSocket::newCounterId() const
return id + 1;
}
int ServerSocket::newArrowId() const
{
int id = 0;
QMapIterator<int, Arrow *> i(arrows);
while (i.hasNext()) {
Arrow *a = i.next().value();
if (a->getId() > id)
id = a->getId();
}
return id + 1;
}
PlayerZone *ServerSocket::getZone(const QString &name) const
{
QListIterator<PlayerZone *> ZoneIterator(zones);
@ -233,8 +240,9 @@ void ServerSocket::clearZones()
delete counterIterator.next().value();
counters.clear();
for (int i = 0; i < arrows.size(); i++)
delete arrows.at(i);
QMapIterator<int, Arrow *> arrowIterator(arrows);
while (arrowIterator.hasNext())
delete arrowIterator.next().value();
arrows.clear();
}
@ -248,6 +256,16 @@ void ServerSocket::leaveGame()
clearZones();
}
bool ServerSocket::deleteArrow(int arrowId)
{
Arrow *arrow = arrows.value(arrowId, 0);
if (!arrow)
return false;
arrows.remove(arrowId);
delete arrow;
return true;
}
void ServerSocket::readClient()
{
while (canReadLine()) {
@ -556,6 +574,23 @@ ReturnMessage::ReturnCode ServerSocket::cmdMoveCard(const QList<QVariant> &param
.arg(targetzone->getName())
.arg(x)
.arg(y), this);
// If the card was moved to another zone, delete all arrows from and to the card
if (startzone != targetzone) {
const QList<ServerSocket *> &players = game->getPlayers();
for (int i = 0; i < players.size(); ++i) {
QList<int> arrowsToDelete;
QMapIterator<int, Arrow *> arrowIterator(players[i]->getArrows());
while (arrowIterator.hasNext()) {
Arrow *arrow = arrowIterator.next().value();
if ((arrow->getStartCard() == card) || (arrow->getTargetCard() == card))
arrowsToDelete.append(arrow->getId());
}
for (int j = 0; j < arrowsToDelete.size(); ++j)
players[i]->deleteArrow(arrowsToDelete[j]);
}
}
return ReturnMessage::ReturnOk;
}
@ -597,13 +632,18 @@ ReturnMessage::ReturnCode ServerSocket::cmdCreateArrow(const QList<QVariant> &pa
Card *targetCard = targetZone->getCard(params[5].toInt(), false);
if (!startCard || !targetCard || (startCard == targetCard))
return ReturnMessage::ReturnContextError;
for (int i = 0; i < arrows.size(); ++i)
if ((arrows[i]->getStartCard() == startCard) && (arrows[i]->getTargetCard() == targetCard))
QMapIterator<int, Arrow *> arrowIterator(arrows);
while (arrowIterator.hasNext()) {
Arrow *temp = arrowIterator.next().value();
if ((temp->getStartCard() == startCard) && (temp->getTargetCard() == targetCard))
return ReturnMessage::ReturnContextError;
}
int color = params[6].toInt();
arrows.append(new Arrow(startCard, targetCard, color));
emit broadcastEvent(QString("create_arrow|%1|%2|%3|%4|%5|%6|%7")
Arrow *arrow = new Arrow(newArrowId(), startCard, targetCard, color);
arrows.insert(arrow->getId(), arrow);
emit broadcastEvent(QString("create_arrow|%1|%2|%3|%4|%5|%6|%7|%8")
.arg(arrow->getId())
.arg(startPlayer->getPlayerId())
.arg(startZone->getName())
.arg(startCard->getId())
@ -617,34 +657,11 @@ ReturnMessage::ReturnCode ServerSocket::cmdCreateArrow(const QList<QVariant> &pa
ReturnMessage::ReturnCode ServerSocket::cmdDeleteArrow(const QList<QVariant> &params)
{
ServerSocket *startPlayer = game->getPlayer(params[0].toInt());
ServerSocket *targetPlayer = game->getPlayer(params[3].toInt());
if (!startPlayer || !targetPlayer)
return ReturnMessage::ReturnContextError;
PlayerZone *startZone = startPlayer->getZone(params[1].toString());
PlayerZone *targetZone = targetPlayer->getZone(params[4].toString());
if (!startZone || !targetZone)
return ReturnMessage::ReturnContextError;
Card *startCard = startZone->getCard(params[2].toInt(), false);
Card *targetCard = targetZone->getCard(params[5].toInt(), false);
Arrow *arrow = 0;
for (int i = 0; i < arrows.size(); ++i)
if ((arrows[i]->getStartCard() == startCard) && (arrows[i]->getTargetCard() == targetCard)) {
arrow = arrows.takeAt(i);
break;
}
if (!arrow)
int arrowId = params[0].toInt();
if (!deleteArrow(arrowId))
return ReturnMessage::ReturnContextError;
emit broadcastEvent(QString("delete_arrow|%1|%2|%3|%4|%5|%6")
.arg(startPlayer->getPlayerId())
.arg(startZone->getName())
.arg(startCard->getId())
.arg(targetPlayer->getPlayerId())
.arg(targetZone->getName())
.arg(targetCard->getId()), this
);
emit broadcastEvent(QString("delete_arrow|%1").arg(arrowId), this);
return ReturnMessage::ReturnOk;
}
@ -866,15 +883,18 @@ ReturnMessage::ReturnCode ServerSocket::cmdSetActivePhase(const QList<QVariant>
QStringList ServerSocket::listArrowsHelper(ServerSocket *player)
{
QStringList result;
const QList<Arrow *> &arrowList = player->getArrows();
for (int i = 0; i < arrowList.size(); ++i) {
Card *startCard = arrowList[i]->getStartCard();
Card *targetCard = arrowList[i]->getTargetCard();
QMapIterator<int, Arrow *> arrowIterator(player->getArrows());
while (arrowIterator.hasNext()) {
Arrow *arrow = arrowIterator.next().value();
Card *startCard = arrow->getStartCard();
Card *targetCard = arrow->getTargetCard();
PlayerZone *startZone = startCard->getZone();
PlayerZone *targetZone = targetCard->getZone();
ServerSocket *startPlayer = startZone->getPlayer();
ServerSocket *targetPlayer = targetZone->getPlayer();
result << QString("%1|%2|%3|%4|%5|%6|%7").arg(startPlayer->getPlayerName()).arg(startZone->getName()).arg(startCard->getId()).arg(targetPlayer->getPlayerName()).arg(targetZone->getName()).arg(targetCard->getId()).arg(arrowList[i]->getColor());
result << QString("%1|%2|%3|%4|%5|%6|%7|%8|%9").arg(player->getPlayerId()).arg(arrow->getId()).arg(startPlayer->getPlayerId()).arg(startZone->getName()).arg(startCard->getId()).arg(targetPlayer->getPlayerId()).arg(targetZone->getName()).arg(targetCard->getId()).arg(arrow->getColor());
}
return result;
}

View file

@ -115,13 +115,14 @@ private:
QList<QString> SideboardList;
QList<PlayerZone *> zones;
QMap<int, Counter *> counters;
QList<Arrow *> arrows;
QMap<int, Arrow *> arrows;
int playerId;
QString playerName;
bool spectator;
int nextCardId;
int newCardId();
int newCounterId() const;
int newArrowId() const;
PlayerZone *getZone(const QString &name) const;
void clearZones();
bool parseCommand(QString line);
@ -149,7 +150,8 @@ public:
bool getAcceptsChatChannelListChanges() const { return acceptsChatChannelListChanges; }
const QList<PlayerZone *> &getZones() const { return zones; }
const QMap<int, Counter *> &getCounters() const { return counters; }
const QList<Arrow *> &getArrows() const { return arrows; }
const QMap<int, Arrow *> &getArrows() const { return arrows; }
bool deleteArrow(int arrowId);
void setupZones();
};