mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-25 16:13:54 -07:00
initial commit
This commit is contained in:
commit
a11f93df4d
99 changed files with 7493 additions and 0 deletions
203
cockatrice/src/carddatabase.cpp
Normal file
203
cockatrice/src/carddatabase.cpp
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
#include "carddatabase.h"
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
CardInfo::CardInfo(const QString &_name, const QString &_manacost, const QString &_cardtype, const QString &_powtough, const QStringList &_text)
|
||||
: name(_name), manacost(_manacost), cardtype(_cardtype), powtough(_powtough), text(_text), pixmap(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CardInfo::CardInfo(QDataStream &stream)
|
||||
: pixmap(NULL)
|
||||
{
|
||||
stream >> name
|
||||
>> editions
|
||||
>> manacost
|
||||
>> cardtype
|
||||
>> powtough
|
||||
>> text;
|
||||
}
|
||||
|
||||
CardInfo::~CardInfo()
|
||||
{
|
||||
if (pixmap)
|
||||
qDebug(QString("Deleting pixmap for %1").arg(name).toLatin1());
|
||||
delete pixmap;
|
||||
}
|
||||
|
||||
void CardInfo::addEdition(const QString &edition)
|
||||
{
|
||||
if (!editions.contains(edition))
|
||||
editions << edition;
|
||||
}
|
||||
|
||||
QPixmap *CardInfo::getPixmap()
|
||||
{
|
||||
if (pixmap)
|
||||
return pixmap;
|
||||
pixmap = new QPixmap();
|
||||
if (getName().isEmpty()) {
|
||||
pixmap->load("../pics/back.jpg");
|
||||
return pixmap;
|
||||
}
|
||||
qDebug(QString("CardDatabase: loading pixmap for %1").arg(getName()).toLatin1());
|
||||
for (int i = 0; i < editions.size(); i++) {
|
||||
/* Fire // Ice */
|
||||
if (pixmap->load(QString("../pics/%1/%2.full.jpg").arg(editions.at(i)).arg(getName().replace(" // ", ""))))
|
||||
return pixmap;
|
||||
if (pixmap->load(QString("../pics/%1/%2%3.full.jpg").arg(editions.at(i)).arg(getName().replace(" // ", "")).arg(1)))
|
||||
return pixmap;
|
||||
}
|
||||
pixmap->load("../pics/none.jpg");
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
void CardInfo::saveToStream(QDataStream &stream)
|
||||
{
|
||||
stream << name
|
||||
<< editions
|
||||
<< manacost
|
||||
<< cardtype
|
||||
<< powtough
|
||||
<< text;
|
||||
}
|
||||
|
||||
CardDatabase::CardDatabase()
|
||||
{
|
||||
}
|
||||
|
||||
CardDatabase::~CardDatabase()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void CardDatabase::clear()
|
||||
{
|
||||
QHashIterator<QString, CardInfo *> i(hash);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
delete i.value();
|
||||
}
|
||||
hash.clear();
|
||||
}
|
||||
|
||||
CardInfo *CardDatabase::getCard(const QString &cardName)
|
||||
{
|
||||
if (hash.contains(cardName))
|
||||
return hash.value(cardName);
|
||||
else {
|
||||
qDebug(QString("CardDatabase: card not found: %1").arg(cardName).toLatin1());
|
||||
CardInfo *newCard = new CardInfo(cardName);
|
||||
newCard->addEdition("TK");
|
||||
hash.insert(cardName, newCard);
|
||||
return newCard;
|
||||
}
|
||||
}
|
||||
|
||||
void CardDatabase::importOracle()
|
||||
{
|
||||
clear();
|
||||
QDir dir("../db");
|
||||
|
||||
// XXX User soll selber auswählen können, welche Karten ihm am besten gefallen.
|
||||
// XXX Muss momentan schmutzig über Zahlen vor den Dateinamen gemacht werden.
|
||||
|
||||
dir.setSorting(QDir::Name | QDir::IgnoreCase);
|
||||
QFileInfoList files = dir.entryInfoList(QStringList() << "*.txt");
|
||||
for (int k = 0; k < files.size(); k++) {
|
||||
QFileInfo i = files[k];
|
||||
QString edition = i.fileName().mid(i.fileName().indexOf('_') + 1);
|
||||
edition = edition.left(edition.indexOf('.'));
|
||||
QFile file(i.filePath());
|
||||
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
QTextStream in(&file);
|
||||
while (!in.atEnd()) {
|
||||
QString cardname = in.readLine();
|
||||
QString manacost = in.readLine();
|
||||
QString cardtype, powtough;
|
||||
QStringList text;
|
||||
if (manacost.contains("Land", Qt::CaseInsensitive)) {
|
||||
cardtype = manacost;
|
||||
manacost.clear();
|
||||
} else {
|
||||
cardtype = in.readLine();
|
||||
powtough = in.readLine();
|
||||
// Dirty hack.
|
||||
// Cards to test: Any creature, any basic land, Ancestral Vision, Fire // Ice.
|
||||
if (!powtough.contains("/") || powtough.size() > 5) {
|
||||
text << powtough;
|
||||
powtough = QString();
|
||||
}
|
||||
}
|
||||
QString line = in.readLine();
|
||||
while (!line.isEmpty()) {
|
||||
text << line;
|
||||
line = in.readLine();
|
||||
}
|
||||
CardInfo *card;
|
||||
if (hash.contains(cardname))
|
||||
card = hash.value(cardname);
|
||||
else {
|
||||
card = new CardInfo(cardname, manacost, cardtype, powtough, text);
|
||||
hash.insert(cardname, card);
|
||||
}
|
||||
card->addEdition(edition);
|
||||
}
|
||||
}
|
||||
|
||||
qDebug(QString("CardDatabase: %1 cards imported").arg(hash.size()).toLatin1());
|
||||
|
||||
CardInfo *empty = new CardInfo();
|
||||
empty->getPixmap(); // cache pixmap for card back
|
||||
hash.insert("", empty);
|
||||
}
|
||||
|
||||
int CardDatabase::loadFromFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
file.open(QIODevice::ReadOnly);
|
||||
QDataStream in(&file);
|
||||
in.setVersion(QDataStream::Qt_4_4);
|
||||
|
||||
quint32 _magicNumber, _fileVersion, cardCount;
|
||||
in >> _magicNumber
|
||||
>> _fileVersion
|
||||
>> cardCount;
|
||||
|
||||
if (_magicNumber != magicNumber)
|
||||
return -1;
|
||||
if (_fileVersion != fileVersion)
|
||||
return -2;
|
||||
|
||||
clear();
|
||||
hash.reserve(cardCount);
|
||||
for (unsigned int i = 0; i < cardCount; i++) {
|
||||
CardInfo *newCard = new CardInfo(in);
|
||||
hash.insert(newCard->getName(), newCard);
|
||||
}
|
||||
|
||||
return cardCount;
|
||||
}
|
||||
|
||||
bool CardDatabase::saveToFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
QDataStream out(&file);
|
||||
out.setVersion(QDataStream::Qt_4_4);
|
||||
|
||||
out << (quint32) magicNumber
|
||||
<< (quint32) fileVersion
|
||||
<< (quint32) hash.size();
|
||||
|
||||
QHashIterator<QString, CardInfo *> i(hash);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
i.value()->saveToStream(out);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
51
cockatrice/src/carddatabase.h
Normal file
51
cockatrice/src/carddatabase.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef CARDDATABASE_H
|
||||
#define CARDDATABASE_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QPixmap>
|
||||
#include <QDataStream>
|
||||
|
||||
class CardInfo {
|
||||
private:
|
||||
QString name;
|
||||
QStringList editions;
|
||||
QString manacost;
|
||||
QString cardtype;
|
||||
QString powtough;
|
||||
QStringList text;
|
||||
QPixmap *pixmap;
|
||||
public:
|
||||
CardInfo(const QString &_name = QString(),
|
||||
const QString &_manacost = QString(),
|
||||
const QString &_cardtype = QString(),
|
||||
const QString &_powtough = QString(),
|
||||
const QStringList &_text = QStringList());
|
||||
CardInfo(QDataStream &stream);
|
||||
~CardInfo();
|
||||
QString getName() const { return name; }
|
||||
QStringList getEditions() const { return editions; }
|
||||
QString getManacost() const { return manacost; }
|
||||
QString getCardType() const { return cardtype; }
|
||||
QString getPowTough() const { return powtough; }
|
||||
QStringList getText() const { return text; }
|
||||
void addEdition(const QString &edition);
|
||||
QPixmap *getPixmap();
|
||||
void saveToStream(QDataStream &stream);
|
||||
};
|
||||
|
||||
class CardDatabase {
|
||||
private:
|
||||
QHash<QString, CardInfo *> hash;
|
||||
static const unsigned int magicNumber = 0x12345678;
|
||||
static const unsigned int fileVersion = 1;
|
||||
public:
|
||||
CardDatabase();
|
||||
~CardDatabase();
|
||||
void clear();
|
||||
CardInfo *getCard(const QString &cardName = QString());
|
||||
void importOracle();
|
||||
int loadFromFile(const QString &fileName);
|
||||
bool saveToFile(const QString &fileName);
|
||||
};
|
||||
|
||||
#endif
|
||||
97
cockatrice/src/carddragitem.cpp
Normal file
97
cockatrice/src/carddragitem.cpp
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
#include "carddragitem.h"
|
||||
#include "playerzone.h"
|
||||
#include <QtGui>
|
||||
|
||||
CardDragItem::CardDragItem(QGraphicsScene *scene, PlayerZone *_startZone, QPixmap *_image, int _id, const QPointF &_hotSpot, QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent), image(_image), id(_id), hotSpot(_hotSpot), startZone(_startZone)
|
||||
{
|
||||
if ((hotSpot.x() < 0) || (hotSpot.y() < 0)) {
|
||||
qDebug(QString("CardDragItem: coordinate overflow: x = %1, y = %2").arg(hotSpot.x()).arg(hotSpot.y()).toLatin1());
|
||||
hotSpot = QPointF();
|
||||
} else if ((hotSpot.x() > CARD_WIDTH) || (hotSpot.y() > CARD_HEIGHT)) {
|
||||
qDebug(QString("CardDragItem: coordinate overflow: x = %1, y = %2").arg(hotSpot.x()).arg(hotSpot.y()).toLatin1());
|
||||
hotSpot = QPointF(CARD_WIDTH, CARD_HEIGHT);
|
||||
}
|
||||
|
||||
setZValue(2000000000);
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
|
||||
scene->addItem(this);
|
||||
}
|
||||
|
||||
CardDragItem::~CardDragItem()
|
||||
{
|
||||
qDebug("CardDragItem destructor");
|
||||
}
|
||||
|
||||
QRectF CardDragItem::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||
}
|
||||
|
||||
void CardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
// Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
|
||||
QRectF foo = option->matrix.mapRect(boundingRect());
|
||||
QPixmap bar = image->scaled(foo.width(), foo.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
painter->drawPixmap(boundingRect(), bar, bar.rect());
|
||||
|
||||
// painter->drawPixmap(boundingRect(), *image, QRectF(0, 0, image->width(), image->height()));
|
||||
}
|
||||
|
||||
void CardDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
QPointF sp = event->scenePos();
|
||||
QList<QGraphicsItem *> colliding = scene()->items(sp);
|
||||
|
||||
PlayerZone *cursorZone = 0;
|
||||
for (int i = colliding.size() - 1; i >= 0; i--) {
|
||||
if ((cursorZone = qgraphicsitem_cast<PlayerZone *>(colliding.at(i)))) {
|
||||
if (cursorZone->getName() == "table") {
|
||||
QPointF cp = cursorZone->scenePos();
|
||||
QPointF localpos = sp - hotSpot - cp;
|
||||
setPos(QPointF(round(localpos.x() / RASTER_WIDTH) * RASTER_WIDTH, round(localpos.y() / RASTER_HEIGHT) * RASTER_HEIGHT) + cp);
|
||||
} else
|
||||
setPos(sp - hotSpot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
QGraphicsScene *sc = scene();
|
||||
QPointF sp = scenePos();
|
||||
sc->removeItem(this);
|
||||
QList<QGraphicsItem *> colliding = sc->items(event->scenePos());
|
||||
|
||||
qDebug(QString("drop: %1 collisions").arg(colliding.size()).toLatin1());
|
||||
PlayerZone *dropZone = 0;
|
||||
for (int i = colliding.size() - 1; i >= 0; i--) {
|
||||
QRectF bbox = colliding.at(i)->boundingRect();
|
||||
qDebug(QString("bbox x %1 y %2 w %3 h %4").arg(bbox.x()).arg(bbox.y()).arg(bbox.width()).arg(bbox.height()).toLatin1());
|
||||
|
||||
if ((dropZone = qgraphicsitem_cast<PlayerZone *>(colliding.at(i)))) {
|
||||
qDebug("zone found");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dropZone) {
|
||||
dropZone->handleDropEvent(id, startZone, (sp - dropZone->pos()).toPoint());
|
||||
QList<QGraphicsItem *> childList = childItems();
|
||||
for (int i = 0; i < childList.size(); i++) {
|
||||
CardDragItem *c = qgraphicsitem_cast<CardDragItem *>(childList.at(i));
|
||||
if (!c)
|
||||
QMessageBox::critical(0, "fehler", "null");
|
||||
dropZone->handleDropEvent(c->id, startZone, (sp - dropZone->pos() + c->pos()).toPoint());
|
||||
}
|
||||
} else
|
||||
QMessageBox::critical(0, "fehler", "fehler");
|
||||
|
||||
event->accept();
|
||||
}
|
||||
28
cockatrice/src/carddragitem.h
Normal file
28
cockatrice/src/carddragitem.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef CARDDRAGITEM_H
|
||||
#define CARDDRAGITEM_H
|
||||
|
||||
#include "carditem.h"
|
||||
|
||||
class QGraphicsScene;
|
||||
class PlayerZone;
|
||||
|
||||
class CardDragItem : public QGraphicsItem {
|
||||
private:
|
||||
QPixmap *image;
|
||||
int id;
|
||||
QPointF hotSpot;
|
||||
PlayerZone *startZone;
|
||||
public:
|
||||
enum { Type = typeCardDrag };
|
||||
int type() const { return Type; }
|
||||
CardDragItem(QGraphicsScene *scene, PlayerZone *_startZone, QPixmap *_image, int _id, const QPointF &_hotSpot, QGraphicsItem *parent = 0);
|
||||
~CardDragItem();
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
QPointF getHotSpot() const { return hotSpot; }
|
||||
protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
};
|
||||
|
||||
#endif
|
||||
61
cockatrice/src/cardinfowidget.cpp
Normal file
61
cockatrice/src/cardinfowidget.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#include "cardinfowidget.h"
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QTextEdit>
|
||||
|
||||
CardInfoWidget::CardInfoWidget(CardDatabase *_db, QWidget *parent)
|
||||
: QFrame(parent), db(_db), aspectratio(0)
|
||||
{
|
||||
cardPicture = new QLabel();
|
||||
cardPicture->setAlignment(Qt::AlignCenter);
|
||||
|
||||
nameLabel1 = new QLabel(tr("Name:"));
|
||||
nameLabel2 = new QLabel();
|
||||
manacostLabel1 = new QLabel(tr("Mana cost:"));
|
||||
manacostLabel2 = new QLabel();
|
||||
cardtypeLabel1 = new QLabel(tr("Card type:"));
|
||||
cardtypeLabel2 = new QLabel();
|
||||
powtoughLabel1 = new QLabel(tr("P / T:"));
|
||||
powtoughLabel2 = new QLabel();
|
||||
|
||||
textLabel = new QTextEdit();
|
||||
textLabel->setReadOnly(true);
|
||||
|
||||
QGridLayout *grid = new QGridLayout(this);
|
||||
grid->addWidget(cardPicture, 0, 0, 1, 2);
|
||||
grid->addWidget(nameLabel1, 1, 0);
|
||||
grid->addWidget(nameLabel2, 1, 1);
|
||||
grid->addWidget(manacostLabel1, 2, 0);
|
||||
grid->addWidget(manacostLabel2, 2, 1);
|
||||
grid->addWidget(cardtypeLabel1, 3, 0);
|
||||
grid->addWidget(cardtypeLabel2, 3, 1);
|
||||
grid->addWidget(powtoughLabel1, 4, 0);
|
||||
grid->addWidget(powtoughLabel2, 4, 1);
|
||||
grid->addWidget(textLabel, 5, 0, -1, 2);
|
||||
grid->setRowStretch(5, 1);
|
||||
|
||||
setFrameStyle(QFrame::Panel | QFrame::Raised);
|
||||
}
|
||||
|
||||
void CardInfoWidget::setCard(CardInfo *card)
|
||||
{
|
||||
if (!card)
|
||||
return;
|
||||
|
||||
QPixmap *pixmap = card->getPixmap();
|
||||
if (aspectratio == 0)
|
||||
aspectratio = (double) pixmap->height() / pixmap->width();
|
||||
double w = width() * 2.0 / 3.0;
|
||||
cardPicture->setPixmap(pixmap->scaled((int) w, (int) (w * aspectratio), Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
|
||||
nameLabel2->setText(card->getName());
|
||||
manacostLabel2->setText(card->getManacost());
|
||||
cardtypeLabel2->setText(card->getCardType());
|
||||
powtoughLabel2->setText(card->getPowTough());
|
||||
textLabel->setText(card->getText().join("\n"));
|
||||
}
|
||||
|
||||
void CardInfoWidget::setCard(const QString &cardName)
|
||||
{
|
||||
setCard(db->getCard(cardName));
|
||||
}
|
||||
29
cockatrice/src/cardinfowidget.h
Normal file
29
cockatrice/src/cardinfowidget.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef CARDINFOWIDGET_H
|
||||
#define CARDINFOWIDGET_H
|
||||
|
||||
#include "carddatabase.h"
|
||||
#include <QFrame>
|
||||
|
||||
class QLabel;
|
||||
class QTextEdit;
|
||||
|
||||
class CardInfoWidget : public QFrame {
|
||||
Q_OBJECT
|
||||
private:
|
||||
CardDatabase *db;
|
||||
double aspectratio;
|
||||
|
||||
QLabel *cardPicture;
|
||||
QLabel *nameLabel1, *nameLabel2;
|
||||
QLabel *manacostLabel1, *manacostLabel2;
|
||||
QLabel *cardtypeLabel1, *cardtypeLabel2;
|
||||
QLabel *powtoughLabel1, *powtoughLabel2;
|
||||
QTextEdit *textLabel;
|
||||
public:
|
||||
CardInfoWidget(CardDatabase *_db, QWidget *parent = 0);
|
||||
public slots:
|
||||
void setCard(CardInfo *card);
|
||||
void setCard(const QString &cardName);
|
||||
};
|
||||
|
||||
#endif
|
||||
202
cockatrice/src/carditem.cpp
Normal file
202
cockatrice/src/carditem.cpp
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
#include <QApplication>
|
||||
#include <QtGui>
|
||||
#include "carditem.h"
|
||||
#include "carddragitem.h"
|
||||
#include "carddatabase.h"
|
||||
#include "playerzone.h"
|
||||
#include "tablezone.h"
|
||||
#include "player.h"
|
||||
|
||||
CardItem::CardItem(CardDatabase *_db, const QString &_name, int _cardid, QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent), db(_db), name(_name), id(_cardid), tapped(false), attacking(false), facedown(false), counters(0), dragItem(NULL)
|
||||
{
|
||||
width = CARD_WIDTH;
|
||||
height = CARD_HEIGHT;
|
||||
image = db->getCard(name)->getPixmap();
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
setFlag(ItemIsSelectable);
|
||||
setAcceptsHoverEvents(true);
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
}
|
||||
|
||||
CardItem::~CardItem()
|
||||
{
|
||||
qDebug(QString("CardItem destructor: %1").arg(name).toLatin1());
|
||||
}
|
||||
|
||||
QRectF CardItem::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, width, height);
|
||||
}
|
||||
|
||||
void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
|
||||
painter->save();
|
||||
QRectF foo = option->matrix.mapRect(boundingRect());
|
||||
qDebug(QString("%1: w=%2,h=%3").arg(name).arg(foo.width()).arg(foo.height()).toLatin1());
|
||||
QPixmap bar = image->scaled((int) foo.width(), (int) foo.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
// painter->drawPixmap(boundingRect(), *image, QRectF(0, 0, image->width(), image->height()));
|
||||
painter->drawPixmap(boundingRect(), bar, bar.rect());
|
||||
if (isSelected()) {
|
||||
painter->setPen(QPen(QColor("red")));
|
||||
painter->drawRect(QRectF(1, 1, width - 2, height - 2));
|
||||
}
|
||||
if (counters) {
|
||||
painter->setFont(QFont("Times", 32, QFont::Bold));
|
||||
painter->setPen(QPen(QColor("black")));
|
||||
painter->setBackground(QBrush(QColor(255, 255, 255, 100)));
|
||||
painter->setBackgroundMode(Qt::OpaqueMode);
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(counters));
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void CardItem::setName(const QString &_name)
|
||||
{
|
||||
name = _name;
|
||||
image = db->getCard(name)->getPixmap();
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::setTapped(bool _tapped)
|
||||
{
|
||||
tapped = _tapped;
|
||||
if (tapped)
|
||||
setTransform(QTransform().translate((float) width / 2, (float) height / 2).rotate(90).translate((float) -width / 2, (float) -height / 2));
|
||||
else
|
||||
setTransform(QTransform());
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::setAttacking(bool _attacking)
|
||||
{
|
||||
attacking = _attacking;
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::setFacedown(bool _facedown)
|
||||
{
|
||||
facedown = _facedown;
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::setCounters(int _counters)
|
||||
{
|
||||
counters = _counters;
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::setAnnotation(const QString &_annotation)
|
||||
{
|
||||
annotation = _annotation;
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void CardItem::resetState()
|
||||
{
|
||||
attacking = false;
|
||||
facedown = false;
|
||||
counters = 0;
|
||||
annotation = QString();
|
||||
setTapped(false);
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
CardDragItem *CardItem::createDragItem(PlayerZone *startZone, int _id, const QPointF &_pos, const QPointF &_scenePos)
|
||||
{
|
||||
dragItem = new CardDragItem(scene(), startZone, image, _id, _pos);
|
||||
dragItem->setPos(_scenePos - dragItem->getHotSpot());
|
||||
|
||||
return dragItem;
|
||||
}
|
||||
|
||||
void CardItem::deleteDragItem()
|
||||
{
|
||||
delete dragItem;
|
||||
dragItem = NULL;
|
||||
}
|
||||
|
||||
void CardItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (!isSelected()) {
|
||||
scene()->clearSelection();
|
||||
setSelected(true);
|
||||
}
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
qgraphicsitem_cast<PlayerZone *>(parentItem())->getPlayer()->showCardMenu(event->screenPos());
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < QApplication::startDragDistance())
|
||||
return;
|
||||
|
||||
createDragItem((PlayerZone *) parentItem(), id, event->pos(), event->scenePos());
|
||||
dragItem->grabMouse();
|
||||
|
||||
QList<QGraphicsItem *> sel = scene()->selectedItems();
|
||||
for (int i = 0; i < sel.size(); i++) {
|
||||
CardItem *c = (CardItem *) sel.at(i);
|
||||
if (c == this)
|
||||
continue;
|
||||
CardDragItem *drag = new CardDragItem(scene(), (PlayerZone *) parentItem(), c->getImage(), c->getId(), QPointF(), dragItem);
|
||||
drag->setPos(c->pos() - pos());
|
||||
}
|
||||
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
void CardItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
if (!isSelected()) {
|
||||
// Unselect all items, then select this one
|
||||
scene()->setSelectionArea(QPainterPath());
|
||||
setSelected(true);
|
||||
}
|
||||
event->accept();
|
||||
|
||||
PlayerZone *zone = (PlayerZone *) parentItem();
|
||||
// Do nothing if the card belongs to another player
|
||||
if (!zone->getPlayer()->getLocal())
|
||||
return;
|
||||
|
||||
if (zone->getHasCardAttr())
|
||||
((TableZone *) zone)->toggleTapped();
|
||||
}
|
||||
|
||||
void CardItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
((PlayerZone *) parentItem())->hoverCardEvent(this);
|
||||
QGraphicsItem::hoverEnterEvent(event);
|
||||
}
|
||||
|
||||
void CardItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
QGraphicsItem::hoverLeaveEvent(event);
|
||||
}
|
||||
|
||||
QVariant CardItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == ItemSelectedChange) {
|
||||
// XXX
|
||||
return value;
|
||||
} else if (change == ItemSelectedHasChanged) {
|
||||
update();
|
||||
return value;
|
||||
} else
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
81
cockatrice/src/carditem.h
Normal file
81
cockatrice/src/carditem.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#ifndef CARDITEM_H
|
||||
#define CARDITEM_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
class CardDatabase;
|
||||
class CardDragItem;
|
||||
class PlayerZone;
|
||||
|
||||
|
||||
const int CARD_WIDTH = 72;
|
||||
const int CARD_HEIGHT = 102;
|
||||
const int RASTER_WIDTH = 36;
|
||||
const int RASTER_HEIGHT = 34;
|
||||
|
||||
/*
|
||||
const int CARD_WIDTH = 72;
|
||||
const int CARD_HEIGHT = 108;
|
||||
const int RASTER_WIDTH = 36;
|
||||
const int RASTER_HEIGHT = 36;
|
||||
*/
|
||||
|
||||
const int MAX_COUNTERS_ON_CARD = 999;
|
||||
|
||||
enum CardItemType {
|
||||
typeCard = QGraphicsItem::UserType + 1,
|
||||
typeCardDrag = QGraphicsItem::UserType + 2,
|
||||
typeZone = QGraphicsItem::UserType + 3,
|
||||
typeOther = QGraphicsItem::UserType + 4
|
||||
};
|
||||
|
||||
class CardItem : public QGraphicsItem {
|
||||
private:
|
||||
CardDatabase *db;
|
||||
QString name;
|
||||
int id;
|
||||
int width, height;
|
||||
QPixmap *image;
|
||||
bool tapped;
|
||||
bool attacking;
|
||||
bool facedown;
|
||||
int counters;
|
||||
QString annotation;
|
||||
CardDragItem *dragItem;
|
||||
public:
|
||||
enum { Type = typeCard };
|
||||
int type() const { return Type; }
|
||||
CardItem(CardDatabase *_db, const QString &_name, int _cardid, QGraphicsItem *parent = 0);
|
||||
~CardItem();
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
int getId() const { return id; }
|
||||
void setId(int _id) { id = _id; }
|
||||
QString getName() const { return name; }
|
||||
void setName(const QString &_name = QString());
|
||||
QPixmap *getImage() const { return image; }
|
||||
bool getTapped() const { return tapped; }
|
||||
void setTapped(bool _tapped);
|
||||
bool getAttacking() const { return attacking; }
|
||||
void setAttacking(bool _attacking);
|
||||
bool getFacedown() const { return facedown; }
|
||||
void setFacedown(bool _facedown);
|
||||
int getCounters() const { return counters; }
|
||||
void setCounters(int _counters);
|
||||
QString getAnnotation() const { return annotation; }
|
||||
void setAnnotation(const QString &_annotation);
|
||||
void resetState();
|
||||
|
||||
CardDragItem *createDragItem(PlayerZone *startZone, int _id, const QPointF &_pos, const QPointF &_scenePos);
|
||||
void deleteDragItem();
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
|
||||
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);
|
||||
};
|
||||
|
||||
#endif
|
||||
31
cockatrice/src/cardlist.cpp
Normal file
31
cockatrice/src/cardlist.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#include "cardlist.h"
|
||||
|
||||
CardList::CardList(bool _contentsKnown)
|
||||
: QList<CardItem *>(), contentsKnown(_contentsKnown)
|
||||
{
|
||||
}
|
||||
|
||||
CardItem *CardList::findCard(const int id, const bool remove, int *position)
|
||||
{
|
||||
if (!contentsKnown) {
|
||||
if (empty())
|
||||
return 0;
|
||||
CardItem *temp = at(0);
|
||||
if (remove)
|
||||
removeAt(0);
|
||||
if (position)
|
||||
*position = id;
|
||||
return temp;
|
||||
} else
|
||||
for (int i = 0; i < size(); i++) {
|
||||
CardItem *temp = at(i);
|
||||
if (temp->getId() == id) {
|
||||
if (remove)
|
||||
removeAt(i);
|
||||
if (position)
|
||||
*position = i;
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
16
cockatrice/src/cardlist.h
Normal file
16
cockatrice/src/cardlist.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef CARDLIST_H
|
||||
#define CARDLIST_H
|
||||
|
||||
#include "carditem.h"
|
||||
#include <QList>
|
||||
|
||||
class CardList : public QList<CardItem *> {
|
||||
protected:
|
||||
bool contentsKnown;
|
||||
public:
|
||||
CardList(bool _contentsKnown);
|
||||
CardItem *findCard(const int id, const bool remove, int *position = NULL);
|
||||
bool getContentsKnown() const { return contentsKnown; }
|
||||
};
|
||||
|
||||
#endif
|
||||
322
cockatrice/src/client.cpp
Normal file
322
cockatrice/src/client.cpp
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
#include <QTimer>
|
||||
#include "client.h"
|
||||
|
||||
Client::Client(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
timer = new QTimer(this);
|
||||
timer->setInterval(1000);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(checkTimeout()));
|
||||
|
||||
MsgId = 0;
|
||||
status = StatusDisconnected;
|
||||
socket = new QTcpSocket(this);
|
||||
socket->setTextModeEnabled(true);
|
||||
connect(socket, SIGNAL(connected()), this, SLOT(slotConnected()));
|
||||
connect(socket, SIGNAL(readyRead()), this, SLOT(readLine()));
|
||||
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotSocketError(QAbstractSocket::SocketError)));
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
{
|
||||
delete socket;
|
||||
}
|
||||
|
||||
void Client::checkTimeout()
|
||||
{
|
||||
QListIterator<PendingCommand *> i(PendingCommands);
|
||||
while (i.hasNext()) {
|
||||
PendingCommand *c = i.next();
|
||||
c->incTime();
|
||||
if (c->timeout()) {
|
||||
disconnectFromServer();
|
||||
emit serverTimeout();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::slotSocketError(QAbstractSocket::SocketError error)
|
||||
{
|
||||
emit logSocketError(socket->errorString());
|
||||
disconnectFromServer();
|
||||
}
|
||||
|
||||
void Client::slotConnected()
|
||||
{
|
||||
timer->start();
|
||||
setStatus(StatusAwaitingWelcome);
|
||||
}
|
||||
|
||||
void Client::readLine()
|
||||
{
|
||||
QString line;
|
||||
for (;;) {
|
||||
if (!socket->canReadLine())
|
||||
break;
|
||||
line = QString(socket->readLine()).trimmed();
|
||||
|
||||
if (line.isNull())
|
||||
break;
|
||||
qDebug(QString("readLine: %1").arg(line).toLatin1());
|
||||
QStringList values = line.split("|");
|
||||
QString prefix = values.takeFirst();
|
||||
// prefix is one of {welcome, private, public, resp, list_games, list_players, list_counters, list_zones, dump_zone}
|
||||
if (!(prefix.compare("private") && prefix.compare("public"))) {
|
||||
ServerEventData *event = new ServerEventData(line);
|
||||
if (event->getEventType() == eventPlayerId) {
|
||||
QStringList data = event->getEventData();
|
||||
if (data.size() != 2) {
|
||||
// XXX
|
||||
}
|
||||
bool ok;
|
||||
int id = data[0].toInt(&ok);
|
||||
if (!ok) {
|
||||
// XXX
|
||||
}
|
||||
delete event;
|
||||
emit playerIdReceived(id, data[1]);
|
||||
} else
|
||||
emit gameEvent(event);
|
||||
} else if (!prefix.compare("resp")) {
|
||||
bool ok;
|
||||
int msgid = values.takeFirst().toInt(&ok);
|
||||
if (!ok) {
|
||||
// XXX
|
||||
}
|
||||
|
||||
if (values.empty()) {
|
||||
// XXX
|
||||
}
|
||||
|
||||
ok = !values.takeFirst().compare("ok");
|
||||
|
||||
// XXX
|
||||
ServerErrorMessage message = msgNone;
|
||||
|
||||
// Update list of pending commands
|
||||
QListIterator<PendingCommand *> i(PendingCommands);
|
||||
bool found = false;
|
||||
PendingCommand *c;
|
||||
while (i.hasNext()) {
|
||||
c = i.next();
|
||||
if (c->getMsgId() == msgid) {
|
||||
found = true;
|
||||
|
||||
QString cmd = c->getCmd();
|
||||
if (cmd.startsWith("submit_deck"))
|
||||
readyStart();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
PendingCommands.removeAt(PendingCommands.indexOf(c));
|
||||
delete c;
|
||||
}
|
||||
|
||||
emit responseReceived(new ServerResponse(msgid, ok, message));
|
||||
} else if (!(prefix.compare("list_games")
|
||||
&& prefix.compare("list_players")
|
||||
&& prefix.compare("list_counters")
|
||||
&& prefix.compare("list_zones")
|
||||
&& prefix.compare("dump_zone")
|
||||
&& prefix.compare("welcome"))) {
|
||||
int cmdid = values.takeFirst().toInt();
|
||||
if (!values[0].compare(".")) {
|
||||
QListIterator<QStringList> i(msgbuf);
|
||||
QList<ServerGame *> gamelist;
|
||||
QList<ServerPlayer *> playerlist;
|
||||
QList<ServerZone *> zonelist;
|
||||
QList<ServerZoneCard *> zonedump;
|
||||
QStringList welcomemsg;
|
||||
while (i.hasNext()) {
|
||||
QStringList val = i.next();
|
||||
|
||||
// XXX Parametergültigkeit überprüfen
|
||||
if (!prefix.compare("list_games"))
|
||||
gamelist << new ServerGame(val[0], val[1], val[2].toInt(), val[3].toInt(), val[4].toInt());
|
||||
else if (!prefix.compare("list_players"))
|
||||
playerlist << new ServerPlayer(val[0].toInt(), val[1]);
|
||||
else if (!prefix.compare("list_counters"))
|
||||
{ }
|
||||
else if (!prefix.compare("list_zones"))
|
||||
zonelist << new ServerZone(val[0], val[1] == "1", val[2] == "1", val[3].toInt());
|
||||
else if (!prefix.compare("dump_zone"))
|
||||
zonedump << new ServerZoneCard(val[0].toInt(), val[1], val[2].toInt(), val[3].toInt(), val[4].toInt(), val[5] == "1", val[6]);
|
||||
else if (!prefix.compare("welcome"))
|
||||
welcomemsg << val[0];
|
||||
}
|
||||
if (!prefix.compare("list_games"))
|
||||
emit gameListReceived(gamelist);
|
||||
else if (!prefix.compare("list_players"))
|
||||
emit playerListReceived(playerlist);
|
||||
else if (!prefix.compare("list_counters"))
|
||||
{ }
|
||||
else if (!prefix.compare("list_zones"))
|
||||
emit zoneListReceived(cmdid, zonelist);
|
||||
else if (!prefix.compare("dump_zone"))
|
||||
emit zoneDumpReceived(cmdid, zonedump);
|
||||
else if (!prefix.compare("welcome")) {
|
||||
emit welcomeMsgReceived(welcomemsg);
|
||||
setStatus(StatusConnected);
|
||||
setName(PlayerName);
|
||||
}
|
||||
msgbuf.clear();
|
||||
} else
|
||||
msgbuf << values;
|
||||
} else {
|
||||
// XXX
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::setStatus(const ProtocolStatus _status)
|
||||
{
|
||||
status = _status;
|
||||
emit statusChanged(_status);
|
||||
}
|
||||
|
||||
void Client::msg(const QString &s)
|
||||
{
|
||||
qDebug(QString("msg gibt aus: %1").arg(s).toLatin1());
|
||||
QTextStream stream(socket);
|
||||
stream.setCodec("UTF-8");
|
||||
stream << s << endl;
|
||||
stream.flush();
|
||||
socket->flush();
|
||||
}
|
||||
|
||||
int Client::cmd(const QString &s)
|
||||
{
|
||||
msg(QString("%1|%2").arg(++MsgId).arg(s));
|
||||
PendingCommands << new PendingCommand(s, MsgId);
|
||||
return MsgId;
|
||||
}
|
||||
|
||||
void Client::connectToServer(const QString &hostname, unsigned int port, const QString &playername)
|
||||
{
|
||||
PlayerName = playername;
|
||||
socket->connectToHost(hostname, port);
|
||||
setStatus(StatusConnecting);
|
||||
}
|
||||
|
||||
void Client::disconnectFromServer()
|
||||
{
|
||||
timer->stop();
|
||||
PendingCommands.clear();
|
||||
setStatus(StatusDisconnected);
|
||||
socket->close();
|
||||
}
|
||||
|
||||
int Client::listGames()
|
||||
{
|
||||
return cmd("list_games");
|
||||
}
|
||||
|
||||
int Client::listPlayers()
|
||||
{
|
||||
return cmd("list_players");
|
||||
}
|
||||
|
||||
int Client::createGame(const QString &name, const QString &description, const QString &password, unsigned int maxPlayers)
|
||||
{
|
||||
return cmd(QString("create_game|%1|%2|%3|%4").arg(name).arg(description).arg(password).arg(maxPlayers));
|
||||
}
|
||||
|
||||
int Client::joinGame(const QString &name, const QString &password)
|
||||
{
|
||||
return cmd(QString("join_game|%1|%2").arg(name).arg(password));
|
||||
}
|
||||
|
||||
int Client::leaveGame()
|
||||
{
|
||||
return cmd("leave_game");
|
||||
}
|
||||
|
||||
int Client::setName(const QString &name)
|
||||
{
|
||||
return cmd(QString("set_name|%1").arg(name));
|
||||
}
|
||||
|
||||
int Client::say(const QString &s)
|
||||
{
|
||||
return cmd(QString("say|%1").arg(s));
|
||||
}
|
||||
|
||||
int Client::shuffle()
|
||||
{
|
||||
return cmd("shuffle");
|
||||
}
|
||||
|
||||
int Client::rollDice(unsigned int sides)
|
||||
{
|
||||
return cmd(QString("roll_dice|%1").arg(sides));
|
||||
}
|
||||
|
||||
int Client::drawCards(unsigned int number)
|
||||
{
|
||||
return cmd(QString("draw_cards|%1").arg(number));
|
||||
}
|
||||
|
||||
int Client::moveCard(int cardid, const QString &startzone, const QString &targetzone, int x, int y)
|
||||
{
|
||||
// if startzone is public: cardid is the card's id
|
||||
// else: cardid is the position of the card in the zone (e.g. deck)
|
||||
return cmd(QString("move_card|%1|%2|%3|%4|%5").arg(cardid).arg(startzone).arg(targetzone).arg(x).arg(y));
|
||||
}
|
||||
|
||||
int Client::createToken(const QString &zone, const QString &name, const QString &powtough, int x, int y)
|
||||
{
|
||||
return cmd(QString("create_token|%1|%2|%3|%4|%5").arg(zone).arg(name).arg(powtough).arg(x).arg(y));
|
||||
}
|
||||
|
||||
int 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));
|
||||
}
|
||||
|
||||
int Client::submitDeck(const QStringList &deck)
|
||||
{
|
||||
int retval = cmd("submit_deck");
|
||||
QStringListIterator i(deck);
|
||||
while (i.hasNext())
|
||||
msg(i.next());
|
||||
msg(".");
|
||||
return retval;
|
||||
}
|
||||
|
||||
int Client::readyStart()
|
||||
{
|
||||
return cmd("ready_start");
|
||||
}
|
||||
|
||||
int Client::incCounter(const QString &counter, int delta)
|
||||
{
|
||||
return cmd(QString("inc_counter|%1|%2").arg(counter).arg(delta));
|
||||
}
|
||||
|
||||
int Client::setCounter(const QString &counter, int value)
|
||||
{
|
||||
return cmd(QString("set_counter|%1|%2").arg(counter).arg(value));
|
||||
}
|
||||
|
||||
int Client::delCounter(const QString &counter)
|
||||
{
|
||||
return cmd(QString("del_counter|%1").arg(counter));
|
||||
}
|
||||
|
||||
int Client::setActivePlayer(int player)
|
||||
{
|
||||
return cmd(QString("set_active_player|%1").arg(player));
|
||||
}
|
||||
|
||||
int Client::setActivePhase(int phase)
|
||||
{
|
||||
return cmd(QString("set_active_phase|%1").arg(phase));
|
||||
}
|
||||
|
||||
int Client::dumpZone(int player, const QString &zone, int numberCards)
|
||||
{
|
||||
return cmd(QString("dump_zone|%1|%2|%3").arg(player).arg(zone).arg(numberCards));
|
||||
}
|
||||
86
cockatrice/src/client.h
Normal file
86
cockatrice/src/client.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#ifndef CLIENT_H
|
||||
#define CLIENT_H
|
||||
|
||||
#include "servereventdata.h"
|
||||
#include "serverresponse.h"
|
||||
#include "servergame.h"
|
||||
#include "serverplayer.h"
|
||||
#include "serverzone.h"
|
||||
#include "serverzonecard.h"
|
||||
#include "pendingcommand.h"
|
||||
#include <QTcpSocket>
|
||||
|
||||
class QTimer;
|
||||
|
||||
// Connection state.
|
||||
// The protocol handler itself is stateless once the connection
|
||||
// has been established.
|
||||
enum ProtocolStatus { StatusDisconnected,
|
||||
StatusConnecting,
|
||||
StatusAwaitingWelcome,
|
||||
StatusConnected };
|
||||
|
||||
class Client : public QObject {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void statusChanged(ProtocolStatus _status);
|
||||
void welcomeMsgReceived(QStringList welcomeMsg);
|
||||
void gameListReceived(QList<ServerGame *> games);
|
||||
void playerListReceived(QList<ServerPlayer *> players);
|
||||
void zoneListReceived(int commandId, QList<ServerZone *> zones);
|
||||
void zoneDumpReceived(int commandId, QList<ServerZoneCard *> cards);
|
||||
void responseReceived(ServerResponse *response);
|
||||
void playerIdReceived(int id, QString name);
|
||||
void gameEvent(ServerEventData *msg);
|
||||
void serverTimeout();
|
||||
void logSocketError(const QString &errorString);
|
||||
|
||||
private slots:
|
||||
void slotConnected();
|
||||
void readLine();
|
||||
void checkTimeout();
|
||||
void slotSocketError(QAbstractSocket::SocketError error);
|
||||
|
||||
private:
|
||||
QTimer *timer;
|
||||
QList<PendingCommand *> PendingCommands;
|
||||
QTcpSocket *socket;
|
||||
ProtocolStatus status;
|
||||
QList<QStringList> msgbuf;
|
||||
QString PlayerName;
|
||||
unsigned int MsgId;
|
||||
void msg(const QString &s);
|
||||
int cmd(const QString &s);
|
||||
void setStatus(const ProtocolStatus _status);
|
||||
public:
|
||||
Client(QObject *parent = 0);
|
||||
~Client();
|
||||
ProtocolStatus getStatus() { return status; }
|
||||
QString peerName() const { return socket->peerName(); }
|
||||
|
||||
void connectToServer(const QString &hostname, unsigned int port, const QString &playername);
|
||||
void disconnectFromServer();
|
||||
int listGames();
|
||||
int listPlayers();
|
||||
int createGame(const QString &name, const QString &description, const QString &password, unsigned int maxPlayers);
|
||||
int joinGame(const QString &name, const QString &password);
|
||||
int leaveGame();
|
||||
int setName(const QString &name);
|
||||
int say(const QString &s);
|
||||
int shuffle();
|
||||
int rollDice(unsigned int sides);
|
||||
int drawCards(unsigned int number);
|
||||
int moveCard(int cardid, const QString &startzone, const QString &targetzone, int x, int y = 0);
|
||||
int createToken(const QString &zone, const QString &name, const QString &powtough, int x, int y);
|
||||
int setCardAttr(const QString &zone, int cardid, const QString &aname, const QString &avalue);
|
||||
int submitDeck(const QStringList &deck);
|
||||
int readyStart();
|
||||
int incCounter(const QString &counter, int delta);
|
||||
int setCounter(const QString &counter, int value);
|
||||
int delCounter(const QString &counter);
|
||||
int setActivePlayer(int player);
|
||||
int setActivePhase(int phase);
|
||||
int dumpZone(int player, const QString &zone, int numberCards);
|
||||
};
|
||||
|
||||
#endif
|
||||
30
cockatrice/src/counter.cpp
Normal file
30
cockatrice/src/counter.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include "counter.h"
|
||||
#include "player.h"
|
||||
#include <QtGui>
|
||||
|
||||
Counter::Counter(Player *_player, const QString &_name, QGraphicsItem *parent)
|
||||
: QGraphicsItem(parent), name(_name), value(0), player(_player)
|
||||
{
|
||||
player->addCounter(this);
|
||||
}
|
||||
|
||||
QRectF Counter::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 50, 30);
|
||||
}
|
||||
|
||||
void Counter::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->save();
|
||||
painter->fillRect(boundingRect(), QBrush(QColor("gray")));
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString("%1").arg(value));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void Counter::setValue(int _value)
|
||||
{
|
||||
value = _value;
|
||||
update(boundingRect());
|
||||
}
|
||||
24
cockatrice/src/counter.h
Normal file
24
cockatrice/src/counter.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef COUNTER_H
|
||||
#define COUNTER_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
class Player;
|
||||
|
||||
class Counter : public QGraphicsItem {
|
||||
private:
|
||||
QString name;
|
||||
int value;
|
||||
protected:
|
||||
Player *player;
|
||||
public:
|
||||
Counter(Player *_player, const QString &_name, QGraphicsItem *parent = 0);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
|
||||
QString getName() const { return name; }
|
||||
int getValue() const { return value; }
|
||||
void setValue(int _value);
|
||||
};
|
||||
|
||||
#endif
|
||||
11
cockatrice/src/counterlist.cpp
Normal file
11
cockatrice/src/counterlist.cpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include "counterlist.h"
|
||||
|
||||
Counter *CounterList::findCounter(const QString &name) const
|
||||
{
|
||||
for (int i = 0; i < size(); i++) {
|
||||
Counter *temp = at(i);
|
||||
if (!temp->getName().compare(name))
|
||||
return temp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
12
cockatrice/src/counterlist.h
Normal file
12
cockatrice/src/counterlist.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef COUNTERLIST_H
|
||||
#define COUNTERLIST_H
|
||||
|
||||
#include "counter.h"
|
||||
#include <QList>
|
||||
|
||||
class CounterList : public QList<Counter *> {
|
||||
public:
|
||||
Counter *findCounter(const QString &name) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
92
cockatrice/src/decklistmodel.cpp
Normal file
92
cockatrice/src/decklistmodel.cpp
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
#include "decklistmodel.h"
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
DeckListModel::~DeckListModel()
|
||||
{
|
||||
qDebug("DeckListModel destructor");
|
||||
cleanList();
|
||||
}
|
||||
|
||||
int DeckListModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return deckList.size();
|
||||
}
|
||||
|
||||
int DeckListModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return 2;
|
||||
}
|
||||
|
||||
QVariant DeckListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
if ((index.row() >= deckList.size()) || (index.column() >= 2))
|
||||
return QVariant();
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
DecklistRow *r = deckList.at(index.row());
|
||||
switch (index.column()) {
|
||||
case 0: return r->getNumber();
|
||||
case 1: return r->getCard();
|
||||
default: return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant DeckListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
if (orientation != Qt::Horizontal)
|
||||
return QVariant();
|
||||
switch (section) {
|
||||
case 0: return QString(tr("Number"));
|
||||
case 1: return QString(tr("Card"));
|
||||
default: return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
void DeckListModel::cleanList()
|
||||
{
|
||||
QListIterator<DecklistRow *> i(deckList);
|
||||
while (i.hasNext())
|
||||
delete i.next();
|
||||
deckList.clear();
|
||||
}
|
||||
|
||||
void DeckListModel::loadFromFile(const QString &fileName)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
return;
|
||||
QTextStream in(&file);
|
||||
cleanList();
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine().simplified();
|
||||
bool isSideboard = false;
|
||||
if (line.startsWith("SB:")) {
|
||||
line = line.mid(3).trimmed();
|
||||
isSideboard = true;
|
||||
}
|
||||
int i = line.indexOf(' ');
|
||||
bool ok;
|
||||
int number = line.left(i).toInt(&ok);
|
||||
if (!ok)
|
||||
continue;
|
||||
DecklistRow *row = new DecklistRow(number, line.mid(i + 1), isSideboard);
|
||||
deckList << row;
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
DecklistRow *DeckListModel::getRow(int row) const
|
||||
{
|
||||
if (row >= deckList.size())
|
||||
return 0;
|
||||
return deckList.at(row);
|
||||
}
|
||||
36
cockatrice/src/decklistmodel.h
Normal file
36
cockatrice/src/decklistmodel.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef DECKLISTMODEL_H
|
||||
#define DECKLISTMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
|
||||
class DecklistRow {
|
||||
private:
|
||||
int number;
|
||||
QString card;
|
||||
bool sideboard;
|
||||
public:
|
||||
DecklistRow(int _number, const QString &_card, bool _sideboard) : number(_number), card(_card), sideboard(_sideboard) { }
|
||||
int getNumber() const { return number; }
|
||||
QString getCard() const { return card; }
|
||||
bool isSideboard() const { return sideboard; }
|
||||
};
|
||||
|
||||
class DeckListModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DeckListModel(QObject *parent = 0)
|
||||
: QAbstractListModel(parent) { }
|
||||
~DeckListModel();
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
void loadFromFile(const QString &fileName);
|
||||
DecklistRow *getRow(int row) const;
|
||||
private:
|
||||
QList<DecklistRow *> deckList;
|
||||
void cleanList();
|
||||
};
|
||||
|
||||
#endif
|
||||
61
cockatrice/src/dlg_connect.cpp
Normal file
61
cockatrice/src/dlg_connect.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#include <QtGui>
|
||||
#include "dlg_connect.h"
|
||||
|
||||
DlgConnect::DlgConnect(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit("localhost");
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit("4747");
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit("Player");
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
okButton = new QPushButton(tr("&OK"));
|
||||
okButton->setDefault(true);
|
||||
cancelButton = new QPushButton(tr("&Cancel"));
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
grid->addWidget(hostLabel, 0, 0);
|
||||
grid->addWidget(hostEdit, 0, 1);
|
||||
grid->addWidget(portLabel, 1, 0);
|
||||
grid->addWidget(portEdit, 1, 1);
|
||||
grid->addWidget(playernameLabel, 2, 0);
|
||||
grid->addWidget(playernameEdit, 2, 1);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(okButton);
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Connect to server"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
|
||||
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
|
||||
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
}
|
||||
|
||||
QString DlgConnect::getHost()
|
||||
{
|
||||
return hostEdit->text();
|
||||
}
|
||||
|
||||
int DlgConnect::getPort()
|
||||
{
|
||||
return portEdit->text().toInt();
|
||||
}
|
||||
|
||||
QString DlgConnect::getPlayerName()
|
||||
{
|
||||
return playernameEdit->text();
|
||||
}
|
||||
23
cockatrice/src/dlg_connect.h
Normal file
23
cockatrice/src/dlg_connect.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef DLG_CONNECT_H
|
||||
#define DLG_CONNECT_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
|
||||
class DlgConnect : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DlgConnect(QWidget *parent = 0);
|
||||
QString getHost();
|
||||
int getPort();
|
||||
QString getPlayerName();
|
||||
private:
|
||||
QLabel *hostLabel, *portLabel, *playernameLabel;
|
||||
QLineEdit *hostEdit, *portEdit, *playernameEdit;
|
||||
QPushButton *okButton, *cancelButton;
|
||||
};
|
||||
|
||||
#endif
|
||||
85
cockatrice/src/dlg_creategame.cpp
Normal file
85
cockatrice/src/dlg_creategame.cpp
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
#include <QtGui>
|
||||
#include "dlg_creategame.h"
|
||||
|
||||
DlgCreateGame::DlgCreateGame(Client *_client, QWidget *parent)
|
||||
: QDialog(parent), client(_client)
|
||||
{
|
||||
msgid = 0;
|
||||
|
||||
nameLabel = new QLabel(tr("&Name:"));
|
||||
nameEdit = new QLineEdit;
|
||||
nameLabel->setBuddy(nameEdit);
|
||||
|
||||
descriptionLabel = new QLabel(tr("&Description:"));
|
||||
descriptionEdit = new QLineEdit;
|
||||
descriptionLabel->setBuddy(descriptionEdit);
|
||||
|
||||
passwordLabel = new QLabel(tr("&Password:"));
|
||||
passwordEdit = new QLineEdit;
|
||||
passwordLabel->setBuddy(passwordEdit);
|
||||
|
||||
maxPlayersLabel = new QLabel(tr("&Max Players:"));
|
||||
maxPlayersEdit = new QLineEdit("2");
|
||||
maxPlayersLabel->setBuddy(maxPlayersEdit);
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
grid->addWidget(nameLabel, 0, 0);
|
||||
grid->addWidget(nameEdit, 0, 1);
|
||||
grid->addWidget(descriptionLabel, 1, 0);
|
||||
grid->addWidget(descriptionEdit, 1, 1);
|
||||
grid->addWidget(passwordLabel, 2, 0);
|
||||
grid->addWidget(passwordEdit, 2, 1);
|
||||
grid->addWidget(maxPlayersLabel, 3, 0);
|
||||
grid->addWidget(maxPlayersEdit, 3, 1);
|
||||
|
||||
okButton = new QPushButton(tr("&OK"));
|
||||
okButton->setDefault(true);
|
||||
cancelButton = new QPushButton(tr("&Cancel"));
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(okButton);
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Create game"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
|
||||
connect(okButton, SIGNAL(clicked()), this, SLOT(actOK()));
|
||||
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(client, SIGNAL(responseReceived(ServerResponse *)), this, SLOT(checkResponse(ServerResponse *)));
|
||||
}
|
||||
|
||||
void DlgCreateGame::actOK()
|
||||
{
|
||||
bool ok;
|
||||
int maxPlayers = maxPlayersEdit->text().toInt(&ok);
|
||||
if (msgid)
|
||||
return;
|
||||
if (!ok) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Invalid number of players."));
|
||||
return;
|
||||
}
|
||||
msgid = client->createGame(nameEdit->text(),
|
||||
descriptionEdit->text(),
|
||||
passwordEdit->text(),
|
||||
maxPlayers);
|
||||
}
|
||||
|
||||
void DlgCreateGame::checkResponse(ServerResponse *response)
|
||||
{
|
||||
if (response->getMsgId() != msgid)
|
||||
return;
|
||||
if (response->getOk())
|
||||
accept();
|
||||
else {
|
||||
QMessageBox::critical(this, tr("Error"), tr("XXX"));
|
||||
msgid = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
28
cockatrice/src/dlg_creategame.h
Normal file
28
cockatrice/src/dlg_creategame.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef DLG_CREATEGAME_H
|
||||
#define DLG_CREATEGAME_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "client.h"
|
||||
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
|
||||
class DlgCreateGame : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DlgCreateGame(Client *_client, QWidget *parent = 0);
|
||||
private slots:
|
||||
void actOK();
|
||||
void checkResponse(ServerResponse *response);
|
||||
private:
|
||||
Client *client;
|
||||
int msgid;
|
||||
|
||||
QLabel *nameLabel, *descriptionLabel, *passwordLabel, *maxPlayersLabel;
|
||||
QLineEdit *nameEdit, *descriptionEdit, *passwordEdit, *maxPlayersEdit;
|
||||
QPushButton *okButton, *cancelButton;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
87
cockatrice/src/dlg_games.cpp
Normal file
87
cockatrice/src/dlg_games.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#include <QtGui>
|
||||
#include "dlg_games.h"
|
||||
#include "dlg_creategame.h"
|
||||
|
||||
DlgGames::DlgGames(Client *_client, QWidget *parent)
|
||||
: QDialog(parent), client(_client)
|
||||
{
|
||||
msgid = 0;
|
||||
|
||||
tableView = new QTreeView;
|
||||
tableModel = new GamesModel(this);
|
||||
tableView->setModel(tableModel);
|
||||
|
||||
createButton = new QPushButton(tr("&Create"));
|
||||
refreshButton = new QPushButton(tr("&Refresh"));
|
||||
joinButton = new QPushButton(tr("&Join"));
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addWidget(createButton);
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(refreshButton);
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(joinButton);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(tableView);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Games"));
|
||||
setMinimumWidth(sizeHint().width());
|
||||
|
||||
connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate()));
|
||||
connect(refreshButton, SIGNAL(clicked()), this, SLOT(actRefresh()));
|
||||
connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin()));
|
||||
|
||||
connect(client, SIGNAL(gameListReceived(QList<ServerGame *>)), this, SLOT(gameListReceived(QList<ServerGame *>)));
|
||||
client->listGames();
|
||||
}
|
||||
|
||||
void DlgGames::actCreate()
|
||||
{
|
||||
DlgCreateGame dlg(client, this);
|
||||
if (dlg.exec())
|
||||
accept();
|
||||
}
|
||||
|
||||
void DlgGames::actRefresh()
|
||||
{
|
||||
client->listGames();
|
||||
}
|
||||
|
||||
void DlgGames::checkResponse(ServerResponse *response)
|
||||
{
|
||||
if (response->getMsgId() != msgid)
|
||||
return;
|
||||
if (response->getOk())
|
||||
accept();
|
||||
else {
|
||||
QMessageBox::critical(this, tr("Error"), tr("XXX"));
|
||||
msgid = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DlgGames::actJoin()
|
||||
{
|
||||
if (msgid)
|
||||
return;
|
||||
|
||||
ServerGame *game = tableModel->getGame(tableView->currentIndex().row());
|
||||
QString password;
|
||||
if (game->getHasPassword()) {
|
||||
bool ok;
|
||||
password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
}
|
||||
|
||||
connect(client, SIGNAL(responseReceived(ServerResponse *)), this, SLOT(checkResponse(ServerResponse *)));
|
||||
msgid = client->joinGame(game->getName(), password);
|
||||
}
|
||||
|
||||
void DlgGames::gameListReceived(QList<ServerGame *> _gameList)
|
||||
{
|
||||
tableModel->setGameList(_gameList);
|
||||
}
|
||||
32
cockatrice/src/dlg_games.h
Normal file
32
cockatrice/src/dlg_games.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef DLG_GAMES_H
|
||||
#define DLG_GAMES_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "gamesmodel.h"
|
||||
#include "servergame.h"
|
||||
#include "client.h"
|
||||
|
||||
class QPushButton;
|
||||
class QTreeView;
|
||||
|
||||
class DlgGames : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DlgGames(Client *_client, QWidget *parent = 0);
|
||||
private slots:
|
||||
void actCreate();
|
||||
void actRefresh();
|
||||
void actJoin();
|
||||
void gameListReceived(QList<ServerGame *> _gameList);
|
||||
void checkResponse(ServerResponse *response);
|
||||
private:
|
||||
Client *client;
|
||||
int msgid;
|
||||
|
||||
QTreeView *tableView;
|
||||
GamesModel *tableModel;
|
||||
QPushButton *refreshButton, *createButton, *joinButton;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
63
cockatrice/src/dlg_startgame.cpp
Normal file
63
cockatrice/src/dlg_startgame.cpp
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#include <QtGui>
|
||||
#include <QFileDialog>
|
||||
#include "dlg_startgame.h"
|
||||
#include "decklistmodel.h"
|
||||
#include "carddatabase.h"
|
||||
|
||||
DlgStartGame::DlgStartGame(CardDatabase *_db, QWidget *parent)
|
||||
: QDialog(parent), db(_db)
|
||||
{
|
||||
tableView = new QTreeView;
|
||||
tableModel = new DeckListModel(this);
|
||||
tableView->setModel(tableModel);
|
||||
|
||||
loadButton = new QPushButton(tr("&Load..."));
|
||||
okButton = new QPushButton(tr("&OK"));
|
||||
okButton->setDefault(true);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addWidget(loadButton);
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(okButton);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(tableView);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Start game"));
|
||||
setMinimumWidth(sizeHint().width());
|
||||
|
||||
connect(loadButton, SIGNAL(clicked()), this, SLOT(actLoad()));
|
||||
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
|
||||
}
|
||||
|
||||
void DlgStartGame::actLoad()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Load deck"), QString(), tr("Deck files (*.dec)"));
|
||||
if (!fileName.isEmpty())
|
||||
tableModel->loadFromFile(fileName);
|
||||
|
||||
// Precache card pictures
|
||||
for (int i = 0; i < tableModel->rowCount(); i++) {
|
||||
QString cardName = tableModel->getRow(i)->getCard();
|
||||
CardInfo *card = db->getCard(cardName);
|
||||
if (!card) {
|
||||
qDebug(QString("Invalid card: %1").arg(cardName).toLatin1());
|
||||
continue;
|
||||
}
|
||||
card->getPixmap();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList DlgStartGame::getDeckList() const
|
||||
{
|
||||
QStringList result;
|
||||
for (int i = 0; i < tableModel->rowCount(); i++) {
|
||||
DecklistRow *temp = tableModel->getRow(i);
|
||||
for (int j = 0; j < temp->getNumber(); j++)
|
||||
result << QString("%1%2").arg(temp->isSideboard() ? "SB:" : "").arg(temp->getCard());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
26
cockatrice/src/dlg_startgame.h
Normal file
26
cockatrice/src/dlg_startgame.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef DLG_STARTGAME_H
|
||||
#define DLG_STARTGAME_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "decklistmodel.h"
|
||||
|
||||
class QTreeView;
|
||||
class QPushButton;
|
||||
class CardDatabase;
|
||||
|
||||
class DlgStartGame: public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DlgStartGame(CardDatabase *_db, QWidget *parent = 0);
|
||||
QStringList getDeckList() const;
|
||||
private slots:
|
||||
void actLoad();
|
||||
private:
|
||||
CardDatabase *db;
|
||||
QTreeView *tableView;
|
||||
DeckListModel *tableModel;
|
||||
|
||||
QPushButton *loadButton, *okButton;
|
||||
};
|
||||
|
||||
#endif
|
||||
371
cockatrice/src/game.cpp
Normal file
371
cockatrice/src/game.cpp
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
#include <QGraphicsScene>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#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"
|
||||
|
||||
Game::Game(CardDatabase *_db, Client *_client, QGraphicsScene *_scene, QMenu *_actionsMenu, QMenu *_cardMenu, int playerId, const QString &playerName)
|
||||
: QObject(), 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), true);
|
||||
|
||||
connect(client, SIGNAL(gameEvent(ServerEventData *)), this, SLOT(gameEvent(ServerEventData *)));
|
||||
connect(client, SIGNAL(playerListReceived(QList<ServerPlayer *>)), this, SLOT(playerListReceived(QList<ServerPlayer *>)));
|
||||
|
||||
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()));
|
||||
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);
|
||||
|
||||
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()));
|
||||
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()));
|
||||
aRearrange = new QAction(tr("&Rearrange"), this);
|
||||
connect(aRearrange, SIGNAL(triggered()), this, SLOT(actRearrange()));
|
||||
|
||||
cardMenu->addAction(aTap);
|
||||
cardMenu->addAction(aUntap);
|
||||
cardMenu->addAction(aAddCounter);
|
||||
cardMenu->addAction(aRemoveCounter);
|
||||
cardMenu->addAction(aSetCounters);
|
||||
cardMenu->addSeparator();
|
||||
cardMenu->addAction(aRearrange);
|
||||
|
||||
dlgStartGame = new DlgStartGame(db);
|
||||
}
|
||||
|
||||
Game::~Game()
|
||||
{
|
||||
qDebug("Game destructor");
|
||||
for (int i = 0; i < players.size(); i++) {
|
||||
emit playerRemoved(players.at(i));
|
||||
delete players.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
Player *Game::addPlayer(int playerId, const QString &playerName, QPointF base, bool local)
|
||||
{
|
||||
Player *newPlayer = new Player(playerName, playerId, base, local, db, client);
|
||||
|
||||
const ZoneList *const z = newPlayer->getZones();
|
||||
for (int i = 0; i < z->size(); i++)
|
||||
scene->addItem(z->at(i));
|
||||
|
||||
const CounterList *const c = newPlayer->getCounters();
|
||||
for (int i = 0; i < c->size(); i++)
|
||||
scene->addItem(c->at(i));
|
||||
|
||||
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)));
|
||||
|
||||
players << newPlayer;
|
||||
emit playerAdded(newPlayer);
|
||||
|
||||
return newPlayer;
|
||||
}
|
||||
|
||||
void Game::playerListReceived(QList<ServerPlayer *> playerList)
|
||||
{
|
||||
QListIterator<ServerPlayer *> 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::restartGameDialog()
|
||||
{
|
||||
dlgStartGame->exec();
|
||||
client->submitDeck(dlgStartGame->getDeckList());
|
||||
}
|
||||
|
||||
void Game::gameEvent(ServerEventData *msg)
|
||||
{
|
||||
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 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()
|
||||
{
|
||||
CardList *const cards = localPlayer->getZones()->findZone("table")->getCards();
|
||||
for (int i = 0; i < cards->size(); i++)
|
||||
client->setCardAttr("table", cards->at(i)->getId(), "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->getCounters()->findCounter("life")->getValue(), 0, 2000000000, 1, &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:"));
|
||||
if (!db->getCard(cardname))
|
||||
QMessageBox::critical(0, "Error", "No such card");
|
||||
else
|
||||
client->createToken("table", cardname, QString(), 0, 0);
|
||||
}
|
||||
|
||||
void Game::showCardMenu(QPoint p)
|
||||
{
|
||||
cardMenu->exec(p);
|
||||
}
|
||||
|
||||
void Game::actTap()
|
||||
{
|
||||
QListIterator<QGraphicsItem *> i(scene->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
client->setCardAttr(qgraphicsitem_cast<PlayerZone *>(temp->parentItem())->getName(), temp->getId(), "tapped", "1");
|
||||
}
|
||||
}
|
||||
|
||||
void Game::actUntap()
|
||||
{
|
||||
QListIterator<QGraphicsItem *> i(scene->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
client->setCardAttr(qgraphicsitem_cast<PlayerZone *>(temp->parentItem())->getName(), temp->getId(), "tapped", "0");
|
||||
}
|
||||
}
|
||||
|
||||
void Game::actAddCounter()
|
||||
{
|
||||
QListIterator<QGraphicsItem *> i(scene->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
if (temp->getCounters() < MAX_COUNTERS_ON_CARD)
|
||||
client->setCardAttr(qgraphicsitem_cast<PlayerZone *>(temp->parentItem())->getName(), temp->getId(), "counters", QString::number(temp->getCounters() + 1));
|
||||
}
|
||||
}
|
||||
|
||||
void Game::actRemoveCounter()
|
||||
{
|
||||
QListIterator<QGraphicsItem *> i(scene->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
if (temp->getCounters())
|
||||
client->setCardAttr(qgraphicsitem_cast<PlayerZone *>(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<QGraphicsItem *> i(scene->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
client->setCardAttr(qgraphicsitem_cast<PlayerZone *>(temp->parentItem())->getName(), temp->getId(), "counters", QString::number(number));
|
||||
}
|
||||
}
|
||||
|
||||
void Game::actRearrange()
|
||||
{
|
||||
// nur sinnvoll bei Karten auf dem Tisch -> Einschränkung einbauen
|
||||
int x, y, x_initial = 0, y_initial = 0;
|
||||
QList<QGraphicsItem *> list = scene->selectedItems();
|
||||
|
||||
// Find coordinates of leftmost card
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
CardItem *temp = (CardItem *) list.at(i);
|
||||
if ((temp->pos().x() < x_initial) || (x_initial == 0)) {
|
||||
x_initial = (int) temp->pos().x();
|
||||
y_initial = (int) temp->pos().y();
|
||||
}
|
||||
}
|
||||
x = x_initial;
|
||||
y = y_initial;
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
CardItem *temp = (CardItem *) list.at(i);
|
||||
QString zoneName = qgraphicsitem_cast<PlayerZone *>(temp->parentItem())->getName();
|
||||
x = x_initial + i * RASTER_WIDTH;
|
||||
y = y_initial + (i % 3) * RASTER_HEIGHT;
|
||||
client->moveCard(temp->getId(), zoneName, zoneName, x, y);
|
||||
}
|
||||
}
|
||||
80
cockatrice/src/game.h
Normal file
80
cockatrice/src/game.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#ifndef GAME_H
|
||||
#define GAME_H
|
||||
|
||||
#include "playerlist.h"
|
||||
|
||||
class ServerPlayer;
|
||||
class QGraphicsScene;
|
||||
class Player;
|
||||
class Client;
|
||||
class ServerEventData;
|
||||
class CardDatabase;
|
||||
class DlgStartGame;
|
||||
|
||||
class Game : public QObject {
|
||||
Q_OBJECT
|
||||
private:
|
||||
QMenu *actionsMenu, *cardMenu;
|
||||
QAction *aTap, *aUntap, *aAddCounter, *aRemoveCounter, *aSetCounters, *aRearrange,
|
||||
*aUntapAll, *aDecLife, *aIncLife, *aSetLife, *aShuffle, *aDraw, *aDrawCards, *aRollDice, *aCreateToken;
|
||||
DlgStartGame *dlgStartGame;
|
||||
|
||||
CardDatabase *db;
|
||||
Client *client;
|
||||
QGraphicsScene *scene;
|
||||
PlayerList players;
|
||||
Player *localPlayer;
|
||||
bool started;
|
||||
Player *addPlayer(int playerId, const QString &playerName, QPointF base, bool local);
|
||||
private slots:
|
||||
void actUntapAll();
|
||||
void actIncLife();
|
||||
void actDecLife();
|
||||
void actSetLife();
|
||||
void actShuffle();
|
||||
void actDrawCard();
|
||||
void actDrawCards();
|
||||
void actRollDice();
|
||||
void actCreateToken();
|
||||
|
||||
void showCardMenu(QPoint p);
|
||||
void actTap();
|
||||
void actUntap();
|
||||
void actAddCounter();
|
||||
void actRemoveCounter();
|
||||
void actSetCounters();
|
||||
void actRearrange();
|
||||
|
||||
void gameEvent(ServerEventData *msg);
|
||||
void playerListReceived(QList<ServerPlayer *> playerList);
|
||||
signals:
|
||||
void submitDecklist();
|
||||
void hoverCard(QString name);
|
||||
void playerAdded(Player *player);
|
||||
void playerRemoved(Player *player);
|
||||
|
||||
// Log events
|
||||
void logPlayerListReceived(QStringList players);
|
||||
void logJoin(QString playerName);
|
||||
void logLeave(QString playerName);
|
||||
void logReadyStart(QString playerName);
|
||||
void logGameStart();
|
||||
void logSay(QString playerName, QString text);
|
||||
void logShuffle(QString playerName);
|
||||
void logRollDice(QString playerName, int sides, int roll);
|
||||
void logDraw(QString playerName, int number);
|
||||
void logMoveCard(QString playerName, QString cardName, QString startZone, QString targetZone);
|
||||
void logCreateToken(QString playerName, QString cardName);
|
||||
void logSetCardCounters(QString playerName, QString cardName, int value, int oldValue);
|
||||
void logSetTapped(QString playerName, QString cardName, bool tapped);
|
||||
void logSetCounter(QString playerName, QString counterName, int value, int oldValue);
|
||||
void logDumpZone(QString playerName, QString zoneName, QString zoneOwner, int numberCards);
|
||||
public slots:
|
||||
void restartGameDialog();
|
||||
public:
|
||||
Game(CardDatabase *_db, Client *_client, QGraphicsScene *_scene, QMenu *_actionsMenu, QMenu *_cardMenu, int playerId, const QString &playerName);
|
||||
~Game();
|
||||
Player *getLocalPlayer() const { return localPlayer; }
|
||||
};
|
||||
|
||||
#endif
|
||||
74
cockatrice/src/gamesmodel.cpp
Normal file
74
cockatrice/src/gamesmodel.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include "gamesmodel.h"
|
||||
#include "servergame.h"
|
||||
|
||||
GamesModel::~GamesModel()
|
||||
{
|
||||
cleanList();
|
||||
}
|
||||
|
||||
int GamesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return gameList.size();
|
||||
}
|
||||
|
||||
int GamesModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
QVariant GamesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
if ((index.row() >= gameList.size()) || (index.column() >= 4))
|
||||
return QVariant();
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
ServerGame *g = gameList.at(index.row());
|
||||
switch (index.column()) {
|
||||
case 0: return g->getName();
|
||||
case 1: return g->getDescription();
|
||||
case 2: return QString(g->getHasPassword() ? "yes" : "no");
|
||||
case 3: return QString("%1/%2").arg(g->getPlayerCount()).arg(g->getMaxPlayers());
|
||||
default: return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant GamesModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
if (orientation != Qt::Horizontal)
|
||||
return QVariant();
|
||||
switch (section) {
|
||||
case 0: return QString("Name");
|
||||
case 1: return QString("Description");
|
||||
case 2: return QString("Password");
|
||||
case 3: return QString("Players");
|
||||
default: return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
ServerGame *GamesModel::getGame(int row)
|
||||
{
|
||||
if (row >= gameList.size())
|
||||
return 0;
|
||||
return gameList[row];
|
||||
}
|
||||
|
||||
void GamesModel::setGameList(const QList<ServerGame *> &_gameList)
|
||||
{
|
||||
cleanList();
|
||||
gameList = _gameList;
|
||||
reset();
|
||||
}
|
||||
|
||||
void GamesModel::cleanList()
|
||||
{
|
||||
QListIterator<ServerGame *> i(gameList);
|
||||
while (i.hasNext())
|
||||
delete i.next();
|
||||
gameList.clear();
|
||||
}
|
||||
26
cockatrice/src/gamesmodel.h
Normal file
26
cockatrice/src/gamesmodel.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef GAMESMODEL_H
|
||||
#define GAMESMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
#include "servergame.h"
|
||||
|
||||
class GamesModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
GamesModel(QObject *parent = 0)
|
||||
: QAbstractListModel(parent) { }
|
||||
~GamesModel();
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
void setGameList(const QList<ServerGame *> &_gameList);
|
||||
ServerGame *getGame(int row);
|
||||
private:
|
||||
QList<ServerGame *> gameList;
|
||||
void cleanList();
|
||||
};
|
||||
|
||||
#endif
|
||||
33
cockatrice/src/gameview.cpp
Normal file
33
cockatrice/src/gameview.cpp
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#include "gameview.h"
|
||||
|
||||
GameView::GameView(QGraphicsScene *scene, QWidget *parent)
|
||||
: QGraphicsView(scene, parent)
|
||||
{
|
||||
setBackgroundBrush(QBrush(QColor(0, 0, 0)));
|
||||
setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
setOptimizationFlags(/*DontClipPainter | */DontSavePainterState);
|
||||
setDragMode(RubberBandDrag);
|
||||
}
|
||||
|
||||
void GameView::scaleToScene()
|
||||
{
|
||||
// This function ensures that the bounding rectangles of card pictures
|
||||
// have integer sizes. This is achieved by using a scale factor of n / 6.
|
||||
QRectF sr = scene()->sceneRect();
|
||||
QRectF vr = QRectF(viewport()->rect().adjusted(2, 2, -2, -2));
|
||||
qreal scale_h = vr.width() / sr.width();
|
||||
qreal scale_v = vr.height() / sr.height();
|
||||
qreal scale_total = qMin(scale_h, scale_v);
|
||||
|
||||
qreal scale_corr = (qreal) ((int) (scale_total * 6)) / 6;
|
||||
|
||||
qDebug(QString("scale_corr = %1 / 6").arg(scale_corr * 6).toLatin1());
|
||||
setTransform(QTransform().scale(scale_corr, scale_corr));
|
||||
}
|
||||
|
||||
void GameView::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
qDebug("GameView: resizeEvent");
|
||||
QGraphicsView::resizeEvent(event);
|
||||
scaleToScene();
|
||||
}
|
||||
14
cockatrice/src/gameview.h
Normal file
14
cockatrice/src/gameview.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef GAMEVIEW_H
|
||||
#define GAMEVIEW_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
|
||||
class GameView : public QGraphicsView {
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
public:
|
||||
void scaleToScene();
|
||||
GameView(QGraphicsScene *scene, QWidget *parent = 0);
|
||||
};
|
||||
|
||||
#endif
|
||||
53
cockatrice/src/gravezone.cpp
Normal file
53
cockatrice/src/gravezone.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#include <QtGui>
|
||||
#include "gravezone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "zoneviewzone.h"
|
||||
|
||||
GraveZone::GraveZone(Player *_p)
|
||||
: PlayerZone(_p, "grave")
|
||||
{
|
||||
cards = new CardList(true);
|
||||
}
|
||||
|
||||
QRectF GraveZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 50, 50);
|
||||
}
|
||||
|
||||
void GraveZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->save();
|
||||
painter->fillRect(boundingRect(), QColor("yellow"));
|
||||
painter->setFont(QFont("Times", 20, QFont::Bold));
|
||||
painter->setPen(QPen(QColor("black")));
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(cards->size()));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void GraveZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
for (int i = 0; i < views.size(); i++)
|
||||
views[i]->addCard(new CardItem(player->getDb(), card->getName(), card->getId()), reorganize, x, y);
|
||||
|
||||
cards->insert(x, card);
|
||||
card->setPos(0, 0);
|
||||
card->setVisible(false);
|
||||
card->resetState();
|
||||
card->setParentItem(this);
|
||||
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void GraveZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), 0, 0);
|
||||
}
|
||||
|
||||
void GraveZone::reorganizeCards()
|
||||
{
|
||||
update(boundingRect());
|
||||
}
|
||||
17
cockatrice/src/gravezone.h
Normal file
17
cockatrice/src/gravezone.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef GRAVEZONE_H
|
||||
#define GRAVEZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
class GraveZone : public PlayerZone {
|
||||
private:
|
||||
public:
|
||||
GraveZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = 0, int y = -1);
|
||||
void reorganizeCards();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
};
|
||||
|
||||
#endif
|
||||
73
cockatrice/src/handzone.cpp
Normal file
73
cockatrice/src/handzone.cpp
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#include <QtGui>
|
||||
#include "handzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
|
||||
HandZone::HandZone(Player *_p)
|
||||
: PlayerZone(_p, "hand")
|
||||
{
|
||||
cards = new CardList(player->getLocal());
|
||||
}
|
||||
|
||||
QRectF HandZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 100, 500);
|
||||
}
|
||||
|
||||
void HandZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->fillRect(boundingRect(), QColor("green"));
|
||||
}
|
||||
|
||||
void HandZone::reorganizeCards()
|
||||
{
|
||||
if (cards->isEmpty())
|
||||
return;
|
||||
|
||||
int cardCount = cards->size();
|
||||
qreal totalWidth = boundingRect().width();
|
||||
qreal totalHeight = boundingRect().height();
|
||||
qreal cardWidth = cards->at(0)->boundingRect().width();
|
||||
qreal cardHeight = cards->at(0)->boundingRect().height();
|
||||
qreal x = (totalWidth - cardWidth) / 2;
|
||||
|
||||
for (int i = 0; i < cardCount; i++) {
|
||||
CardItem *c = cards->at(i);
|
||||
// If the total height of the cards is smaller than the available height,
|
||||
// the cards do not need to overlap and are displayed in the center of the area.
|
||||
if (cardHeight * cardCount > totalHeight)
|
||||
c->setPos(x, ((qreal) i) * (totalHeight - cardHeight) / (cardCount - 1));
|
||||
else
|
||||
c->setPos(x, ((qreal) i) * cardHeight + (totalHeight - cardCount * cardHeight) / 2);
|
||||
c->setZValue(i);
|
||||
}
|
||||
}
|
||||
|
||||
void HandZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
Q_UNUSED(y);
|
||||
|
||||
if (x == -1)
|
||||
x = cards->size();
|
||||
cards->insert(x, card);
|
||||
|
||||
if (!cards->getContentsKnown()) {
|
||||
card->setId(-1);
|
||||
card->setName();
|
||||
}
|
||||
card->setParentItem(this);
|
||||
card->resetState();
|
||||
card->setVisible(true);
|
||||
card->update(card->boundingRect());
|
||||
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void HandZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
Q_UNUSED(dropPoint);
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), cards->size(), 0);
|
||||
}
|
||||
17
cockatrice/src/handzone.h
Normal file
17
cockatrice/src/handzone.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef HANDZONE_H
|
||||
#define HANDZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
class HandZone : public PlayerZone {
|
||||
private:
|
||||
public:
|
||||
HandZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = -1, int y = -1);
|
||||
void reorganizeCards();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
};
|
||||
|
||||
#endif
|
||||
88
cockatrice/src/libraryzone.cpp
Normal file
88
cockatrice/src/libraryzone.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#include <QtGui>
|
||||
#include "libraryzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "carddatabase.h"
|
||||
#include "carddragitem.h"
|
||||
#include "zoneviewzone.h"
|
||||
|
||||
LibraryZone::LibraryZone(Player *_p)
|
||||
: PlayerZone(_p, "deck")
|
||||
{
|
||||
cards = new CardList(false);
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
QRectF LibraryZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 50, 50);
|
||||
}
|
||||
|
||||
void LibraryZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->save();
|
||||
painter->fillRect(boundingRect(), QColor("red"));
|
||||
painter->setFont(QFont("Times", 20, QFont::Bold));
|
||||
painter->setPen(QPen(QColor("black")));
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(cards->size()));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void LibraryZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
for (int i = 0; i < views.size(); i++)
|
||||
views[i]->addCard(new CardItem(player->getDb(), card->getName(), card->getId()), reorganize, x, y);
|
||||
|
||||
cards->insert(x, card);
|
||||
card->setId(-1);
|
||||
card->setName(QString());
|
||||
card->setPos(0, 0);
|
||||
card->setVisible(false);
|
||||
card->resetState();
|
||||
card->setParentItem(this);
|
||||
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void LibraryZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), 0, 0);
|
||||
}
|
||||
|
||||
void LibraryZone::reorganizeCards()
|
||||
{
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
void LibraryZone::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
PlayerZone::mousePressEvent(event);
|
||||
if (event->isAccepted())
|
||||
return;
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
event->accept();
|
||||
} else
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
void LibraryZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < QApplication::startDragDistance())
|
||||
return;
|
||||
|
||||
CardItem *card = cards->at(0);
|
||||
CardDragItem *drag = card->createDragItem(this, 0, event->pos(), event->scenePos());
|
||||
drag->grabMouse();
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
void LibraryZone::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
21
cockatrice/src/libraryzone.h
Normal file
21
cockatrice/src/libraryzone.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef LIBRARYZONE_H
|
||||
#define LIBRARYZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
class LibraryZone : public PlayerZone {
|
||||
private:
|
||||
public:
|
||||
LibraryZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = 0, int y = -1);
|
||||
void reorganizeCards();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
};
|
||||
|
||||
#endif
|
||||
51
cockatrice/src/main.cpp
Normal file
51
cockatrice/src/main.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@gmx.net *
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
#include <QtPlugin>
|
||||
#include "window.h"
|
||||
#include <stdio.h>
|
||||
|
||||
//Q_IMPORT_PLUGIN(qjpeg)
|
||||
|
||||
void myMessageOutput(QtMsgType type, const char *msg)
|
||||
{
|
||||
static FILE *f = NULL;
|
||||
if (!f)
|
||||
f = fopen("qdebug.txt", "w");
|
||||
fprintf(f, "%s\n", msg);
|
||||
fflush(f);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
qInstallMsgHandler(myMessageOutput);
|
||||
QApplication app(argc, argv);
|
||||
app.addLibraryPath("plugins");
|
||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
MainWindow *ui = new MainWindow;
|
||||
ui->show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
147
cockatrice/src/messagelogwidget.cpp
Normal file
147
cockatrice/src/messagelogwidget.cpp
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
#include "messagelogwidget.h"
|
||||
#include "game.h"
|
||||
#include <QScrollBar>
|
||||
|
||||
void MessageLogWidget::appendAndScroll(const QString &s)
|
||||
{
|
||||
append(s);
|
||||
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
|
||||
}
|
||||
|
||||
void MessageLogWidget::logConnecting(QString hostname)
|
||||
{
|
||||
appendAndScroll(tr("Connecting to %1...").arg(hostname));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logConnected(const QStringList WelcomeMsg)
|
||||
{
|
||||
appendAndScroll(tr("Connected."));
|
||||
|
||||
QStringListIterator i(WelcomeMsg);
|
||||
while (i.hasNext())
|
||||
appendAndScroll(i.next());
|
||||
}
|
||||
|
||||
void MessageLogWidget::logDisconnected()
|
||||
{
|
||||
appendAndScroll(tr("Disconnected from server."));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logSocketError(const QString &errorString)
|
||||
{
|
||||
appendAndScroll(errorString);
|
||||
}
|
||||
|
||||
void MessageLogWidget::logPlayerListReceived(QStringList players)
|
||||
{
|
||||
append("---");
|
||||
append(tr("You have joined the game. Player list:"));
|
||||
for (int i = 0; i < players.size(); i++)
|
||||
append(players.at(i));
|
||||
appendAndScroll("---");
|
||||
}
|
||||
|
||||
void MessageLogWidget::logJoin(QString playerName)
|
||||
{
|
||||
appendAndScroll(tr("%1 has joined the game").arg(playerName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logLeave(QString playerName)
|
||||
{
|
||||
appendAndScroll(tr("%1 has left the game").arg(playerName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logReadyStart(QString playerName)
|
||||
{
|
||||
appendAndScroll(tr("%1 is ready to start a new game.").arg(playerName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logGameStart()
|
||||
{
|
||||
appendAndScroll(tr("Game has started."));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logSay(QString playerName, QString message)
|
||||
{
|
||||
appendAndScroll(QString("<font color=\"red\">%1:</font> %2").arg(playerName).arg(message));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logShuffle(QString playerName)
|
||||
{
|
||||
appendAndScroll(tr("%1 shuffles his/her library").arg(playerName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logRollDice(QString playerName, int sides, int roll)
|
||||
{
|
||||
appendAndScroll(tr("%1 rolled a %2 with a %3-sided dice").arg(playerName).arg(roll).arg(sides));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logDraw(QString playerName, int number)
|
||||
{
|
||||
if (number == 1)
|
||||
appendAndScroll(tr("%1 draws a card").arg(playerName));
|
||||
else
|
||||
appendAndScroll(tr("%1 draws %2 cards").arg(playerName).arg(number));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logMoveCard(QString playerName, QString cardName, QString startZone, QString targetZone)
|
||||
{
|
||||
appendAndScroll(tr("%1 moves %2 from %3 to %4").arg(playerName).arg(cardName).arg(startZone).arg(targetZone));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logCreateToken(QString playerName, QString cardName)
|
||||
{
|
||||
appendAndScroll(tr("%1 creates token: %2").arg(playerName).arg(cardName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logSetCardCounters(QString playerName, QString cardName, int value, int oldValue)
|
||||
{
|
||||
if (value > oldValue)
|
||||
appendAndScroll(tr("%1 places %2 counters on %3 (now %4)").arg(playerName).arg(value - oldValue).arg(cardName).arg(value));
|
||||
else
|
||||
appendAndScroll(tr("%1 removes %2 counters from %3 (now %4)").arg(playerName).arg(oldValue - value).arg(cardName).arg(value));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logSetTapped(QString playerName, QString cardName, bool tapped)
|
||||
{
|
||||
appendAndScroll(tr("%1 %2 %3").arg(playerName).arg(tapped ? "taps" : "untaps").arg(cardName));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logSetCounter(QString playerName, QString counterName, int value, int oldValue)
|
||||
{
|
||||
appendAndScroll(tr("%1 sets counter \"%2\" to %3 (%4%5)").arg(playerName).arg(counterName).arg(value).arg(value > oldValue ? "+" : "").arg(value - oldValue));
|
||||
}
|
||||
|
||||
void MessageLogWidget::logDumpZone(QString playerName, QString zoneName, QString zoneOwner, int numberCards)
|
||||
{
|
||||
if (numberCards)
|
||||
appendAndScroll(tr("%1 is looking at the top %2 cards of %3's %4").arg(playerName).arg(numberCards).arg(zoneOwner).arg(zoneName));
|
||||
else
|
||||
appendAndScroll(tr("%1 is looking at %2's %3").arg(playerName).arg(zoneOwner).arg(zoneName));
|
||||
}
|
||||
|
||||
|
||||
void MessageLogWidget::connectToGame(Game *game)
|
||||
{
|
||||
connect(game, SIGNAL(logPlayerListReceived(QStringList)), this, SLOT(logPlayerListReceived(QStringList)));
|
||||
connect(game, SIGNAL(logJoin(QString)), this, SLOT(logJoin(QString)));
|
||||
connect(game, SIGNAL(logLeave(QString)), this, SLOT(logLeave(QString)));
|
||||
connect(game, SIGNAL(logReadyStart(QString)), this, SLOT(logReadyStart(QString)));
|
||||
connect(game, SIGNAL(logGameStart()), this, SLOT(logGameStart()));
|
||||
connect(game, SIGNAL(logSay(QString, QString)), this, SLOT(logSay(QString, QString)));
|
||||
connect(game, SIGNAL(logShuffle(QString)), this, SLOT(logShuffle(QString)));
|
||||
connect(game, SIGNAL(logRollDice(QString, int, int)), this, SLOT(logRollDice(QString, int, int)));
|
||||
connect(game, SIGNAL(logDraw(QString, int)), this, SLOT(logDraw(QString, int)));
|
||||
connect(game, SIGNAL(logMoveCard(QString, QString, QString, QString)), this, SLOT(logMoveCard(QString, QString, QString, QString)));
|
||||
connect(game, SIGNAL(logCreateToken(QString, QString)), this, SLOT(logCreateToken(QString, QString)));
|
||||
connect(game, SIGNAL(logSetCardCounters(QString, QString, int, int)), this, SLOT(logSetCardCounters(QString, QString, int, int)));
|
||||
connect(game, SIGNAL(logSetTapped(QString, QString, bool)), this, SLOT(logSetTapped(QString, QString, bool)));
|
||||
connect(game, SIGNAL(logSetCounter(QString, QString, int, int)), this, SLOT(logSetCounter(QString, QString, int, int)));
|
||||
connect(game, SIGNAL(logDumpZone(QString, QString, QString, int)), this, SLOT(logDumpZone(QString, QString, QString, int)));
|
||||
}
|
||||
|
||||
MessageLogWidget::MessageLogWidget(QWidget *parent)
|
||||
: QTextEdit(parent)
|
||||
{
|
||||
setReadOnly(true);
|
||||
}
|
||||
39
cockatrice/src/messagelogwidget.h
Normal file
39
cockatrice/src/messagelogwidget.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef MESSAGELOGWIDGET_H
|
||||
#define MESSAGELOGWIDGET_H
|
||||
|
||||
#include <QTextEdit>
|
||||
#include <QAbstractSocket>
|
||||
|
||||
class Game;
|
||||
|
||||
class MessageLogWidget : public QTextEdit {
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
void logConnecting(QString hostname);
|
||||
void logConnected(const QStringList WelcomeMsg);
|
||||
void logDisconnected();
|
||||
void logSocketError(const QString &errorString);
|
||||
private slots:
|
||||
void logPlayerListReceived(QStringList players);
|
||||
void logJoin(QString playerName);
|
||||
void logLeave(QString playerName);
|
||||
void logReadyStart(QString playerName);
|
||||
void logGameStart();
|
||||
void logSay(QString playerName, QString message);
|
||||
void logShuffle(QString playerName);
|
||||
void logRollDice(QString playerName, int sides, int roll);
|
||||
void logDraw(QString playerName, int number);
|
||||
void logMoveCard(QString playerName, QString cardName, QString startZone, QString targetZone);
|
||||
void logCreateToken(QString playerName, QString cardName);
|
||||
void logSetCardCounters(QString playerName, QString cardName, int value, int oldValue);
|
||||
void logSetTapped(QString playerName, QString cardName, bool tapped);
|
||||
void logSetCounter(QString playerName, QString counterName, int value, int oldValue);
|
||||
void logDumpZone(QString playerName, QString zoneName, QString zoneOwner, int numberCards);
|
||||
private:
|
||||
void appendAndScroll(const QString &s);
|
||||
public:
|
||||
void connectToGame(Game *game);
|
||||
MessageLogWidget(QWidget *parent = 0);
|
||||
};
|
||||
|
||||
#endif
|
||||
19
cockatrice/src/pendingcommand.h
Normal file
19
cockatrice/src/pendingcommand.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef PENDINGCOMMAND_H
|
||||
#define PENDINGCOMMAND_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class PendingCommand {
|
||||
private:
|
||||
QString cmd;
|
||||
int msgid;
|
||||
int time;
|
||||
public:
|
||||
int getMsgId() const { return msgid; }
|
||||
QString getCmd() const { return cmd; }
|
||||
bool timeout() const { return time > 5; }
|
||||
void incTime() { ++time; }
|
||||
PendingCommand(const QString &_cmd, int _msgid) : cmd(_cmd), msgid(_msgid), time(0) { }
|
||||
};
|
||||
|
||||
#endif
|
||||
296
cockatrice/src/player.cpp
Normal file
296
cockatrice/src/player.cpp
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "handzone.h"
|
||||
#include "tablezone.h"
|
||||
#include "libraryzone.h"
|
||||
#include "gravezone.h"
|
||||
#include "rfgzone.h"
|
||||
#include "sideboardzone.h"
|
||||
#include <QMenu>
|
||||
|
||||
Player::Player(const QString &_name, int _id, QPointF _base, bool _local, CardDatabase *_db, Client *_client)
|
||||
: QObject(), defaultNumberTopCards(3), name(_name), id(_id), base(_base), local(_local), db(_db), client(_client)
|
||||
{
|
||||
LibraryZone *deck = new LibraryZone(this);
|
||||
deck->setPos(_base);
|
||||
|
||||
// XXX
|
||||
qreal foo = deck->boundingRect().height();
|
||||
|
||||
GraveZone *grave = new GraveZone(this);
|
||||
grave->setPos(_base + QPointF(0, foo));
|
||||
|
||||
RfgZone *rfg = new RfgZone(this);
|
||||
rfg->setPos(_base + QPointF(0, 2 * foo));
|
||||
|
||||
SideboardZone *sb = new SideboardZone(this);
|
||||
sb->setPos(_base + QPointF(0, 3 * foo));
|
||||
|
||||
Counter *life = new Counter(this, "life");
|
||||
life->setPos(_base + QPointF(-50, 5 * foo));
|
||||
|
||||
_base += QPointF(deck->boundingRect().width(), 0);
|
||||
|
||||
PlayerZone *hand = new HandZone(this);
|
||||
hand->setPos(_base);
|
||||
_base += QPointF(hand->boundingRect().width(), 0);
|
||||
|
||||
PlayerZone *table = new TableZone(this);
|
||||
table->setPos(_base);
|
||||
|
||||
aMoveHandToTopLibrary = new QAction(tr("Move to &top of library"), this);
|
||||
connect(aMoveHandToTopLibrary, SIGNAL(triggered()), this, SLOT(actMoveHandToTopLibrary()));
|
||||
aMoveHandToBottomLibrary = new QAction(tr("Move to &bottom of library"), this);
|
||||
connect(aMoveHandToBottomLibrary, SIGNAL(triggered()), this, SLOT(actMoveHandToBottomLibrary()));
|
||||
|
||||
aViewLibrary = new QAction(tr("&View library"), this);
|
||||
if (local)
|
||||
aViewLibrary->setShortcut(tr("F5"));
|
||||
connect(aViewLibrary, SIGNAL(triggered()), this, SLOT(actViewLibrary()));
|
||||
aViewTopCards = new QAction(tr("View &top cards of library..."), this);
|
||||
connect(aViewTopCards, SIGNAL(triggered()), this, SLOT(actViewTopCards()));
|
||||
|
||||
aViewGraveyard = new QAction(tr("&View graveyard"), this);
|
||||
if (local)
|
||||
aViewGraveyard->setShortcut(tr("F6"));
|
||||
connect(aViewGraveyard, SIGNAL(triggered()), this, SLOT(actViewGraveyard()));
|
||||
|
||||
aViewRfg = new QAction(tr("&View removed cards"), this);
|
||||
connect(aViewRfg, SIGNAL(triggered()), this, SLOT(actViewRfg()));
|
||||
|
||||
aViewSideboard = new QAction(tr("&View sideboard"), this);
|
||||
connect(aViewSideboard, SIGNAL(triggered()), this, SLOT(actViewSideboard()));
|
||||
|
||||
playerMenu = new QMenu(tr("Player \"%1\"").arg(name));
|
||||
|
||||
QMenu *handMenu = playerMenu->addMenu(tr("&Hand"));
|
||||
handMenu->addAction(aMoveHandToTopLibrary);
|
||||
handMenu->addAction(aMoveHandToBottomLibrary);
|
||||
hand->setMenu(handMenu);
|
||||
|
||||
QMenu *libraryMenu = playerMenu->addMenu(tr("&Library"));
|
||||
libraryMenu->addAction(aViewLibrary);
|
||||
libraryMenu->addAction(aViewTopCards);
|
||||
deck->setMenu(libraryMenu);
|
||||
|
||||
QMenu *graveMenu = playerMenu->addMenu(tr("&Graveyard"));
|
||||
graveMenu->addAction(aViewGraveyard);
|
||||
grave->setMenu(graveMenu);
|
||||
|
||||
QMenu *rfgMenu = playerMenu->addMenu(tr("&Removed cards"));
|
||||
rfgMenu->addAction(aViewRfg);
|
||||
rfg->setMenu(rfgMenu);
|
||||
|
||||
QMenu *sbMenu = playerMenu->addMenu(tr("&Sideboard"));
|
||||
sbMenu->addAction(aViewSideboard);
|
||||
sb->setMenu(sbMenu);
|
||||
}
|
||||
|
||||
Player::~Player()
|
||||
{
|
||||
qDebug("Player destructor");
|
||||
|
||||
for (int i = 0; i < zones.size(); i++)
|
||||
delete zones.at(i);
|
||||
|
||||
for (int i = 0; i < counters.size(); i++)
|
||||
delete counters.at(i);
|
||||
}
|
||||
|
||||
void Player::actMoveHandToTopLibrary()
|
||||
{
|
||||
PlayerZone *library = zones.findZone("deck");
|
||||
zones.findZone("hand")->moveAllToZone(library->getName(), 0);
|
||||
}
|
||||
|
||||
void Player::actMoveHandToBottomLibrary()
|
||||
{
|
||||
PlayerZone *library = zones.findZone("deck");
|
||||
zones.findZone("hand")->moveAllToZone(library->getName(), library->getCards()->size());
|
||||
}
|
||||
|
||||
void Player::actViewLibrary()
|
||||
{
|
||||
emit addZoneView(this, "deck", 0);
|
||||
}
|
||||
|
||||
void Player::actViewTopCards()
|
||||
{
|
||||
bool ok;
|
||||
int number = QInputDialog::getInteger(0, tr("View top cards of library"), tr("Number of cards:"), defaultNumberTopCards, 1, 2000000000, 1, &ok);
|
||||
if (ok) {
|
||||
defaultNumberTopCards = number;
|
||||
emit addZoneView(this, "deck", number);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::actViewGraveyard()
|
||||
{
|
||||
emit addZoneView(this, "grave", 0);
|
||||
}
|
||||
|
||||
void Player::actViewRfg()
|
||||
{
|
||||
emit addZoneView(this, "rfg", 0);
|
||||
}
|
||||
|
||||
void Player::actViewSideboard()
|
||||
{
|
||||
emit addZoneView(this, "sb", 0);
|
||||
}
|
||||
|
||||
void Player::addZone(PlayerZone *z)
|
||||
{
|
||||
zones << z;
|
||||
}
|
||||
|
||||
void Player::addCounter(Counter *c)
|
||||
{
|
||||
counters << c;
|
||||
}
|
||||
|
||||
void Player::gameEvent(ServerEventData *event)
|
||||
{
|
||||
QStringList data = event->getEventData();
|
||||
switch (event->getEventType()) {
|
||||
case eventSetupZones: {
|
||||
// XXX Life counter
|
||||
int life = data[0].toInt();
|
||||
int deck_cards = data[1].toInt();
|
||||
int sb_cards = data[2].toInt();
|
||||
// XXX Fehlerbehandlung
|
||||
|
||||
// Clean up existing zones first
|
||||
for (int i = 0; i < zones.size(); i++)
|
||||
zones.at(i)->clearContents();
|
||||
|
||||
Counter *lifeCounter = counters.findCounter("life");
|
||||
lifeCounter->setValue(life);
|
||||
|
||||
PlayerZone *deck = zones.findZone("deck");
|
||||
for (; deck_cards; deck_cards--)
|
||||
deck->addCard(new CardItem(db, QString(), -1));
|
||||
deck->reorganizeCards();
|
||||
|
||||
PlayerZone *sb = zones.findZone("sb");
|
||||
for (; sb_cards; sb_cards--)
|
||||
sb->addCard(new CardItem(db, QString(), -1));
|
||||
sb->reorganizeCards();
|
||||
|
||||
break;
|
||||
}
|
||||
case eventDraw: {
|
||||
PlayerZone *deck = zones.findZone("deck");
|
||||
PlayerZone *hand = zones.findZone("hand");
|
||||
if (!event->getPublic()) {
|
||||
hand->addCard(deck->takeCard(0, data[0].toInt(), data[1]));
|
||||
} else {
|
||||
int number = data[0].toInt();
|
||||
for (; number; number--)
|
||||
hand->addCard(deck->takeCard(0, -1, QString()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eventMoveCard: {
|
||||
if (data.size() != 7) {
|
||||
qDebug("error");
|
||||
// XXX
|
||||
}
|
||||
int cardId = data[0].toInt();
|
||||
QString cardName = data[1];
|
||||
PlayerZone *startZone = zones.findZone(data[2]);
|
||||
if (!startZone)
|
||||
qDebug(QString("start zone invalid: %1").arg(data[2]).toLatin1());
|
||||
int position = data[3].toInt();
|
||||
PlayerZone *targetZone = zones.findZone(data[4]);
|
||||
if (!targetZone)
|
||||
qDebug(QString("target zone invalid: %1").arg(data[4]).toLatin1());
|
||||
int x = data[5].toInt();
|
||||
int y = data[6].toInt();
|
||||
// XXX Mehr Fehlerbehandlung
|
||||
|
||||
CardItem *card = startZone->takeCard(position, cardId, cardName);
|
||||
if (!card) // XXX
|
||||
qDebug("null");
|
||||
|
||||
card->deleteDragItem();
|
||||
|
||||
// The log event has to be sent before the card is added to the target zone
|
||||
// because the addCard function can modify the card object.
|
||||
emit logMoveCard(name, card->getName(), startZone->getName(), targetZone->getName());
|
||||
|
||||
targetZone->addCard(card, true, x, y);
|
||||
|
||||
break;
|
||||
}
|
||||
case eventCreateToken: {
|
||||
// zone, cardid, cardname, powtough, x, y
|
||||
if (data.size() != 6) {
|
||||
qDebug("error");
|
||||
}
|
||||
PlayerZone *zone = zones.findZone(data[0]);
|
||||
int cardid = data[1].toInt();
|
||||
QString cardname = data[2];
|
||||
QString powtough = data[3];
|
||||
int x = data[4].toInt();
|
||||
int y = data[5].toInt();
|
||||
|
||||
CardItem *card = new CardItem(db, cardname, cardid);
|
||||
|
||||
emit logCreateToken(name, card->getName());
|
||||
zone->addCard(card, true, x, y);
|
||||
|
||||
break;
|
||||
}
|
||||
case eventSetCardAttr: {
|
||||
if (data.size() != 4) {
|
||||
// XXX
|
||||
}
|
||||
PlayerZone *zone = zones.findZone(data[0]);
|
||||
int cardId = data[1].toInt();
|
||||
CardItem *card = zone->getCard(cardId, "");
|
||||
QString aname = data[2];
|
||||
QString avalue = data[3];
|
||||
// XXX Fehlerbehandlung
|
||||
|
||||
if (aname == "tapped") {
|
||||
bool tapped = avalue == "1";
|
||||
emit logSetTapped(name, card->getName(), tapped);
|
||||
card->setTapped(tapped);
|
||||
} else if (aname == "attacking")
|
||||
card->setAttacking(avalue == "1");
|
||||
else if (aname == "facedown")
|
||||
card->setFacedown(avalue == "1");
|
||||
else if (aname == "counters") {
|
||||
int value = avalue.toInt();
|
||||
emit logSetCardCounters(name, card->getName(), value, card->getCounters());
|
||||
card->setCounters(value);
|
||||
} else if (aname == "annotation")
|
||||
card->setAnnotation(avalue);
|
||||
break;
|
||||
}
|
||||
case eventSetCounter: {
|
||||
if (data.size() != 2) {
|
||||
// XXX
|
||||
}
|
||||
int value = data[1].toInt();
|
||||
Counter *c = counters.findCounter(data[0]);
|
||||
int oldValue = c->getValue();
|
||||
c->setValue(value);
|
||||
emit logSetCounter(name, c->getName(), value, oldValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qDebug("unhandled player event");
|
||||
}
|
||||
}
|
||||
|
||||
void Player::hoverCardEvent(CardItem *card)
|
||||
{
|
||||
emit hoverCard(card->getName());
|
||||
}
|
||||
|
||||
void Player::showCardMenu(const QPoint &p)
|
||||
{
|
||||
emit sigShowCardMenu(p);
|
||||
}
|
||||
71
cockatrice/src/player.h
Normal file
71
cockatrice/src/player.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef PLAYER_H
|
||||
#define PLAYER_H
|
||||
|
||||
#include <QInputDialog>
|
||||
#include <QPoint>
|
||||
#include "zonelist.h"
|
||||
#include "counterlist.h"
|
||||
#include "servereventdata.h"
|
||||
|
||||
class Client;
|
||||
class CardDatabase;
|
||||
class QMenu;
|
||||
class QAction;
|
||||
|
||||
class Player : public QObject {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void moveCard(int cardId, QString startZone, QString targetZone, int x, int y);
|
||||
void hoverCard(QString name);
|
||||
void addZoneView(Player *player, QString zoneName, int number);
|
||||
void sigShowCardMenu(QPoint p);
|
||||
// Log events
|
||||
void logMoveCard(QString playerName, QString cardName, QString startZone, QString targetZone);
|
||||
void logCreateToken(QString playerName, QString cardName);
|
||||
void logSetCardCounters(QString playerName, QString cardName, int value, int oldValue);
|
||||
void logSetTapped(QString playerName, QString cardName, bool tapped);
|
||||
void logSetCounter(QString playerName, QString counterName, int value, int oldValue);
|
||||
private slots:
|
||||
void actMoveHandToTopLibrary();
|
||||
void actMoveHandToBottomLibrary();
|
||||
|
||||
void actViewLibrary();
|
||||
void actViewTopCards();
|
||||
|
||||
void actViewGraveyard();
|
||||
|
||||
void actViewRfg();
|
||||
|
||||
void actViewSideboard();
|
||||
private:
|
||||
QMenu *playerMenu;
|
||||
QAction *aMoveHandToTopLibrary, *aMoveHandToBottomLibrary,
|
||||
*aViewLibrary, *aViewTopCards, *aViewGraveyard, *aViewRfg, *aViewSideboard;
|
||||
|
||||
int defaultNumberTopCards;
|
||||
QString name;
|
||||
int id;
|
||||
QPointF base;
|
||||
bool local;
|
||||
ZoneList zones;
|
||||
CounterList counters;
|
||||
CardDatabase *db;
|
||||
public:
|
||||
Client *client;
|
||||
void addZone(PlayerZone *z);
|
||||
void addCounter(Counter *c);
|
||||
Player(const QString &_name, int _id, QPointF _base, bool _local, CardDatabase *_db, Client *_client);
|
||||
~Player();
|
||||
QMenu *getPlayerMenu() const { return playerMenu; }
|
||||
int getId() const { return id; }
|
||||
QString getName() const { return name; }
|
||||
bool getLocal() const { return local; }
|
||||
const ZoneList *const getZones() const { return &zones; }
|
||||
const CounterList *const getCounters() const { return &counters; }
|
||||
void gameEvent(ServerEventData *event);
|
||||
void hoverCardEvent(CardItem *card);
|
||||
CardDatabase *getDb() const { return db; }
|
||||
void showCardMenu(const QPoint &p);
|
||||
};
|
||||
|
||||
#endif
|
||||
11
cockatrice/src/playerlist.cpp
Normal file
11
cockatrice/src/playerlist.cpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include "playerlist.h"
|
||||
|
||||
Player *PlayerList::findPlayer(int id) const
|
||||
{
|
||||
for (int i = 0; i < size(); i++) {
|
||||
Player *temp = at(i);
|
||||
if (temp->getId() == id)
|
||||
return temp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
12
cockatrice/src/playerlist.h
Normal file
12
cockatrice/src/playerlist.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef PLAYERLIST_H
|
||||
#define PLAYERLIST_H
|
||||
|
||||
#include "player.h"
|
||||
#include <QList>
|
||||
|
||||
class PlayerList : public QList<Player *> {
|
||||
public:
|
||||
Player *findPlayer(int id) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
98
cockatrice/src/playerzone.cpp
Normal file
98
cockatrice/src/playerzone.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#include <QtGui>
|
||||
#include "playerzone.h"
|
||||
#include "carditem.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "zoneviewzone.h"
|
||||
|
||||
PlayerZone::PlayerZone(Player *_p, const QString &_name, QGraphicsItem *parent, bool isView)
|
||||
: QGraphicsItem(parent), player(_p), name(_name), cards(NULL), menu(NULL), hasCardAttr(false)
|
||||
{
|
||||
if (!isView)
|
||||
player->addZone(this);
|
||||
}
|
||||
|
||||
PlayerZone::~PlayerZone()
|
||||
{
|
||||
qDebug(QString("PlayerZone destructor: %1").arg(name).toLatin1());
|
||||
while (!views.empty())
|
||||
delete views.at(0);
|
||||
|
||||
clearContents();
|
||||
delete cards;
|
||||
}
|
||||
|
||||
void PlayerZone::clearContents()
|
||||
{
|
||||
for (int i = 0; i < cards->size(); i++)
|
||||
delete cards->at(i);
|
||||
cards->clear();
|
||||
}
|
||||
|
||||
void PlayerZone::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::RightButton) {
|
||||
if (menu) {
|
||||
menu->exec(event->screenPos());
|
||||
event->accept();
|
||||
} else
|
||||
event->ignore();
|
||||
} else
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
CardItem *PlayerZone::getCard(int cardId, const QString &cardName)
|
||||
{
|
||||
CardItem *c = cards->findCard(cardId, false);
|
||||
// If the card's id is -1, this zone is invisible,
|
||||
// so we need to give the card an id and a name as it comes out.
|
||||
// It can be assumed that in an invisible zone, all cards are equal.
|
||||
if ((c->getId() == -1) || (c->getName().isEmpty())) {
|
||||
c->setId(cardId);
|
||||
c->setName(cardName);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
CardItem *PlayerZone::takeCard(int position, int cardId, const QString &cardName)
|
||||
{
|
||||
CardItem *c = cards->takeAt(position);
|
||||
for (int i = 0; i < views.size(); i++)
|
||||
views[i]->removeCard(position);
|
||||
|
||||
if (c->getId() == -1) {
|
||||
c->setId(cardId);
|
||||
c->setName(cardName);
|
||||
}
|
||||
reorganizeCards();
|
||||
return c;
|
||||
}
|
||||
|
||||
void PlayerZone::setCardAttr(int cardId, const QString &aname, const QString &avalue)
|
||||
{
|
||||
if (hasCardAttr)
|
||||
player->client->setCardAttr(name, cardId, aname, avalue);
|
||||
}
|
||||
|
||||
void PlayerZone::hoverCardEvent(CardItem *card)
|
||||
{
|
||||
player->hoverCardEvent(card);
|
||||
}
|
||||
|
||||
void PlayerZone::addView(ZoneViewZone *view)
|
||||
{
|
||||
views.append(view);
|
||||
}
|
||||
|
||||
void PlayerZone::removeView(ZoneViewZone *view)
|
||||
{
|
||||
views.removeAt(views.indexOf(view));
|
||||
}
|
||||
|
||||
void PlayerZone::moveAllToZone(const QString &targetZone, int targetX)
|
||||
{
|
||||
// Cards need to be moved in reverse order so that the other
|
||||
// cards' list index doesn't change
|
||||
for (int i = cards->size() - 1; i >= 0; i--)
|
||||
player->client->moveCard(cards->at(i)->getId(), getName(), targetZone, targetX);
|
||||
}
|
||||
47
cockatrice/src/playerzone.h
Normal file
47
cockatrice/src/playerzone.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef PLAYERZONE_H
|
||||
#define PLAYERZONE_H
|
||||
|
||||
#include <QString>
|
||||
#include "cardlist.h"
|
||||
|
||||
class Player;
|
||||
class ZoneViewZone;
|
||||
class QMenu;
|
||||
|
||||
class PlayerZone : public QGraphicsItem {
|
||||
protected:
|
||||
Player *player;
|
||||
QString name;
|
||||
CardList *cards;
|
||||
QList<ZoneViewZone *> views;
|
||||
QMenu *menu;
|
||||
bool hasCardAttr;
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
public:
|
||||
enum { Type = typeZone };
|
||||
int type() const { return Type; }
|
||||
virtual void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint) = 0;
|
||||
PlayerZone(Player *_player, const QString &_name, QGraphicsItem *parent = 0, bool isView = false);
|
||||
~PlayerZone();
|
||||
void clearContents();
|
||||
bool getHasCardAttr() const { return hasCardAttr; }
|
||||
QMenu *getMenu() const { return menu; }
|
||||
void setMenu(QMenu *_menu) { menu = _menu; }
|
||||
QString getName() const { return name; }
|
||||
Player *getPlayer() const { return player; }
|
||||
bool contentsKnown() const { return cards->getContentsKnown(); }
|
||||
CardList *const getCards() const { return cards; }
|
||||
virtual void addCard(CardItem *card, bool reorganize = true, int x = -1, int y = -1) = 0;
|
||||
// getCard() finds a card by id.
|
||||
CardItem *getCard(int cardId, const QString &cardName);
|
||||
// takeCard() finds a card by position and removes it from the zone and from all of its views.
|
||||
CardItem *takeCard(int position, int cardId, const QString &cardName);
|
||||
void setCardAttr(int cardId, const QString &aname, const QString &avalue);
|
||||
void hoverCardEvent(CardItem *card);
|
||||
void addView(ZoneViewZone *view);
|
||||
void removeView(ZoneViewZone *view);
|
||||
virtual void reorganizeCards() = 0;
|
||||
void moveAllToZone(const QString &targetZone, int targetX);
|
||||
};
|
||||
|
||||
#endif
|
||||
53
cockatrice/src/rfgzone.cpp
Normal file
53
cockatrice/src/rfgzone.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#include <QtGui>
|
||||
#include "rfgzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "zoneviewzone.h"
|
||||
|
||||
RfgZone::RfgZone(Player *_p)
|
||||
: PlayerZone(_p, "rfg")
|
||||
{
|
||||
cards = new CardList(true);
|
||||
}
|
||||
|
||||
QRectF RfgZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 50, 50);
|
||||
}
|
||||
|
||||
void RfgZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->save();
|
||||
painter->fillRect(boundingRect(), QColor("white"));
|
||||
painter->setFont(QFont("Times", 20, QFont::Bold));
|
||||
painter->setPen(QPen(QColor("black")));
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(cards->size()));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void RfgZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
for (int i = 0; i < views.size(); i++)
|
||||
views[i]->addCard(new CardItem(player->getDb(), card->getName(), card->getId()), reorganize, x, y);
|
||||
|
||||
cards->insert(x, card);
|
||||
card->setPos(0, 0);
|
||||
card->setVisible(false);
|
||||
card->resetState();
|
||||
card->setParentItem(this);
|
||||
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void RfgZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), 0, 0);
|
||||
}
|
||||
|
||||
void RfgZone::reorganizeCards()
|
||||
{
|
||||
update(boundingRect());
|
||||
}
|
||||
17
cockatrice/src/rfgzone.h
Normal file
17
cockatrice/src/rfgzone.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef RFGZONE_H
|
||||
#define RFGZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
class RfgZone : public PlayerZone {
|
||||
private:
|
||||
public:
|
||||
RfgZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = 0, int y = -1);
|
||||
void reorganizeCards();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
};
|
||||
|
||||
#endif
|
||||
49
cockatrice/src/servereventdata.cpp
Normal file
49
cockatrice/src/servereventdata.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#include "servereventdata.h"
|
||||
|
||||
// Message structure for server events:
|
||||
// {"private","public"}|PlayerId|PlayerName|EventType|EventData
|
||||
|
||||
const int event_count = 19;
|
||||
const event_string event_strings[event_count] = {
|
||||
{eventPlayerId, "player_id"},
|
||||
{eventSay, "say"},
|
||||
{eventName, "name"},
|
||||
{eventJoin, "join"},
|
||||
{eventLeave, "leave"},
|
||||
{eventReadyStart, "ready_start"},
|
||||
{eventSetupZones, "setup_zones"},
|
||||
{eventGameStart, "game_start"},
|
||||
{eventShuffle, "shuffle"},
|
||||
{eventRollDice, "roll_dice"},
|
||||
{eventDraw, "draw"},
|
||||
{eventMoveCard, "move_card"},
|
||||
{eventCreateToken, "create_token"},
|
||||
{eventSetCardAttr, "set_card_attr"},
|
||||
{eventSetCounter, "set_counter"},
|
||||
{eventDelCounter, "del_counter"},
|
||||
{eventSetActivePlayer, "set_active_player"},
|
||||
{eventSetActivePhase, "set_active_phase"},
|
||||
{eventDumpZone, "dump_zone"}
|
||||
};
|
||||
|
||||
ServerEventData::ServerEventData(const QString &line)
|
||||
{
|
||||
QStringList values = line.split("|");
|
||||
|
||||
IsPublic = !values.takeFirst().compare("public");
|
||||
PlayerId = values.takeFirst().toInt();
|
||||
PlayerName = values.takeFirst();
|
||||
|
||||
QString type = values.takeFirst();
|
||||
bool found = false;
|
||||
for (int i = 0; i < event_count; i++)
|
||||
if (!type.compare(event_strings[i].str)) {
|
||||
EventType = event_strings[i].type;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
EventType = eventInvalid;
|
||||
|
||||
EventData = values;
|
||||
}
|
||||
54
cockatrice/src/servereventdata.h
Normal file
54
cockatrice/src/servereventdata.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef SERVEREVENTDATA_H
|
||||
#define SERVEREVENTDATA_H
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
|
||||
enum ServerEventType {
|
||||
eventInvalid,
|
||||
eventPlayerId,
|
||||
eventSay,
|
||||
eventName,
|
||||
eventJoin,
|
||||
eventLeave,
|
||||
eventReadyStart,
|
||||
eventSetupZones,
|
||||
eventGameStart,
|
||||
eventShuffle,
|
||||
eventRollDice,
|
||||
eventDraw,
|
||||
eventMoveCard,
|
||||
eventCreateToken,
|
||||
eventSetCardAttr,
|
||||
eventSetCounter,
|
||||
eventDelCounter,
|
||||
eventSetActivePlayer,
|
||||
eventSetActivePhase,
|
||||
eventDumpZone
|
||||
};
|
||||
|
||||
struct event_string {
|
||||
ServerEventType type;
|
||||
char *str;
|
||||
};
|
||||
|
||||
extern const int event_count;
|
||||
extern const event_string event_strings[];
|
||||
|
||||
class ServerEventData {
|
||||
private:
|
||||
bool IsPublic;
|
||||
int PlayerId;
|
||||
QString PlayerName;
|
||||
ServerEventType EventType;
|
||||
QStringList EventData;
|
||||
public:
|
||||
ServerEventData(const QString &line);
|
||||
bool getPublic() { return IsPublic; }
|
||||
int getPlayerId() { return PlayerId; }
|
||||
QString getPlayerName() { return PlayerName; }
|
||||
ServerEventType getEventType() { return EventType; }
|
||||
QStringList getEventData() { return EventData; }
|
||||
};
|
||||
|
||||
#endif
|
||||
21
cockatrice/src/servergame.h
Normal file
21
cockatrice/src/servergame.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef SERVERGAME_H
|
||||
#define SERVERGAME_H
|
||||
|
||||
class ServerGame {
|
||||
private:
|
||||
QString name;
|
||||
QString description;
|
||||
bool hasPassword;
|
||||
unsigned char playerCount;
|
||||
unsigned char maxPlayers;
|
||||
public:
|
||||
ServerGame(const QString &_name, const QString &_description, bool _hasPassword, unsigned char _playerCount, unsigned char _maxPlayers)
|
||||
: name(_name), description(_description), hasPassword(_hasPassword), playerCount(_playerCount), maxPlayers(_maxPlayers) { }
|
||||
QString getName() { return name; }
|
||||
QString getDescription() { return description; }
|
||||
bool getHasPassword() { return hasPassword; }
|
||||
unsigned char getPlayerCount() { return playerCount; }
|
||||
unsigned char getMaxPlayers() { return maxPlayers; }
|
||||
};
|
||||
|
||||
#endif
|
||||
17
cockatrice/src/serverplayer.h
Normal file
17
cockatrice/src/serverplayer.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef SERVERPLAYER_H
|
||||
#define SERVERPLAYER_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class ServerPlayer {
|
||||
private:
|
||||
int PlayerId;
|
||||
QString name;
|
||||
public:
|
||||
ServerPlayer(int _PlayerId, const QString &_name)
|
||||
: PlayerId(_PlayerId), name(_name) { }
|
||||
int getPlayerId() { return PlayerId; }
|
||||
QString getName() { return name; }
|
||||
};
|
||||
|
||||
#endif
|
||||
22
cockatrice/src/serverresponse.h
Normal file
22
cockatrice/src/serverresponse.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef SERVERRESPONSE_H
|
||||
#define SERVERRESPONSE_H
|
||||
|
||||
enum ServerErrorMessage {
|
||||
msgNone,
|
||||
msgSyntaxError
|
||||
};
|
||||
|
||||
class ServerResponse {
|
||||
private:
|
||||
int msgId;
|
||||
bool ok;
|
||||
ServerErrorMessage message;
|
||||
public:
|
||||
ServerResponse(int _msgId, bool _ok, ServerErrorMessage _message)
|
||||
: msgId(_msgId), ok(_ok), message(_message) { }
|
||||
int getMsgId() { return msgId; }
|
||||
bool getOk() { return ok; }
|
||||
ServerErrorMessage getMessage() { return message; }
|
||||
};
|
||||
|
||||
#endif
|
||||
21
cockatrice/src/serverzone.h
Normal file
21
cockatrice/src/serverzone.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef SERVERZONE_H
|
||||
#define SERVERZONE_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class ServerZone {
|
||||
private:
|
||||
QString name;
|
||||
bool isPublic;
|
||||
bool hasCoords;
|
||||
int cardCount;
|
||||
public:
|
||||
ServerZone(const QString &_name, bool _isPublic, bool _hasCoords, int _cardCount)
|
||||
: name(_name), isPublic(_isPublic), hasCoords(_hasCoords), cardCount(_cardCount) { }
|
||||
QString getName() const { return name; }
|
||||
bool getPublic() const { return isPublic; }
|
||||
bool getHasCoords() const { return hasCoords; }
|
||||
int getCardCount() const { return cardCount; }
|
||||
};
|
||||
|
||||
#endif
|
||||
28
cockatrice/src/serverzonecard.h
Normal file
28
cockatrice/src/serverzonecard.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef SERVERZONECARD_H
|
||||
#define SERVERZONECARD_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class ServerZoneCard {
|
||||
private:
|
||||
int id;
|
||||
QString name;
|
||||
int x, y;
|
||||
int counters;
|
||||
bool tapped;
|
||||
bool attacking;
|
||||
QString annotation;
|
||||
public:
|
||||
ServerZoneCard(int _id, const QString &_name, int _x, int _y, int _counters, bool _attacking, const QString &_annotation)
|
||||
: id(_id), name(_name), x(_x), y(_y), counters(_counters), attacking(_attacking), annotation(_annotation) { }
|
||||
int getId() const { return id; }
|
||||
QString getName() const { return name; }
|
||||
int getX() const { return x; }
|
||||
int getY() const { return y; }
|
||||
int getCounters() const { return counters; }
|
||||
bool getTapped() const { return tapped; }
|
||||
bool getAttacking() const { return attacking; }
|
||||
QString getAnnotation() const { return annotation; }
|
||||
};
|
||||
|
||||
#endif
|
||||
54
cockatrice/src/sideboardzone.cpp
Normal file
54
cockatrice/src/sideboardzone.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#include <QtGui>
|
||||
#include "sideboardzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "zoneviewzone.h"
|
||||
|
||||
SideboardZone::SideboardZone(Player *_p)
|
||||
: PlayerZone(_p, "sb")
|
||||
{
|
||||
cards = new CardList(false);
|
||||
}
|
||||
|
||||
QRectF SideboardZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, 50, 50);
|
||||
}
|
||||
|
||||
void SideboardZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->save();
|
||||
painter->fillRect(boundingRect(), QColor("blue"));
|
||||
painter->setFont(QFont("Times", 20, QFont::Bold));
|
||||
painter->setPen(QPen(QColor("black")));
|
||||
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(cards->size()));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void SideboardZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
for (int i = 0; i < views.size(); i++)
|
||||
views[i]->addCard(new CardItem(player->getDb(), card->getName(), card->getId()), reorganize, x, y);
|
||||
|
||||
cards->insert(x, card);
|
||||
card->setPos(0, 0);
|
||||
card->setVisible(false);
|
||||
card->resetState();
|
||||
card->setParentItem(this);
|
||||
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void SideboardZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), 0, 0);
|
||||
}
|
||||
|
||||
void SideboardZone::reorganizeCards()
|
||||
{
|
||||
update(boundingRect());
|
||||
}
|
||||
|
||||
17
cockatrice/src/sideboardzone.h
Normal file
17
cockatrice/src/sideboardzone.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef SIDEBOARDZONE_H
|
||||
#define SIDEBOARDZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
class SideboardZone : public PlayerZone {
|
||||
private:
|
||||
public:
|
||||
SideboardZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = 0, int y = -1);
|
||||
void reorganizeCards();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
};
|
||||
|
||||
#endif
|
||||
56
cockatrice/src/tablezone.cpp
Normal file
56
cockatrice/src/tablezone.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include <QtGui>
|
||||
#include "tablezone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
|
||||
TableZone::TableZone(Player *_p)
|
||||
: PlayerZone(_p, "table"), width(700), height(500)
|
||||
{
|
||||
cards = new CardList(true);
|
||||
hasCardAttr = true;
|
||||
}
|
||||
|
||||
QRectF TableZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, width, height);
|
||||
}
|
||||
|
||||
void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
painter->fillRect(boundingRect(), QColor("blue"));
|
||||
}
|
||||
|
||||
void TableZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
Q_UNUSED(reorganize);
|
||||
cards->append(card);
|
||||
if ((x != -1) && (y != -1)) {
|
||||
if (!player->getLocal())
|
||||
y = height - CARD_HEIGHT - y;
|
||||
card->setPos(x, y);
|
||||
}
|
||||
card->setZValue((y + CARD_HEIGHT) * width + x + 1000);
|
||||
card->setParentItem(this);
|
||||
card->setVisible(true);
|
||||
card->update(card->boundingRect());
|
||||
}
|
||||
|
||||
void TableZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), dropPoint.x(), dropPoint.y());
|
||||
}
|
||||
|
||||
void TableZone::reorganizeCards()
|
||||
{
|
||||
}
|
||||
|
||||
void TableZone::toggleTapped()
|
||||
{
|
||||
QListIterator<QGraphicsItem *> i(scene()->selectedItems());
|
||||
while (i.hasNext()) {
|
||||
CardItem *temp = (CardItem *) i.next();
|
||||
setCardAttr(temp->getId(), "tapped", temp->getTapped() ? "0" : "1");
|
||||
}
|
||||
}
|
||||
22
cockatrice/src/tablezone.h
Normal file
22
cockatrice/src/tablezone.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef TABLEZONE_H
|
||||
#define TABLEZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
|
||||
const int GRID_WIDTH = 30;
|
||||
const int GRID_HEIGHT = 30;
|
||||
|
||||
class TableZone : public PlayerZone {
|
||||
private:
|
||||
int width, height;
|
||||
public:
|
||||
TableZone(Player *_p);
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = -1, int y = -1);
|
||||
void reorganizeCards();
|
||||
void toggleTapped();
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
};
|
||||
|
||||
#endif
|
||||
258
cockatrice/src/window.cpp
Normal file
258
cockatrice/src/window.cpp
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@gmx.net *
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include <QtGui>
|
||||
#include <QtOpenGL>
|
||||
|
||||
#include "window.h"
|
||||
#include "dlg_connect.h"
|
||||
#include "dlg_games.h"
|
||||
#include "cardinfowidget.h"
|
||||
#include "messagelogwidget.h"
|
||||
|
||||
#include "gameview.h"
|
||||
#include "player.h"
|
||||
#include "game.h"
|
||||
#include "carddatabase.h"
|
||||
#include "zoneviewzone.h"
|
||||
#include "zoneviewwidget.h"
|
||||
#include "zoneviewlayout.h"
|
||||
|
||||
void MainWindow::hoverCard(QString name)
|
||||
{
|
||||
cardInfo->setCard(name);
|
||||
}
|
||||
|
||||
void MainWindow::playerAdded(Player *player)
|
||||
{
|
||||
menuBar()->addMenu(player->getPlayerMenu());
|
||||
connect(player, SIGNAL(addZoneView(Player *, QString, int)), zoneLayout, SLOT(addItem(Player *, QString, int)));
|
||||
}
|
||||
|
||||
void MainWindow::playerRemoved(Player *player)
|
||||
{
|
||||
menuBar()->removeAction(player->getPlayerMenu()->menuAction());
|
||||
}
|
||||
|
||||
void MainWindow::statusChanged(ProtocolStatus _status)
|
||||
{
|
||||
switch (_status) {
|
||||
case StatusConnecting:
|
||||
emit logConnecting(client->peerName());
|
||||
break;
|
||||
case StatusDisconnected:
|
||||
if (game) {
|
||||
delete game;
|
||||
game = 0;
|
||||
}
|
||||
aDisconnect->setEnabled(false);
|
||||
aGames->setEnabled(false);
|
||||
aRestartGame->setEnabled(false);
|
||||
aLeaveGame->setEnabled(false);
|
||||
emit logDisconnected();
|
||||
break;
|
||||
case StatusConnected:
|
||||
aDisconnect->setEnabled(true);
|
||||
aGames->setEnabled(true);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
void MainWindow::actConnect()
|
||||
{
|
||||
DlgConnect dlg(this);
|
||||
if (dlg.exec())
|
||||
client->connectToServer(dlg.getHost(), dlg.getPort(), dlg.getPlayerName());
|
||||
}
|
||||
|
||||
void MainWindow::actDisconnect()
|
||||
{
|
||||
client->disconnectFromServer();
|
||||
}
|
||||
|
||||
void MainWindow::actGames()
|
||||
{
|
||||
DlgGames dlg(client, this);
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void MainWindow::actLeaveGame()
|
||||
{
|
||||
client->leaveGame();
|
||||
delete game;
|
||||
game = 0;
|
||||
aRestartGame->setEnabled(false);
|
||||
aLeaveGame->setEnabled(false);
|
||||
aGames->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::actExit()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void MainWindow::updateSceneSize()
|
||||
{
|
||||
QRectF sr = scene->sceneRect();
|
||||
QSizeF zoneSize = zoneLayout->size();
|
||||
qDebug(QString("updateSceneSize: width=%1").arg(850 + zoneSize.width()).toLatin1());
|
||||
scene->setSceneRect(sr.x(), sr.y(), 850 + zoneSize.width(), sr.height());
|
||||
view->scaleToScene();
|
||||
}
|
||||
|
||||
// Knöpfe
|
||||
|
||||
void MainWindow::buttonSay()
|
||||
{
|
||||
client->say(sayEdit->text());
|
||||
sayEdit->clear();
|
||||
}
|
||||
|
||||
void MainWindow::playerIdReceived(int id, QString name)
|
||||
{
|
||||
game = new Game(db, client, scene, actionsMenu, cardMenu, id, name);
|
||||
connect(game, SIGNAL(submitDecklist()), this, SLOT(decklistDialog()));
|
||||
connect(game, SIGNAL(hoverCard(QString)), this, SLOT(hoverCard(QString)));
|
||||
connect(game, SIGNAL(playerAdded(Player *)), this, SLOT(playerAdded(Player *)));
|
||||
connect(game, SIGNAL(playerRemoved(Player *)), this, SLOT(playerRemoved(Player *)));
|
||||
connect(aRestartGame, SIGNAL(triggered()), game, SLOT(restartGameDialog()));
|
||||
playerAdded(game->getLocalPlayer());
|
||||
|
||||
messageLog->connectToGame(game);
|
||||
aGames->setEnabled(false);
|
||||
aRestartGame->setEnabled(true);
|
||||
aLeaveGame->setEnabled(true);
|
||||
|
||||
client->listPlayers();
|
||||
}
|
||||
|
||||
void MainWindow::serverTimeout()
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Server timeout"));
|
||||
}
|
||||
|
||||
void MainWindow::createActions()
|
||||
{
|
||||
aConnect = new QAction(tr("&Connect..."), this);
|
||||
connect(aConnect, SIGNAL(triggered()), this, SLOT(actConnect()));
|
||||
aDisconnect = new QAction(tr("&Disconnect"), this);
|
||||
aDisconnect->setEnabled(false);
|
||||
connect(aDisconnect, SIGNAL(triggered()), this, SLOT(actDisconnect()));
|
||||
aGames = new QAction(tr("&Games..."), this);
|
||||
aGames->setEnabled(false);
|
||||
connect(aGames, SIGNAL(triggered()), this, SLOT(actGames()));
|
||||
aRestartGame = new QAction(tr("&Restart game..."), this);
|
||||
aRestartGame->setShortcut(tr("F2"));
|
||||
aRestartGame->setEnabled(false);
|
||||
aLeaveGame = new QAction(tr("&Leave game"), this);
|
||||
aLeaveGame->setEnabled(false);
|
||||
connect(aLeaveGame, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
|
||||
aExit = new QAction(tr("&Exit"), this);
|
||||
connect(aExit, SIGNAL(triggered()), this, SLOT(actExit()));
|
||||
}
|
||||
|
||||
void MainWindow::createMenus()
|
||||
{
|
||||
gameMenu = menuBar()->addMenu(tr("&Game"));
|
||||
gameMenu->addAction(aConnect);
|
||||
gameMenu->addAction(aDisconnect);
|
||||
gameMenu->addSeparator();
|
||||
gameMenu->addAction(aGames);
|
||||
gameMenu->addAction(aRestartGame);
|
||||
gameMenu->addAction(aLeaveGame);
|
||||
gameMenu->addSeparator();
|
||||
gameMenu->addAction(aExit);
|
||||
|
||||
actionsMenu = menuBar()->addMenu(tr("&Actions"));
|
||||
|
||||
cardMenu = menuBar()->addMenu(tr("&Card"));
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent), game(NULL)
|
||||
{
|
||||
// setWindowState(windowState() | Qt::WindowFullScreen);
|
||||
|
||||
QPixmapCache::setCacheLimit(200000);
|
||||
createActions();
|
||||
createMenus();
|
||||
|
||||
db = new CardDatabase;
|
||||
int cardCount = db->loadFromFile("../cards.dat");
|
||||
qDebug(QString("%1 cards loaded").arg(cardCount).toLatin1());
|
||||
|
||||
scene = new QGraphicsScene(0, 0, 850, 1000, this);
|
||||
view = new GameView(scene);
|
||||
|
||||
// view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
|
||||
// view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
|
||||
|
||||
zoneLayout = new ZoneViewLayout(db);
|
||||
zoneLayout->setPos(850, 0);
|
||||
scene->addItem(zoneLayout);
|
||||
connect(zoneLayout, SIGNAL(sizeChanged()), this, SLOT(updateSceneSize()));
|
||||
|
||||
cardInfo = new CardInfoWidget(db);
|
||||
messageLog = new MessageLogWidget;
|
||||
sayEdit = new QLineEdit;
|
||||
sayButton = new QPushButton(tr("&Say"));
|
||||
|
||||
QHBoxLayout *hLayout = new QHBoxLayout;
|
||||
hLayout->addWidget(sayEdit);
|
||||
hLayout->addWidget(sayButton);
|
||||
|
||||
QVBoxLayout *verticalLayout = new QVBoxLayout;
|
||||
verticalLayout->addWidget(cardInfo);
|
||||
verticalLayout->addWidget(messageLog);
|
||||
verticalLayout->addLayout(hLayout);
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
mainLayout->addWidget(view);
|
||||
mainLayout->setStretchFactor(view, 10);
|
||||
mainLayout->addLayout(verticalLayout);
|
||||
|
||||
QWidget *centralWidget = new QWidget;
|
||||
centralWidget->setLayout(mainLayout);
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(buttonSay()));
|
||||
connect(sayButton, SIGNAL(clicked()), this, SLOT(buttonSay()));
|
||||
|
||||
client = new Client(this);
|
||||
connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout()));
|
||||
connect(client, SIGNAL(statusChanged(ProtocolStatus)), this, SLOT(statusChanged(ProtocolStatus)));
|
||||
connect(client, SIGNAL(playerIdReceived(int, QString)), this, SLOT(playerIdReceived(int, QString)));
|
||||
|
||||
connect(this, SIGNAL(logConnecting(QString)), messageLog, SLOT(logConnecting(QString)));
|
||||
connect(client, SIGNAL(welcomeMsgReceived(const QStringList)), messageLog, SLOT(logConnected(const QStringList)));
|
||||
connect(this, SIGNAL(logDisconnected()), messageLog, SLOT(logDisconnected()));
|
||||
connect(client, SIGNAL(logSocketError(const QString &)), messageLog, SLOT(logSocketError(const QString &)));
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
delete game;
|
||||
|
||||
// db->importOracle();
|
||||
// db->saveToFile("../cards.dat");
|
||||
delete db;
|
||||
}
|
||||
85
cockatrice/src/window.h
Normal file
85
cockatrice/src/window.h
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2008 by Max-Wilhelm Bruker *
|
||||
* brukie@gmx.net *
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef WINDOW_H
|
||||
#define WINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "client.h"
|
||||
|
||||
class QGraphicsScene;
|
||||
class GameView;
|
||||
class Game;
|
||||
class CardDatabase;
|
||||
class Player;
|
||||
|
||||
class CardInfoWidget;
|
||||
class MessageLogWidget;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
class ServerZoneCard;
|
||||
class ZoneViewLayout;
|
||||
class ZoneViewWidget;
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void hoverCard(QString name);
|
||||
void playerAdded(Player *player);
|
||||
void playerRemoved(Player *player);
|
||||
void statusChanged(ProtocolStatus _status);
|
||||
void playerIdReceived(int id, QString name);
|
||||
void serverTimeout();
|
||||
|
||||
void buttonSay();
|
||||
|
||||
void actConnect();
|
||||
void actDisconnect();
|
||||
void actGames();
|
||||
void actLeaveGame();
|
||||
void actExit();
|
||||
|
||||
void updateSceneSize();
|
||||
signals:
|
||||
void logConnecting(QString hostname);
|
||||
void logDisconnected();
|
||||
private:
|
||||
void createActions();
|
||||
void createMenus();
|
||||
QMenu *gameMenu, *actionsMenu, *cardMenu;
|
||||
QAction *aConnect, *aDisconnect, *aGames, *aRestartGame, *aLeaveGame, *aExit;
|
||||
|
||||
CardInfoWidget *cardInfo;
|
||||
MessageLogWidget *messageLog;
|
||||
QLineEdit *sayEdit;
|
||||
QPushButton *sayButton;
|
||||
|
||||
Client *client;
|
||||
QGraphicsScene *scene;
|
||||
GameView *view;
|
||||
Game *game;
|
||||
CardDatabase *db;
|
||||
ZoneViewLayout *zoneLayout;
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
};
|
||||
|
||||
#endif
|
||||
18
cockatrice/src/zoneclosebutton.cpp
Normal file
18
cockatrice/src/zoneclosebutton.cpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#include <QtGui>
|
||||
#include "zoneclosebutton.h"
|
||||
|
||||
void ZoneCloseButton::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
emit triggered();
|
||||
}
|
||||
|
||||
void ZoneCloseButton::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
painter->fillRect(rect(), QColor("red"));
|
||||
}
|
||||
|
||||
ZoneCloseButton::ZoneCloseButton(QGraphicsItem *parent)
|
||||
: QGraphicsWidget(parent)
|
||||
{
|
||||
resize(20, 20);
|
||||
}
|
||||
17
cockatrice/src/zoneclosebutton.h
Normal file
17
cockatrice/src/zoneclosebutton.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef ZONECLOSEBUTTON_H
|
||||
#define ZONECLOSEBUTTON_H
|
||||
|
||||
#include <QGraphicsWidget>
|
||||
|
||||
class ZoneCloseButton : public QGraphicsWidget {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void triggered();
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
public:
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
ZoneCloseButton(QGraphicsItem *parent = 0);
|
||||
};
|
||||
|
||||
#endif
|
||||
11
cockatrice/src/zonelist.cpp
Normal file
11
cockatrice/src/zonelist.cpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include "zonelist.h"
|
||||
|
||||
PlayerZone *ZoneList::findZone(const QString &name) const
|
||||
{
|
||||
for (int i = 0; i < size(); i++) {
|
||||
PlayerZone *temp = at(i);
|
||||
if (!temp->getName().compare(name))
|
||||
return temp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
12
cockatrice/src/zonelist.h
Normal file
12
cockatrice/src/zonelist.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef ZONELIST_H
|
||||
#define ZONELIST_H
|
||||
|
||||
#include "playerzone.h"
|
||||
#include <QList>
|
||||
|
||||
class ZoneList : public QList<PlayerZone *> {
|
||||
public:
|
||||
PlayerZone *findZone(const QString &name) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
36
cockatrice/src/zoneviewlayout.cpp
Normal file
36
cockatrice/src/zoneviewlayout.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include "zoneviewlayout.h"
|
||||
#include "zoneviewwidget.h"
|
||||
#include "player.h"
|
||||
|
||||
ZoneViewLayout::ZoneViewLayout(CardDatabase *_db, QGraphicsItem *parent)
|
||||
: QGraphicsWidget(parent), db(_db)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ZoneViewLayout::reorganize()
|
||||
{
|
||||
qDebug(QString("ZoneViewLayout: activate: count=%1").arg(views.size()).toLatin1());
|
||||
resize(views.size() * 150, 1000);
|
||||
for (int i = 0; i < views.size(); i++) {
|
||||
views.at(i)->setPos(i * 150, 0);
|
||||
}
|
||||
emit sizeChanged();
|
||||
}
|
||||
|
||||
void ZoneViewLayout::addItem(Player *player, const QString &zoneName, int numberCards)
|
||||
{
|
||||
ZoneViewWidget *item = new ZoneViewWidget(db, player, player->getZones()->findZone(zoneName), numberCards, this);
|
||||
views.append(item);
|
||||
connect(item, SIGNAL(closePressed(ZoneViewWidget *)), this, SLOT(removeItem(ZoneViewWidget *)));
|
||||
reorganize();
|
||||
}
|
||||
|
||||
void ZoneViewLayout::removeItem(ZoneViewWidget *item)
|
||||
{
|
||||
qDebug("ZoneViewLayout::removeItem");
|
||||
views.removeAt(views.indexOf(item));
|
||||
scene()->removeItem(item);
|
||||
delete item;
|
||||
reorganize();
|
||||
}
|
||||
25
cockatrice/src/zoneviewlayout.h
Normal file
25
cockatrice/src/zoneviewlayout.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef ZONEVIEWLAYOUT_H
|
||||
#define ZONEVIEWLAYOUT_H
|
||||
|
||||
#include <QGraphicsWidget>
|
||||
|
||||
class CardDatabase;
|
||||
class ZoneViewWidget;
|
||||
class Player;
|
||||
|
||||
class ZoneViewLayout : public QGraphicsWidget {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void sizeChanged();
|
||||
private:
|
||||
QList<ZoneViewWidget *> views;
|
||||
CardDatabase *db;
|
||||
public:
|
||||
ZoneViewLayout(CardDatabase *_db, QGraphicsItem *parent = 0);
|
||||
void reorganize();
|
||||
public slots:
|
||||
void addItem(Player *player, const QString &zoneName, int numberCards = 0);
|
||||
void removeItem(ZoneViewWidget *item);
|
||||
};
|
||||
|
||||
#endif
|
||||
45
cockatrice/src/zoneviewwidget.cpp
Normal file
45
cockatrice/src/zoneviewwidget.cpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#include <QtGui>
|
||||
|
||||
#include "zoneviewwidget.h"
|
||||
#include "carditem.h"
|
||||
#include "zoneviewzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
#include "zoneclosebutton.h"
|
||||
|
||||
ZoneViewWidget::ZoneViewWidget(CardDatabase *_db, Player *_player, PlayerZone *_origZone, int numberCards, QGraphicsItem *parent)
|
||||
: QGraphicsWidget(parent), db(_db), player(_player)
|
||||
{
|
||||
ZoneCloseButton *closeButton = new ZoneCloseButton(this);
|
||||
connect(closeButton, SIGNAL(triggered()), this, SLOT(slotClosePressed()));
|
||||
|
||||
resize(150, 1000);
|
||||
|
||||
zone = new ZoneViewZone(player, _origZone, numberCards, this);
|
||||
zone->setPos(0, 30);
|
||||
if (!zone->initializeCards()) {
|
||||
connect(player->client, SIGNAL(zoneDumpReceived(int, QList<ServerZoneCard *>)), this, SLOT(zoneDumpReceived(int, QList<ServerZoneCard *>)));
|
||||
cmdId = player->client->dumpZone(player->getId(), _origZone->getName(), numberCards);
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneViewWidget::zoneDumpReceived(int commandId, QList<ServerZoneCard *> cards)
|
||||
{
|
||||
if (commandId != cmdId)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < cards.size(); i++) {
|
||||
ServerZoneCard *temp = cards[i];
|
||||
|
||||
CardItem *card = new CardItem(db, temp->getName(), i, zone);
|
||||
zone->addCard(card, false, i);
|
||||
|
||||
delete temp;
|
||||
}
|
||||
zone->reorganizeCards();
|
||||
}
|
||||
|
||||
void ZoneViewWidget::slotClosePressed()
|
||||
{
|
||||
emit closePressed(this);
|
||||
}
|
||||
31
cockatrice/src/zoneviewwidget.h
Normal file
31
cockatrice/src/zoneviewwidget.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef ZONEVIEWWIDGET_H
|
||||
#define ZONEVIEWWIDGET_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsWidget>
|
||||
#include "serverzonecard.h"
|
||||
|
||||
class PlayerZone;
|
||||
class ZoneViewZone;
|
||||
class Player;
|
||||
class CardDatabase;
|
||||
|
||||
class ZoneViewWidget : public QGraphicsWidget {
|
||||
Q_OBJECT
|
||||
private:
|
||||
ZoneViewZone *zone;
|
||||
int cmdId;
|
||||
|
||||
CardDatabase *db;
|
||||
Player *player;
|
||||
signals:
|
||||
void closePressed(ZoneViewWidget *zv);
|
||||
private slots:
|
||||
void zoneDumpReceived(int commandId, QList<ServerZoneCard *> cards);
|
||||
void slotClosePressed();
|
||||
public:
|
||||
ZoneViewWidget(CardDatabase *_db, Player *_player, PlayerZone *_origZone, int numberCards = 0, QGraphicsItem *parent = 0);
|
||||
};
|
||||
|
||||
#endif
|
||||
104
cockatrice/src/zoneviewzone.cpp
Normal file
104
cockatrice/src/zoneviewzone.cpp
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#include <QtGui>
|
||||
#include "zoneviewzone.h"
|
||||
#include "player.h"
|
||||
#include "client.h"
|
||||
|
||||
ZoneViewZone::ZoneViewZone(Player *_p, PlayerZone *_origZone, int _numberCards, QGraphicsItem *parent)
|
||||
: PlayerZone(_p, _origZone->getName(), parent, true), numberCards(_numberCards), origZone(_origZone)
|
||||
{
|
||||
cards = new CardList(true);
|
||||
origZone->addView(this);
|
||||
}
|
||||
|
||||
ZoneViewZone::~ZoneViewZone()
|
||||
{
|
||||
qDebug("ZoneViewZone destructor");
|
||||
origZone->removeView(this);
|
||||
}
|
||||
|
||||
QRectF ZoneViewZone::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, CARD_WIDTH * 1.75, scene()->sceneRect().height());
|
||||
}
|
||||
|
||||
void ZoneViewZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(painter);
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
}
|
||||
|
||||
bool ZoneViewZone::initializeCards()
|
||||
{
|
||||
if (!origZone->contentsKnown())
|
||||
return false;
|
||||
|
||||
CardList *const c = origZone->getCards();
|
||||
int number = numberCards == 0 ? c->size() : (numberCards < c->size() ? numberCards : c->size());
|
||||
for (int i = 0; i < number; i++) {
|
||||
CardItem *card = c->at(i);
|
||||
addCard(new CardItem(player->getDb(), card->getName(), card->getId(), this), false, i);
|
||||
}
|
||||
reorganizeCards();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Because of boundingRect(), this function must not be called before the zone was added to a scene.
|
||||
void ZoneViewZone::reorganizeCards()
|
||||
{
|
||||
qDebug("reorganizeCards");
|
||||
|
||||
if (cards->isEmpty())
|
||||
return;
|
||||
|
||||
int cardCount = cards->size();
|
||||
qreal totalWidth = boundingRect().width();
|
||||
qreal totalHeight = boundingRect().height();
|
||||
qreal cardWidth = cards->at(0)->boundingRect().width();
|
||||
qreal cardHeight = cards->at(0)->boundingRect().height();
|
||||
qreal x1 = 0;
|
||||
qreal x2 = (totalWidth - cardWidth);
|
||||
|
||||
for (int i = 0; i < cardCount; i++) {
|
||||
CardItem *c = cards->at(i);
|
||||
qreal x = i % 2 ? x2 : x1;
|
||||
// If the total height of the cards is smaller than the available height,
|
||||
// the cards do not need to overlap and are displayed in the center of the area.
|
||||
if (cardHeight * cardCount > totalHeight)
|
||||
c->setPos(x, ((qreal) i) * (totalHeight - cardHeight) / (cardCount - 1));
|
||||
else
|
||||
c->setPos(x, ((qreal) i) * cardHeight + (totalHeight - cardCount * cardHeight) / 2);
|
||||
if (!origZone->contentsKnown())
|
||||
c->setId(i);
|
||||
c->setZValue(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneViewZone::addCard(CardItem *card, bool reorganize, int x, int y)
|
||||
{
|
||||
Q_UNUSED(y);
|
||||
qDebug(QString("ZoneViewZone: inserting '%1' at x=%2").arg(card->getName()).arg(x).toLatin1());
|
||||
cards->insert(x, card);
|
||||
card->setParentItem(this);
|
||||
card->update(card->boundingRect());
|
||||
if (reorganize)
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
void ZoneViewZone::handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint)
|
||||
{
|
||||
Q_UNUSED(dropPoint);
|
||||
qDebug(QString("handleDropEvent id=%1").arg(cardId).toLatin1());
|
||||
player->client->moveCard(cardId, startZone->getName(), getName(), 0, 0);
|
||||
}
|
||||
|
||||
void ZoneViewZone::removeCard(int position)
|
||||
{
|
||||
if (position >= cards->size())
|
||||
return;
|
||||
|
||||
CardItem *card = cards->at(position);
|
||||
cards->removeAt(position);
|
||||
delete card;
|
||||
reorganizeCards();
|
||||
}
|
||||
27
cockatrice/src/zoneviewzone.h
Normal file
27
cockatrice/src/zoneviewzone.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef ZONEVIEWERZONE_H
|
||||
#define ZONEVIEWERZONE_H
|
||||
|
||||
#include "playerzone.h"
|
||||
#include "serverzonecard.h"
|
||||
|
||||
class ZoneViewWidget;
|
||||
|
||||
class ZoneViewZone : public PlayerZone {
|
||||
private:
|
||||
int numberCards;
|
||||
void handleDropEvent(int cardId, PlayerZone *startZone, const QPoint &dropPoint);
|
||||
PlayerZone *origZone;
|
||||
signals:
|
||||
void removeZoneViewWidget(ZoneViewWidget *zv);
|
||||
public:
|
||||
ZoneViewZone(Player *_p, PlayerZone *_origZone, int _numberCards = 0, QGraphicsItem *parent = 0);
|
||||
~ZoneViewZone();
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void addCard(CardItem *card, bool reorganize = true, int x = 0, int y = -1);
|
||||
void reorganizeCards();
|
||||
bool initializeCards();
|
||||
void removeCard(int position);
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue