This commit is contained in:
Max-Wilhelm Bruker 2009-10-17 23:55:31 +02:00
parent fd4b388975
commit 867a27ecd4
14 changed files with 249 additions and 36 deletions

View file

@ -40,7 +40,8 @@ HEADERS += src/counter.h \
src/dlg_settings.h \
src/phasestoolbar.h \
src/chatwidget.h \
src/gamescene.h
src/gamescene.h \
src/arrowitem.h
SOURCES += src/counter.cpp \
src/gameselector.cpp \
src/dlg_creategame.cpp \
@ -76,6 +77,7 @@ SOURCES += src/counter.cpp \
src/dlg_settings.cpp \
src/phasestoolbar.cpp \
src/chatwidget.cpp \
src/gamescene.cpp
src/gamescene.cpp \
src/arrowitem.cpp
TRANSLATIONS += translations/cockatrice_de.ts translations/cockatrice_en.ts
CONFIG += qt debug

View file

@ -0,0 +1,95 @@
#include "arrowitem.h"
#include "carditem.h"
#include "cardzone.h"
#include "player.h"
#include "math.h"
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsScene>
ArrowItem::ArrowItem(CardItem *_startItem, CardItem *_targetItem)
: QGraphicsItem(), startItem(_startItem), targetItem(_targetItem)
{
setZValue(2000000005);
if (startItem && targetItem)
updatePath();
}
void ArrowItem::updatePath()
{
color = QColor(255, 0, 0, 200);
QPointF endPoint = targetItem->mapToScene(QPointF(targetItem->boundingRect().width() / 2, targetItem->boundingRect().height() / 2));
updatePath(endPoint);
}
void ArrowItem::updatePath(const QPointF &endPoint)
{
const double arrowWidth = 15.0;
const double headWidth = 40.0;
const double headLength = headWidth / sqrt(2);
QPointF startPoint = startItem->mapToScene(QPointF(startItem->boundingRect().width() / 2, startItem->boundingRect().height() / 2));
QLineF line(startPoint, endPoint);
qreal lineLength = line.length();
path = QPainterPath(QPointF(0, -arrowWidth / 2));
path.lineTo(0, arrowWidth / 2);
path.lineTo(lineLength - headLength, arrowWidth / 2);
path.lineTo(lineLength - headLength, headWidth / 2);
path.lineTo(lineLength, 0);
path.lineTo(lineLength - headLength, -headWidth / 2);
path.lineTo(lineLength - headLength, -arrowWidth / 2);
path.lineTo(0, -arrowWidth / 2);
setPos(startPoint);
setTransform(QTransform().rotate(-line.angle()));
}
void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
painter->setBrush(color);
painter->drawPath(path);
}
ArrowDragItem::ArrowDragItem(CardItem *_startItem)
: ArrowItem(_startItem)
{
}
void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
event->accept();
QPointF endPos = event->scenePos();
QList<QGraphicsItem *> colliding = scene()->items(endPos);
CardItem *cursorItem = 0;
for (int i = colliding.size() - 1; i >= 0; i--)
if ((cursorItem = qgraphicsitem_cast<CardItem *>(colliding.at(i))))
break;
if (!cursorItem) {
targetItem = 0;
updatePath(endPos);
color = QColor(190, 0, 0, 150);
} else {
targetItem = cursorItem;
updatePath();
}
update();
}
void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
{
if (targetItem) {
CardZone *startZone = static_cast<CardZone *>(startItem->parentItem());
CardZone *targetZone = static_cast<CardZone *>(targetItem->parentItem());
startZone->getPlayer()->client->createArrow(
startZone->getPlayer()->getId(),
startZone->getName(),
startItem->getId(),
targetZone->getPlayer()->getId(),
targetZone->getName(),
targetItem->getId()
);
}
deleteLater();
}

View file

@ -0,0 +1,33 @@
#ifndef ARROWITEM_H
#define ARROWITEM_H
#include <QGraphicsItem>
class CardItem;
class QGraphicsSceneMouseEvent;
class ArrowItem : public QObject, public QGraphicsItem {
Q_OBJECT
private:
QPainterPath path;
protected:
QColor color;
CardItem *startItem, *targetItem;
public:
ArrowItem(CardItem *_startItem = 0, CardItem *_targetItem = 0);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QRectF boundingRect() const { return path.boundingRect(); }
void updatePath();
void updatePath(const QPointF &endPoint);
};
class ArrowDragItem : public ArrowItem {
Q_OBJECT
public:
ArrowDragItem(CardItem *_startItem);
protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
};
#endif // ARROWITEM_H

View file

@ -7,6 +7,7 @@
#include "tablezone.h"
#include "player.h"
#include "game.h"
#include "arrowitem.h"
CardItem::CardItem(CardDatabase *_db, const QString &_name, int _cardid, QGraphicsItem *parent)
: AbstractGraphicsItem(parent), db(_db), info(db->getCard(_name)), name(_name), id(_cardid), tapped(false), attacking(false), facedown(false), counters(0), doesntUntap(false), dragItem(NULL)
@ -193,46 +194,53 @@ void CardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
scene()->clearSelection();
setSelected(true);
}
if (event->button() == Qt::LeftButton) {
if (event->button() == Qt::LeftButton)
setCursor(Qt::ClosedHandCursor);
} else if (event->button() == Qt::RightButton) {
qgraphicsitem_cast<CardZone *>(parentItem())->getPlayer()->showCardMenu(event->screenPos());
}
event->accept();
}
void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < QApplication::startDragDistance())
return;
bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier) || facedown;
createDragItem(id, event->pos(), event->scenePos(), faceDown);
dragItem->grabMouse();
if (event->buttons().testFlag(Qt::RightButton)) {
if ((event->screenPos() - event->buttonDownScreenPos(Qt::RightButton)).manhattanLength() < 2 * QApplication::startDragDistance())
return;
ArrowDragItem *arrow = new ArrowDragItem(this);
scene()->addItem(arrow);
arrow->grabMouse();
} else {
if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < 2 * QApplication::startDragDistance())
return;
bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier) || facedown;
CardZone *zone = (CardZone *) parentItem();
QList<QGraphicsItem *> sel = scene()->selectedItems();
int j = 0;
for (int i = 0; i < sel.size(); i++) {
CardItem *c = (CardItem *) sel.at(i);
if (c == this)
continue;
++j;
QPointF childPos;
if (zone->getHasCardAttr())
childPos = c->pos() - pos();
else
childPos = QPointF(j * CARD_WIDTH / 2, 0);
CardDragItem *drag = new CardDragItem(c, c->getId(), childPos, false, dragItem);
drag->setPos(dragItem->pos() + childPos);
scene()->addItem(drag);
createDragItem(id, event->pos(), event->scenePos(), faceDown);
dragItem->grabMouse();
CardZone *zone = (CardZone *) parentItem();
QList<QGraphicsItem *> sel = scene()->selectedItems();
int j = 0;
for (int i = 0; i < sel.size(); i++) {
CardItem *c = (CardItem *) sel.at(i);
if (c == this)
continue;
++j;
QPointF childPos;
if (zone->getHasCardAttr())
childPos = c->pos() - pos();
else
childPos = QPointF(j * CARD_WIDTH / 2, 0);
CardDragItem *drag = new CardDragItem(c, c->getId(), childPos, false, dragItem);
drag->setPos(dragItem->pos() + childPos);
scene()->addItem(drag);
}
}
setCursor(Qt::OpenHandCursor);
}
void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent */*event*/)
void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::RightButton)
qgraphicsitem_cast<CardZone *>(parentItem())->getPlayer()->showCardMenu(event->screenPos());
setCursor(Qt::OpenHandCursor);
}

View file

@ -22,6 +22,7 @@ ServerEventData::ServerEventData(const QString &line)
eventHash.insert("draw", eventDraw);
eventHash.insert("move_card", eventMoveCard);
eventHash.insert("create_token", eventCreateToken);
eventHash.insert("create_arrow", eventCreateArrow);
eventHash.insert("set_card_attr", eventSetCardAttr);
eventHash.insert("add_counter", eventAddCounter);
eventHash.insert("set_counter", eventSetCounter);
@ -497,6 +498,11 @@ 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)
{
return cmd(QString("create_arrow|%1|%2|%3|%4|%5|%6").arg(startPlayerId).arg(startZone).arg(startCardId).arg(targetPlayerId).arg(targetPlayerZone).arg(targetCardId));
}
PendingCommand *Client::setCardAttr(const QString &zone, int cardid, const QString &aname, const QString &avalue)
{
return cmd(QString("set_card_attr|%1|%2|%3|%4").arg(zone).arg(cardid).arg(aname).arg(avalue));

View file

@ -44,6 +44,7 @@ enum ServerEventType {
eventDraw,
eventMoveCard,
eventCreateToken,
eventCreateArrow,
eventSetCardAttr,
eventAddCounter,
eventSetCounter,
@ -325,7 +326,7 @@ private slots:
void enterGameResponse(ServerResponse response);
void leaveGameResponse(ServerResponse response);
private:
static const int protocolVersion = 1;
static const int protocolVersion = 2;
static const int maxTimeout = 10;
QTimer *timer;
@ -363,6 +364,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 *setCardAttr(const QString &zone, int cardid, const QString &aname, const QString &avalue);
PendingCommand *readyStart();
PendingCommand *incCounter(int counterId, int delta);

View file

@ -12,6 +12,7 @@
#include "counter.h"
#include "gamescene.h"
#include "player.h"
#include "arrowitem.h"
Game::Game(CardDatabase *_db, Client *_client, GameScene *_scene, QMenuBar *menuBar, QObject *parent)
: QObject(parent), db(_db), client(_client), scene(_scene), started(false), currentPhase(-1)
@ -320,7 +321,26 @@ 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 eventCreateToken:
case eventSetupZones:
case eventSetCardAttr:

View file

@ -91,6 +91,7 @@ signals:
void logDraw(Player *player, int number);
void logMoveCard(Player *player, QString cardName, CardZone *startZone, int oldX, CardZone *targetZone, int newX);
void logCreateToken(Player *player, QString cardName);
void logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard);
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);

View file

@ -189,6 +189,17 @@ void MessageLogWidget::logCreateToken(Player *player, QString cardName)
append(tr("%1 creates token: %2.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))));
}
void MessageLogWidget::logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard)
{
append(tr("%1 points from %2's %3 to %4's %5.")
.arg(sanitizeHtml(player->getName()))
.arg(sanitizeHtml(startPlayer->getName()))
.arg(sanitizeHtml(startCard))
.arg(sanitizeHtml(targetPlayer->getName()))
.arg(sanitizeHtml(targetCard))
);
}
void MessageLogWidget::logSetCardCounters(Player *player, QString cardName, int value, int oldValue)
{
QString finalStr;
@ -280,6 +291,7 @@ void MessageLogWidget::connectToGame(Game *game)
connect(game, SIGNAL(logDraw(Player *, int)), this, SLOT(logDraw(Player *, int)));
connect(game, SIGNAL(logMoveCard(Player *, QString, CardZone *, int, CardZone *, int)), this, SLOT(logMoveCard(Player *, QString, CardZone *, int, CardZone *, int)));
connect(game, SIGNAL(logCreateToken(Player *, QString)), this, SLOT(logCreateToken(Player *, QString)));
connect(game, SIGNAL(logCreateArrow(Player *, Player *, QString, Player *, QString)), this, SLOT(logCreateArrow(Player *, Player *, QString, Player *, QString)));
connect(game, SIGNAL(logSetCardCounters(Player *, QString, int, int)), this, SLOT(logSetCardCounters(Player *, QString, int, int)));
connect(game, SIGNAL(logSetTapped(Player *, QString, bool)), this, SLOT(logSetTapped(Player *, QString, bool)));
connect(game, SIGNAL(logSetCounter(Player *, QString, int, int)), this, SLOT(logSetCounter(Player *, QString, int, int)));

View file

@ -38,6 +38,7 @@ private slots:
void logDraw(Player *player, int number);
void logMoveCard(Player *player, QString cardName, CardZone *startZone, int oldX, CardZone *targetZone, int newX);
void logCreateToken(Player *player, QString cardName);
void logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard);
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);

View file

@ -55,8 +55,7 @@ void PingWidget::paintEvent(QPaintEvent */*event*/)
QRadialGradient g(QPointF((double) width() / 2, (double) height() / 2), qMin(width(), height()) / 2.0);
g.setColorAt(0, color);
g.setColorAt(1, Qt::transparent);
painter.setBrush(QBrush(g));
painter.setPen(Qt::black);
painter.fillRect(0, 0, width(), height(), QBrush(g));
}
void PingWidget::setPercentage(int value, int max)

View file

@ -83,6 +83,13 @@ ServerSocket::ServerSocket(Server *_server, QObject *parent)
<< QVariant::String
<< QVariant::Int
<< QVariant::Int, &ServerSocket::cmdCreateToken));
commandHash.insert("create_arrow", CommandProperties(true, true, true, false, QList<QVariant::Type>()
<< QVariant::Int
<< QVariant::String
<< QVariant::Int
<< QVariant::Int
<< QVariant::String
<< QVariant::Int, &ServerSocket::cmdCreateArrow));
commandHash.insert("set_card_attr", CommandProperties(true, true, true, false, QList<QVariant::Type>()
<< QVariant::String
<< QVariant::Int
@ -562,6 +569,32 @@ ReturnMessage::ReturnCode ServerSocket::cmdCreateToken(const QList<QVariant> &pa
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdCreateArrow(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);
if (!startCard || !targetCard)
return ReturnMessage::ReturnContextError;
emit broadcastEvent(QString("create_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
);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdSetCardAttr(const QList<QVariant> &params)
{
// zone, card id, attr name, attr value

View file

@ -90,6 +90,7 @@ private:
ReturnMessage::ReturnCode cmdRevealCard(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdMoveCard(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdCreateToken(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdCreateArrow(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdSetCardAttr(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdIncCounter(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdAddCounter(const QList<QVariant> &params);

View file

@ -18,5 +18,5 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
static const int PROTOCOL_VERSION = 1;
static const char *VERSION_STRING = "Servatrice 0.20090928";
static const int PROTOCOL_VERSION = 2;
static const char *VERSION_STRING = "Servatrice 0.20091017";