Merge remote-tracking branch 'upstream/master' into mtgjson-importer

This commit is contained in:
Fabio Bas 2014-06-21 10:50:23 +02:00
commit 26f1db5dda
29 changed files with 487 additions and 348 deletions

View file

@ -50,15 +50,21 @@ elseif(WIN32)
endif()
# Define proper compilation flags
IF (CMAKE_COMPILER_IS_GNUCC)
IF(MSVC)
# Visual Studio:
# Maximum optimization
set(CMAKE_CXX_FLAGS_RELEASE "/Ox")
# Generate complete debugging information
#set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
ELSEIF (CMAKE_COMPILER_IS_GNUCXX)
# linux/gcc, bsd/gcc, windows/mingw
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0")
else()
ELSE()
# other: osx/llvm, bsd/llvm
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
ENDIF (CMAKE_COMPILER_IS_GNUCC)
ENDIF()
# GNU systems need to define the Mersenne exponent for the RNG to compile w/o warning
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")

View file

@ -154,8 +154,11 @@ INCLUDE_DIRECTORIES(${QT_MOBILITY_MULTIMEDIAKIT_INCLUDE_DIR})
# Build cockatrice binary and link it
ADD_EXECUTABLE(cockatrice WIN32 MACOSX_BUNDLE ${cockatrice_SOURCES} ${cockatrice_QM} ${cockatrice_RESOURCES_RCC} ${cockatrice_MOC_SRCS})
TARGET_LINK_LIBRARIES(cockatrice cockatrice_common ${QT_LIBRARIES} ${QT_MOBILITY_MULTIMEDIAKIT_LIBRARY})
TARGET_LINK_LIBRARIES(cockatrice cockatrice_common ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES} ${QT_MOBILITY_MULTIMEDIAKIT_LIBRARY})
if(MSVC)
set_target_properties(cockatrice PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS")
endif(MSVC)
if(UNIX)
if(APPLE)

View file

@ -2,7 +2,10 @@
#include <QGraphicsScene>
#include <QCursor>
#include <QGraphicsSceneMouseEvent>
#include <math.h>
#include <cmath>
#ifdef _WIN32
#include "round.h"
#endif /* _WIN32 */
#include "carddatabase.h"
#include "cardinfowidget.h"
#include "abstractcarditem.h"
@ -143,7 +146,7 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
painter->restore();
}
void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
painter->save();

View file

@ -1,9 +1,11 @@
#define _USE_MATH_DEFINES
#include <cmath>
#include "arrowitem.h"
#include "playertarget.h"
#include "carditem.h"
#include "cardzone.h"
#include "player.h"
#include "math.h"
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsScene>
@ -64,7 +66,7 @@ void ArrowItem::updatePath(const QPointF &endPoint)
{
const double arrowWidth = 15.0;
const double headWidth = 40.0;
const double headLength = headWidth / sqrt(2);
const double headLength = headWidth / pow(2, 0.5); // aka headWidth / sqrt (2) but this produces a compile error with MSVC++
const double phi = 15;
if (!startItem)

View file

@ -148,7 +148,7 @@ QString CardZone::getTranslatedName(bool hisOwn, GrammaticalCase gc) const
return QString();
}
void CardZone::mouseDoubleClickEvent(QGraphicsSceneMouseEvent */*event*/)
void CardZone::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * /*event*/)
{
if (doubleClickAction)
doubleClickAction->trigger();

View file

@ -13,7 +13,7 @@ QRectF GeneralCounter::boundingRect() const
return QRectF(0, 0, radius * 2, radius * 2);
}
void GeneralCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
void GeneralCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
QRectF mapRect = painter->combinedTransform().mapRect(boundingRect());
int translatedHeight = mapRect.size().height();

View file

@ -19,7 +19,7 @@ public:
int getNumber() const { return dataNode->getNumber(); }
void setNumber(int _number) { dataNode->setNumber(_number); }
float getPrice() const { return dataNode->getPrice(); }
void setPrice(float _price) { dataNode->setPrice(_price); }
void setPrice(const float _price) { dataNode->setPrice(_price); }
QString getName() const { return dataNode->getName(); }
void setName(const QString &_name) { dataNode->setName(_name); }
DecklistCardNode *getDataNode() const { return dataNode; }

View file

@ -266,7 +266,7 @@ FilterItemList *FilterTree::attrTypeList(CardFilter::Attr attr,
int FilterTree::findTermIndex(CardFilter::Attr attr, CardFilter::Type type,
const QString &term)
{
attrTypeList(attr, type)->termIndex(term);
return attrTypeList(attr, type)->termIndex(term);
}
int FilterTree::findTermIndex(const CardFilter *f)

View file

@ -180,9 +180,9 @@ bool GamesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &/*sourc
if (!gameTypeFilter.isEmpty() && gameTypes.intersect(gameTypeFilter).isEmpty())
return false;
if ((maxPlayersFilterMin != -1) && (game.max_players() < maxPlayersFilterMin))
if ((maxPlayersFilterMin != -1) && ((int)game.max_players() < maxPlayersFilterMin))
return false;
if ((maxPlayersFilterMax != -1) && (game.max_players() > maxPlayersFilterMax))
if ((maxPlayersFilterMax != -1) && ((int)game.max_players() > maxPlayersFilterMax))
return false;
return true;

View file

@ -75,7 +75,7 @@ QRectF HandZone::boundingRect() const
return QRectF(0, 0, 100, zoneHeight);
}
void HandZone::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
void HandZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
if (bgPixmap.isNull())
painter->fillRect(boundingRect(), Qt::darkGreen);

View file

@ -19,6 +19,8 @@
***************************************************************************/
#include <QApplication>
#include <QFile>
#include <QTextStream>
#include <QTextCodec>
#include <QtPlugin>
#include <QTranslator>
@ -28,7 +30,6 @@
#include <QIcon>
#include <QDir>
#include <QDesktopServices>
#include <stdio.h>
#include "main.h"
#include "window_main.h"
@ -56,11 +57,11 @@ QString translationPath = QString();
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);
QFile file("qdebug.txt");
file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
QTextStream out(&file);
out << msg << endl;
file.close();
}
void installNewTranslator()

View file

@ -3,7 +3,10 @@
#include <QPen>
#include <QTimer>
#include <QDebug>
#include <math.h>
#include <cmath>
#ifdef _WIN32
#include "round.h"
#endif /* _WIN32 */
#include "phasestoolbar.h"
#include "pixmapgenerator.h"
@ -85,7 +88,7 @@ void PhaseButton::mousePressEvent(QGraphicsSceneMouseEvent * /*event*/)
emit clicked();
}
void PhaseButton::mouseDoubleClickEvent(QGraphicsSceneMouseEvent */*event*/)
void PhaseButton::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * /*event*/)
{
triggerDoubleClickAction();
}

View file

@ -105,7 +105,7 @@ void PileZone::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
setCursor(Qt::OpenHandCursor);
}
void PileZone::mouseReleaseEvent(QGraphicsSceneMouseEvent */*event*/)
void PileZone::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
{
setCursor(Qt::OpenHandCursor);
}

View file

@ -2,7 +2,10 @@
#include "pb/serverinfo_user.pb.h"
#include <QPainter>
#include <QSvgRenderer>
#include <math.h>
#include <cmath>
#ifdef _WIN32
#include "round.h"
#endif /* _WIN32 */
#include <QDebug>
QMap<QString, QPixmap> PhasePixmapGenerator::pmCache;

View file

@ -85,7 +85,7 @@ void PlayerArea::updateBgPixmap()
update();
}
void PlayerArea::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
void PlayerArea::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
painter->fillRect(bRect, bgPixmapBrush);
}
@ -1430,7 +1430,7 @@ QRectF Player::boundingRect() const
return bRect;
}
void Player::paint(QPainter * /*painter*/, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
void Player::paint(QPainter * /*painter*/, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
}

View file

@ -5,7 +5,10 @@
#include <QPainter>
#include <QPixmapCache>
#include <QDebug>
#include <math.h>
#include <cmath>
#ifdef _WIN32
#include "round.h"
#endif /* _WIN32 */
PlayerCounter::PlayerCounter(Player *_player, int _id, const QString &_name, int _value, QGraphicsItem *parent)
: AbstractCounter(_player, _id, _name, false, _value, parent)
@ -87,7 +90,8 @@ void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o
cachedPixmap = QPixmap(translatedSize.width(), translatedSize.height());
QPainter tempPainter(&cachedPixmap);
QRadialGradient grad(translatedRect.center(), sqrt(translatedSize.width() * translatedSize.width() + translatedSize.height() * translatedSize.height()) / 2);
// pow(foo, 0.5) equals to sqrt(foo), but using sqrt(foo) in this context will produce a compile error with MSVC++
QRadialGradient grad(translatedRect.center(), pow(translatedSize.width() * translatedSize.width() + translatedSize.height() * translatedSize.height(), 0.5) / 2);
grad.setColorAt(1, Qt::black);
grad.setColorAt(0, QColor(180, 180, 180));
tempPainter.fillRect(QRectF(0, 0, translatedSize.width(), translatedSize.height()), grad);

View file

@ -2,7 +2,10 @@
#include <QPainter>
#include <QPalette>
#include <QTimer>
#include <math.h>
#include <cmath>
#ifdef _WIN32
#include "round.h"
#endif /* _WIN32 */
ReplayTimelineWidget::ReplayTimelineWidget(QWidget *parent)
: QWidget(parent), maxBinValue(1), maxTime(1), timeScaleFactor(1.0), currentTime(0), currentEvent(0)

12
cockatrice/src/round.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef MSVC_ROUND_FIX
#define MSVC_ROUND_FIX
/**
* This helper function exists only because MS VC++ 2010 does not support round() in
* <cmath>. round() works with g++ and clang++ but is formally a C++11 extension.
* So this file exists for MS VC++ only.
*/
inline double round(double val) {
return floor(val + 0.5);
}
#endif /* MSVC_ROUND_FIX */

View file

@ -46,7 +46,7 @@ QRectF StackZone::boundingRect() const
return QRectF(0, 0, 100, zoneHeight);
}
void StackZone::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
void StackZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
if (bgPixmap.isNull())
painter->fillRect(boundingRect(), QColor(113, 43, 43));

View file

@ -4,6 +4,8 @@
#include "abstractclient.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include "pending_command.h"
#include "pb/session_commands.pb.h"
@ -21,34 +23,90 @@ TabUserLists::TabUserLists(TabSupervisor *_tabSupervisor, AbstractClient *_clien
ignoreList = new UserList(_tabSupervisor, client, UserList::IgnoreList);
userInfoBox = new UserInfoBox(client, false);
userInfoBox->updateInfo(userInfo);
connect(allUsersList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool)));
connect(buddyList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool)));
connect(ignoreList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool)));
connect(client, SIGNAL(userJoinedEventReceived(const Event_UserJoined &)), this, SLOT(processUserJoinedEvent(const Event_UserJoined &)));
connect(client, SIGNAL(userLeftEventReceived(const Event_UserLeft &)), this, SLOT(processUserLeftEvent(const Event_UserLeft &)));
connect(client, SIGNAL(buddyListReceived(const QList<ServerInfo_User> &)), this, SLOT(buddyListReceived(const QList<ServerInfo_User> &)));
connect(client, SIGNAL(ignoreListReceived(const QList<ServerInfo_User> &)), this, SLOT(ignoreListReceived(const QList<ServerInfo_User> &)));
connect(client, SIGNAL(addToListEventReceived(const Event_AddToList &)), this, SLOT(processAddToListEvent(const Event_AddToList &)));
connect(client, SIGNAL(removeFromListEventReceived(const Event_RemoveFromList &)), this, SLOT(processRemoveFromListEvent(const Event_RemoveFromList &)));
PendingCommand *pend = client->prepareSessionCommand(Command_ListUsers());
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(processListUsersResponse(const Response &)));
client->sendCommand(pend);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(userInfoBox);
vbox->addWidget(allUsersList);
QHBoxLayout *addToBuddyList = new QHBoxLayout;
addBuddyEdit = new QLineEdit;
addBuddyEdit->setPlaceholderText(tr("Add to Buddy List"));
connect(addBuddyEdit, SIGNAL(returnPressed()), this, SLOT(addToBuddyList()));
QPushButton *addBuddyButton = new QPushButton("Add");
connect(addBuddyButton, SIGNAL(clicked()), this, SLOT(addToBuddyList()));
addToBuddyList->addWidget(addBuddyEdit);
addToBuddyList->addWidget(addBuddyButton);
QHBoxLayout *addToIgnoreList = new QHBoxLayout;
addIgnoreEdit = new QLineEdit;
addIgnoreEdit->setPlaceholderText(tr("Add to Ignore List"));
connect(addIgnoreEdit, SIGNAL(returnPressed()), this, SLOT(addToIgnoreList()));
QPushButton *addIgnoreButton = new QPushButton("Add");
connect(addIgnoreButton, SIGNAL(clicked()), this, SLOT(addToIgnoreList()));
addToIgnoreList->addWidget(addIgnoreEdit);
addToIgnoreList->addWidget(addIgnoreButton);
QVBoxLayout *buddyPanel = new QVBoxLayout;
buddyPanel->addWidget(buddyList);
buddyPanel->addLayout(addToBuddyList);
QVBoxLayout *ignorePanel = new QVBoxLayout;
ignorePanel->addWidget(ignoreList);
ignorePanel->addLayout(addToIgnoreList);
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addWidget(buddyList);
mainLayout->addWidget(ignoreList);
mainLayout->addLayout(buddyPanel);
mainLayout->addLayout(ignorePanel);
mainLayout->addLayout(vbox);
setLayout(mainLayout);
}
void TabUserLists::addToBuddyList()
{
QString userName = addBuddyEdit->text();
if (userName.length() < 1) return;
std::string listName = "buddy";
addToList(listName, userName);
addBuddyEdit->clear();
}
void TabUserLists::addToIgnoreList()
{
QString userName = addIgnoreEdit->text();
if (userName.length() < 1) return;
std::string listName = "ignore";
addToList(listName, userName);
addIgnoreEdit->clear();
}
void TabUserLists::addToList(const std::string &listName, const QString &userName)
{
Command_AddToList cmd;
cmd.set_list(listName);
cmd.set_user_name(userName.toStdString());
client->sendCommand(client->prepareSessionCommand(cmd));
}
void TabUserLists::retranslateUi()
{
allUsersList->retranslateUi();

View file

@ -3,6 +3,7 @@
#include "tab.h"
#include "pb/serverinfo_user.pb.h"
#include <QLineEdit>
class AbstractClient;
class UserList;
@ -30,12 +31,17 @@ private slots:
void ignoreListReceived(const QList<ServerInfo_User> &_ignoreList);
void processAddToListEvent(const Event_AddToList &event);
void processRemoveFromListEvent(const Event_RemoveFromList &event);
void addToIgnoreList();
void addToBuddyList();
private:
AbstractClient *client;
UserList *allUsersList;
UserList *buddyList;
UserList *ignoreList;
UserInfoBox *userInfoBox;
QLineEdit *addBuddyEdit;
QLineEdit *addIgnoreEdit;
void addToList(const std::string &listName, const QString &userName);
public:
TabUserLists(TabSupervisor *_tabSupervisor, AbstractClient *_client, const ServerInfo_User &userInfo, QWidget *parent = 0);
void retranslateUi();

View file

@ -1,7 +1,10 @@
#include <QPainter>
#include <QSet>
#include <QGraphicsScene>
#include <math.h>
#include <cmath>
#ifdef _WIN32
#include "round.h"
#endif /* _WIN32 */
#include "tablezone.h"
#include "player.h"
#include "settingscache.h"
@ -46,7 +49,7 @@ bool TableZone::isInverted() const
return ((player->getMirrored() && !settingsCache->getInvertVerticalCoordinate()) || (!player->getMirrored() && settingsCache->getInvertVerticalCoordinate()));
}
void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
if (bgPixmap.isNull())
painter->fillRect(boundingRect(), QColor(0, 0, 100));

View file

@ -31,7 +31,7 @@ QRectF ZoneViewZone::boundingRect() const
return bRect;
}
void ZoneViewZone::paint(QPainter */*painter*/, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
void ZoneViewZone::paint(QPainter * /*painter*/, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
}

View file

@ -83,7 +83,7 @@ public:
virtual QString getName() const = 0;
virtual void setName(const QString &_name) = 0;
virtual float getPrice() const = 0;
virtual void setPrice(float _price) = 0;
virtual void setPrice(const float _price) = 0;
float getTotalPrice() const { return getNumber() * getPrice(); }
int height() const { return 0; }
bool compare(AbstractDecklistNode *other) const;

View file

@ -26,7 +26,7 @@
#include "pb/command_move_card.pb.h"
Server_CardZone::Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ServerInfo_Zone::ZoneType _type)
: player(_player),
: player(_player),
name(_name),
has_coords(_has_coords),
type(_type),
@ -37,255 +37,257 @@ Server_CardZone::Server_CardZone(Server_Player *_player, const QString &_name, b
Server_CardZone::~Server_CardZone()
{
qDebug() << "Server_CardZone destructor:" << name;
clear();
qDebug() << "Server_CardZone destructor:" << name;
clear();
}
void Server_CardZone::shuffle()
{
QList<Server_Card *> temp;
for (int i = cards.size(); i; i--)
temp.append(cards.takeAt(rng->rand(0, i - 1)));
cards = temp;
playersWithWritePermission.clear();
// Size 0 or 1 decks are sorted
if (cards.size() < 2) return;
for (int i = cards.size() - 1; i > 0; i--){
int j = rng->rand(0, i);
cards.swap(j,i);
}
playersWithWritePermission.clear();
}
void Server_CardZone::removeCardFromCoordMap(Server_Card *card, int oldX, int oldY)
{
if (oldX < 0)
return;
const int baseX = (oldX / 3) * 3;
QMap<int, Server_Card *> &coordMap = coordinateMap[oldY];
if (coordMap.contains(baseX) && coordMap.contains(baseX + 1) && coordMap.contains(baseX + 2))
// If the removal of this card has opened up a previously full pile...
freePilesMap[oldY].insert(coordMap.value(baseX)->getName(), baseX);
coordMap.remove(oldX);
if (!(coordMap.contains(baseX) && coordMap.value(baseX)->getName() == card->getName()) && !(coordMap.contains(baseX + 1) && coordMap.value(baseX + 1)->getName() == card->getName()) && !(coordMap.contains(baseX + 2) && coordMap.value(baseX + 2)->getName() == card->getName()))
// If this card was the last one with this name...
freePilesMap[oldY].remove(card->getName(), baseX);
if (!coordMap.contains(baseX) && !coordMap.contains(baseX + 1) && !coordMap.contains(baseX + 2)) {
// If the removal of this card has freed a whole pile, i.e. it was the last card in it...
if (baseX < freeSpaceMap[oldY])
freeSpaceMap[oldY] = baseX;
}
if (oldX < 0)
return;
const int baseX = (oldX / 3) * 3;
QMap<int, Server_Card *> &coordMap = coordinateMap[oldY];
if (coordMap.contains(baseX) && coordMap.contains(baseX + 1) && coordMap.contains(baseX + 2))
// If the removal of this card has opened up a previously full pile...
freePilesMap[oldY].insert(coordMap.value(baseX)->getName(), baseX);
coordMap.remove(oldX);
if (!(coordMap.contains(baseX) && coordMap.value(baseX)->getName() == card->getName()) && !(coordMap.contains(baseX + 1) && coordMap.value(baseX + 1)->getName() == card->getName()) && !(coordMap.contains(baseX + 2) && coordMap.value(baseX + 2)->getName() == card->getName()))
// If this card was the last one with this name...
freePilesMap[oldY].remove(card->getName(), baseX);
if (!coordMap.contains(baseX) && !coordMap.contains(baseX + 1) && !coordMap.contains(baseX + 2)) {
// If the removal of this card has freed a whole pile, i.e. it was the last card in it...
if (baseX < freeSpaceMap[oldY])
freeSpaceMap[oldY] = baseX;
}
}
void Server_CardZone::insertCardIntoCoordMap(Server_Card *card, int x, int y)
{
if (x < 0)
return;
coordinateMap[y].insert(x, card);
if (!(x % 3)) {
if (!freePilesMap[y].contains(card->getName(), x) && card->getAttachedCards().isEmpty())
freePilesMap[y].insert(card->getName(), x);
if (freeSpaceMap[y] == x) {
int nextFreeX = x;
do {
nextFreeX += 3;
} while (coordinateMap[y].contains(nextFreeX) || coordinateMap[y].contains(nextFreeX + 1) || coordinateMap[y].contains(nextFreeX + 2));
freeSpaceMap[y] = nextFreeX;
}
} else if (!((x - 2) % 3)) {
const int baseX = (x / 3) * 3;
freePilesMap[y].remove(coordinateMap[y].value(baseX)->getName(), baseX);
}
if (x < 0)
return;
coordinateMap[y].insert(x, card);
if (!(x % 3)) {
if (!freePilesMap[y].contains(card->getName(), x) && card->getAttachedCards().isEmpty())
freePilesMap[y].insert(card->getName(), x);
if (freeSpaceMap[y] == x) {
int nextFreeX = x;
do {
nextFreeX += 3;
} while (coordinateMap[y].contains(nextFreeX) || coordinateMap[y].contains(nextFreeX + 1) || coordinateMap[y].contains(nextFreeX + 2));
freeSpaceMap[y] = nextFreeX;
}
} else if (!((x - 2) % 3)) {
const int baseX = (x / 3) * 3;
freePilesMap[y].remove(coordinateMap[y].value(baseX)->getName(), baseX);
}
}
int Server_CardZone::removeCard(Server_Card *card)
{
int index = cards.indexOf(card);
cards.removeAt(index);
if (has_coords)
removeCardFromCoordMap(card, card->getX(), card->getY());
card->setZone(0);
return index;
int index = cards.indexOf(card);
cards.removeAt(index);
if (has_coords)
removeCardFromCoordMap(card, card->getX(), card->getY());
card->setZone(0);
return index;
}
Server_Card *Server_CardZone::getCard(int id, int *position, bool remove)
{
if (type != ServerInfo_Zone::HiddenZone) {
for (int i = 0; i < cards.size(); ++i) {
Server_Card *tmp = cards[i];
if (tmp->getId() == id) {
if (position)
*position = i;
if (remove) {
cards.removeAt(i);
tmp->setZone(0);
}
return tmp;
}
}
return NULL;
} else {
if ((id >= cards.size()) || (id < 0))
return NULL;
Server_Card *tmp = cards[id];
if (position)
*position = id;
if (remove) {
cards.removeAt(id);
tmp->setZone(0);
}
return tmp;
}
if (type != ServerInfo_Zone::HiddenZone) {
for (int i = 0; i < cards.size(); ++i) {
Server_Card *tmp = cards[i];
if (tmp->getId() == id) {
if (position)
*position = i;
if (remove) {
cards.removeAt(i);
tmp->setZone(0);
}
return tmp;
}
}
return NULL;
} else {
if ((id >= cards.size()) || (id < 0))
return NULL;
Server_Card *tmp = cards[id];
if (position)
*position = id;
if (remove) {
cards.removeAt(id);
tmp->setZone(0);
}
return tmp;
}
}
int Server_CardZone::getFreeGridColumn(int x, int y, const QString &cardName) const
{
const QMap<int, Server_Card *> &coordMap = coordinateMap.value(y);
if (x == -1) {
if (freePilesMap[y].contains(cardName)) {
x = (freePilesMap[y].value(cardName) / 3) * 3;
if (!coordMap.contains(x))
return x;
else if (!coordMap.contains(x + 1))
return x + 1;
else
return x + 2;
}
} else if (x >= 0) {
int resultX = 0;
x = (x / 3) * 3;
if (!coordMap.contains(x))
resultX = x;
else if (!coordMap.value(x)->getAttachedCards().isEmpty()) {
resultX = x;
x = -1;
} else if (!coordMap.contains(x + 1))
resultX = x + 1;
else if (!coordMap.contains(x + 2))
resultX = x + 2;
else {
resultX = x;
x = -1;
}
if (x < 0)
while (coordMap.contains(resultX))
resultX += 3;
const QMap<int, Server_Card *> &coordMap = coordinateMap.value(y);
if (x == -1) {
if (freePilesMap[y].contains(cardName)) {
x = (freePilesMap[y].value(cardName) / 3) * 3;
if (!coordMap.contains(x))
return x;
else if (!coordMap.contains(x + 1))
return x + 1;
else
return x + 2;
}
} else if (x >= 0) {
int resultX = 0;
x = (x / 3) * 3;
if (!coordMap.contains(x))
resultX = x;
else if (!coordMap.value(x)->getAttachedCards().isEmpty()) {
resultX = x;
x = -1;
} else if (!coordMap.contains(x + 1))
resultX = x + 1;
else if (!coordMap.contains(x + 2))
resultX = x + 2;
else {
resultX = x;
x = -1;
}
if (x < 0)
while (coordMap.contains(resultX))
resultX += 3;
return resultX;
}
return freeSpaceMap[y];
return resultX;
}
return freeSpaceMap[y];
}
bool Server_CardZone::isColumnStacked(int x, int y) const
{
if (!has_coords)
return false;
return coordinateMap[y].contains((x / 3) * 3 + 1);
if (!has_coords)
return false;
return coordinateMap[y].contains((x / 3) * 3 + 1);
}
bool Server_CardZone::isColumnEmpty(int x, int y) const
{
if (!has_coords)
return true;
return !coordinateMap[y].contains((x / 3) * 3);
if (!has_coords)
return true;
return !coordinateMap[y].contains((x / 3) * 3);
}
void Server_CardZone::moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y)
{
CardToMove *cardToMove = new CardToMove;
cardToMove->set_card_id(card->getId());
player->moveCard(ges, this, QList<const CardToMove *>() << cardToMove, this, x, y, false, false);
delete cardToMove;
CardToMove *cardToMove = new CardToMove;
cardToMove->set_card_id(card->getId());
player->moveCard(ges, this, QList<const CardToMove *>() << cardToMove, this, x, y, false, false);
delete cardToMove;
}
void Server_CardZone::fixFreeSpaces(GameEventStorage &ges)
{
if (!has_coords)
return;
QSet<QPair<int, int> > placesToLook;
for (int i = 0; i < cards.size(); ++i)
placesToLook.insert(QPair<int, int>((cards[i]->getX() / 3) * 3, cards[i]->getY()));
QSetIterator<QPair<int, int> > placeIterator(placesToLook);
while (placeIterator.hasNext()) {
const QPair<int, int> &foo = placeIterator.next();
int baseX = foo.first;
int y = foo.second;
if (!coordinateMap[y].contains(baseX)) {
if (coordinateMap[y].contains(baseX + 1))
moveCardInRow(ges, coordinateMap[y].value(baseX + 1), baseX, y);
else if (coordinateMap[y].contains(baseX + 2)) {
moveCardInRow(ges, coordinateMap[y].value(baseX + 2), baseX, y);
continue;
} else
continue;
}
if (!coordinateMap[y].contains(baseX + 1) && coordinateMap[y].contains(baseX + 2))
moveCardInRow(ges, coordinateMap[y].value(baseX + 2), baseX + 1, y);
}
if (!has_coords)
return;
QSet<QPair<int, int> > placesToLook;
for (int i = 0; i < cards.size(); ++i)
placesToLook.insert(QPair<int, int>((cards[i]->getX() / 3) * 3, cards[i]->getY()));
QSetIterator<QPair<int, int> > placeIterator(placesToLook);
while (placeIterator.hasNext()) {
const QPair<int, int> &foo = placeIterator.next();
int baseX = foo.first;
int y = foo.second;
if (!coordinateMap[y].contains(baseX)) {
if (coordinateMap[y].contains(baseX + 1))
moveCardInRow(ges, coordinateMap[y].value(baseX + 1), baseX, y);
else if (coordinateMap[y].contains(baseX + 2)) {
moveCardInRow(ges, coordinateMap[y].value(baseX + 2), baseX, y);
continue;
} else
continue;
}
if (!coordinateMap[y].contains(baseX + 1) && coordinateMap[y].contains(baseX + 2))
moveCardInRow(ges, coordinateMap[y].value(baseX + 2), baseX + 1, y);
}
}
void Server_CardZone::updateCardCoordinates(Server_Card *card, int oldX, int oldY)
{
if (!has_coords)
return;
if (oldX != -1)
removeCardFromCoordMap(card, oldX, oldY);
insertCardIntoCoordMap(card, card->getX(), card->getY());
if (!has_coords)
return;
if (oldX != -1)
removeCardFromCoordMap(card, oldX, oldY);
insertCardIntoCoordMap(card, card->getX(), card->getY());
}
void Server_CardZone::insertCard(Server_Card *card, int x, int y)
{
if (hasCoords()) {
card->setCoords(x, y);
cards.append(card);
insertCardIntoCoordMap(card, x, y);
} else {
card->setCoords(0, 0);
if (x == -1)
cards.append(card);
else
cards.insert(x, card);
}
card->setZone(this);
if (hasCoords()) {
card->setCoords(x, y);
cards.append(card);
insertCardIntoCoordMap(card, x, y);
} else {
card->setCoords(0, 0);
if (x == -1)
cards.append(card);
else
cards.insert(x, card);
}
card->setZone(this);
}
void Server_CardZone::clear()
{
for (int i = 0; i < cards.size(); i++)
delete cards.at(i);
cards.clear();
coordinateMap.clear();
freePilesMap.clear();
freeSpaceMap.clear();
playersWithWritePermission.clear();
for (int i = 0; i < cards.size(); i++)
delete cards.at(i);
cards.clear();
coordinateMap.clear();
freePilesMap.clear();
freeSpaceMap.clear();
playersWithWritePermission.clear();
}
void Server_CardZone::addWritePermission(int playerId)
{
playersWithWritePermission.insert(playerId);
playersWithWritePermission.insert(playerId);
}
void Server_CardZone::getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAsking, bool omniscient)
{
info->set_name(name.toStdString());
info->set_type(type);
info->set_with_coords(has_coords);
info->set_card_count(cards.size());
info->set_always_reveal_top_card(alwaysRevealTopCard);
if (
(((playerWhosAsking == player) || omniscient) && (type != ServerInfo_Zone::HiddenZone))
|| ((playerWhosAsking != player) && (type == ServerInfo_Zone::PublicZone))
) {
QListIterator<Server_Card *> cardIterator(cards);
while (cardIterator.hasNext())
cardIterator.next()->getInfo(info->add_card_list());
}
info->set_name(name.toStdString());
info->set_type(type);
info->set_with_coords(has_coords);
info->set_card_count(cards.size());
info->set_always_reveal_top_card(alwaysRevealTopCard);
if (
(((playerWhosAsking == player) || omniscient) && (type != ServerInfo_Zone::HiddenZone))
|| ((playerWhosAsking != player) && (type == ServerInfo_Zone::PublicZone))
) {
QListIterator<Server_Card *> cardIterator(cards);
while (cardIterator.hasNext())
cardIterator.next()->getInfo(info->add_card_list());
}
}

Binary file not shown.

View file

@ -83,87 +83,115 @@ If someone runs his own server where you can register a user profile, read his d
\section{Downloading and Installing the Cockatrice Program}
Due to a legal dispute there are currently no official builds left, so currently you have to build your own binaries.
\subsection{Client compilation}
\subsection{Building the Client}
\subsubsection{Windows}
There should be two ways to compile Cockatrice: With Visual Studio 2010 and with MinGW.
As the Visual Studio method is more complicated and might not work, you should do it with MinGW.
The following howto has been tested with Windows 7 64Bit.
To build Cockatrice, we need the Cockatrice sourcecode, its dependencies and build tools of course.
Everything is freely available.
There should be two ways to compile Cockatrice:
With Microsoft Visual Studio 2010 (Visual C++ 2010) and with MinGW, a minimalist GNU environment for Windows.
We suggest to use Visual Studio because there is a severe problem with MinGW:
It doesn't offer a compatible version of its tools.
The Qt library needs a certain, old MinGW version\footnote{The officially needed version is MinGW 4.8.2, the last known working version was MinGW 20120426} which is unavailable on the internet because they use an online installer and don't offer old, stable releases.
Trying to build with the current version of MinGW will result in application crashes!
So MinGW and Qt force us to focus on Visual Studio and don't support MinGW.
Gladly, Microsoft offers Visual Studio Express free of charge, which is a limited but sufficient version of Visual Studio.
It only requires a free of charge registration after 30 days.
The following howto which uses Visual C++ 2010 Express has been tested with an up to date Windows 7 64Bit.
The resulting build is a 32bit binary, which runs on both 32bit and 64bit systems.
\paragraph{Prerequisites}
We need the Cockatrice sourcecode, it's dependencies and build tools. Everything is freely available:
Here is an introduction of all dependencies and tools needed for Cockatrice, followed by a list of downloadlinks in the same order.
\begin{enumerate}
\item MinGW is needed to compile everything, it ships the compiler and other tools for this task.
\item The Microsoft Windows SDK for Windows 7 and .NET Framework 4 provides tools and libraries to create Windows applications.
\item The Visual C++ 2010 SP 1 Compiler Update for Windows SDK 7.1 (KB2519277) is a necessary update for the SDK.
\item Microsoft Visual C++ 2010 Express is the actual development environment.
\item Microsoft Visual Studio 2010 Service Pack 1 (VS10sp1-KB983509) is an update for Visual Studio.
\item The Qt libraries 4.8.x for Windows (VS 2010) are the main dependency for Cockatrice.
\item protobuf 2.5.0 is another dependency for Cockatrice (it has no installer, you need to download the zip file with the sourcecode).
\item cmake version 2.8.12.x is needed to create Cockatrice's project files for Visual Studio. Version 3 has not been tested yet with Cockatrice.
\item git is needed to download the latest Cockatrice source code.
\item cmake is needed to create Cockatrice's project files for MinGW.
\item Qt 4.8 is a dependency for Cockatrice (download the MinGW version!)
\item protobuf 2.5 is another dependency for Cockatrice (download the zip file with the sourcecode).
\item Nullsoft Scriptable Install System (NSIS) which can be used to create an installer for your own Cockatrice version.
\item Nullsoft Scriptable Install System (NSIS 3.0b0) is a program to create the Windows installer for Cockatrice.
\end{enumerate}
All downloadlinks together:
\footnotesize{\begin{enumerate}
\item \url{http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/mingw-get-inst-20120426/}
\item \url{http://www.microsoft.com/en-us/download/details.aspx?id=8279} % Win SDK
\item \url{http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=4422} % SDK Update
\item \url{http://go.microsoft.com/?linkid=9709949} % MSVC
\item \url{http://www.microsoft.com/en-us/download/details.aspx?id=23691} % MSVC SP1
\item \url{http://download.qt-project.org/official_releases/qt/4.8/4.8.6/qt-opensource-windows-x86-vs2010-4.8.6.exe}
\item \url{http://www.cmake.org/files/v2.8/cmake-2.8.12.2-win32-x86.exe}
\item \url{http://git-scm.com/download/win}
\item \url{http://www.cmake.org/files/v2.8/cmake-2.8.10.2-win32-x86.exe}
\item \url{http://download.qt-project.org/official_releases/qt/4.8/4.8.4/qt-win-opensource-4.8.4-mingw.exe}
\item \url{http://protobuf.googlecode.com/files/protobuf-2.5.0.zip}
\item \url{http://nsis.sourceforge.net/Download}
\end{enumerate}}
\paragraph{Installation of the Prerequisites}
Problems will occur if you don't install the first four steps (all the Microsoft SDK and Visual Studio packages) in the exact same order as printed here!
\begin{enumerate}
\item Download MinGW (mingw-get-inst), git, cmake, protobuf 2.5 sources zip and Qt 4.8.4 MinGW (see links above).
\item Make a standard installation for git, cmake and NSIS.
\item Install MinGW:
\begin{enumerate}
\item Select default values everywhere, except: Also check the C++ Compiler, check the MSYS Basis System and MinGW Developer Toolkit.
\item Append \shellcmd{C:\textbackslash MinGW\textbackslash bin} to your PATH variable (google how to do it for your Windows version, if you don't know it).
This is very important and overseen many times! You can keep the PATH configuration dialog open for the next step.
\end{enumerate}
\item Install Qt, select default values everywhere, ignore the message regarding win32.h and append \shellcmd{C:\textbackslash Qt\textbackslash 4.8.4\textbackslash bin} to your PATH variable like you did for MinGW.
\item Unpack protobuf-2.5.0.zip in \shellcmd{C:\textbackslash MinGW\textbackslash msys\textbackslash 1.0\textbackslash home\textbackslash YOURLOGIN}
\begin{enumerate}
\item Open MinGW Shell, type the following commands exactly:
\item \shellcmd{cd protobuf-2.5.0/protobuf-2.5.0}
\item \shellcmd{./configure --prefix=`cd /mingw; pwd -W`} (these apostrophs are backticks and do not forget the dot at the beginning!)
\item \shellcmd{make; make install} (this builds and installs protobuf, which needs some time)
\item Close MinGW Shell
\end{enumerate}
\item Install Microsoft Windows SDK for Windows 7 and .NET Framework 4.
\item Apply the Visual C++ 2010 SP 1 Compiler Update for Windows SDK 7.1
\item Install Visual C++ 2010 Express (Start the web installer, you may disable Silverlight)
\item Apply Visual C++ 2010 Express Service Pack 1
\item Install Qt4 VS 2010 edition.
\item Install NSIS.
\item Install cmake. Choose to add CMake to the System path.
\item Install git. Choose Run Git from Windows Command Prompt.
\end{enumerate}
Your system is now able to compile Cockatrice. You do not have to repeat the process so far ever again.
As protobuf does neither provide an installer nor the libraries needed for Cockatrice, you have to build those with Visual Studio from the protobuf sources.
The Cockatrice installer will search for the protobuf libraries within the Cockatrice sources, so before unpacking and building protobuf, you need to download the Cockatrice sources first:
\begin{enumerate}
\item Right click into a folder, select Git Gui, then Clone Existing Directory,
\item enter Source Location \url{https://github.com/Daenyth/Cockatrice}
\item enter target directory (from now on called Cockatrice), click clone and wait until the sources have been downloaded,
\item close Git Gui.
\end{enumerate}
Now we prepare protobuf:
\begin{enumerate}
\item Create a \shellcmd{build} directory inside the Cockatrice directory.
\item Copy the protobuf-2.5.0.zip into the build directory.
\item Rightclick the zip, choose Extract all. This uses the Windows included zip unpacker to extract the archive.
\end{enumerate}
To be clear: you will (and must) have a Cockatrice/build/protobuf-2.5.0/protobuf-2.5.0 directory hierarchy after that!
Now the protobuf dependencies for Cockatrice will be built:
\begin{enumerate}
\item Start Visual C++ 2010 Express and from the File menu Open Project/Solution, move to the Cockatrice/build/protobuf-2.5.0/protobuf-2.5.0/vsprojects directory and choose protobuf.sln.
\item Let you guide through the Conversion Wizard, you don't need to create a backup.
\item After the conversion is finished, open the projects (uncheck ``Ask me for every project in this solution'' and click OK).
\item You don't need to look at the conversion report.
\item Select Release or Debug in the toolbar. Release optimizes the code for size and speed, while Debug creates larger, slower binaries, used for development. You need to use the same setting for Cockatrice later! We suggest to use Release.
\item Rightclick on libprotobuf, choose Build. Note that the output should say: Build started: Project libprotobuf, Configuration: Release Win32
\item Then rightclick on protoc, choose Build. This will build libprotoc and the protoc executable, also as Release Win32.
\item After the build succeeded, close Visual C++.
\end{enumerate}
The Cockatrice/build/protobuf-2.5.0/protobuf-2.5.0/vsprojects/Release directory now contains libprotobuf.dll, libprotobuf.lib and protoc.exe which are needed for Cockatrice.
\paragraph{Cockatrice Compilation}
Now everything is ready to compile Cockatrice.
\begin{enumerate}
\item Checkout Cockatrice:
\begin{enumerate}
\item Start Git Bash and type the following command exactly:
\item \shellcmd{git clone https://github.com/Daenyth/Cockatrice}
\item Close Git Bash
\end{enumerate}
\item Start CMake (cmake-gui) and do the following:
\begin{enumerate}
\item Where is the source code: Point to the Cockatrice directory
\item Where to build the binaries: Point to the Cockatrice/build directory (it doesn't matter if it exists; if it doesn't, cmake will ask later if it shall create this directory)
\item Check Advanced
\item Click Configure, choose MinGW, leave the rest default
\item An error will occur, set the following:
\begin{itemize}
\item Set PROTOBUF\_INCLUDE\_DIR to C:/MinGW/include/google/protobuf
\item Set PROTOBUF\_LIBRARY to C:/MinGW/lib/libprotobuf.dll.a
\item Set PROTOBUF\_LITE\_LIBRARY to C:/MinGW/lib/libprotobuf-lite.dll.a
\item Set PROTOBUF\_PROTOC\_EXECUTABLE to C:/MinGW/bin/protoc.exe
\item Set PROTOBUF\_PROTOC\_LIBRARY to C:/MinGW/lib/libprotoc.dll.a
\end{itemize}
\item Click Configure again, then Generate
\item Close CMake
\end{enumerate}
\item Start cmd.exe (the Windows Command Prompt) and type the following commands:
\begin{enumerate}
\item \shellcmd{cd Cockatrice/build} (this changes to the build directory)
\item \shellcmd{make} (this builds everything and might need some time)
\end{enumerate}
\item Start CMake GUI, locate the Cockatrice directory and locate the Cockatrice/build directory.
Then click Configure and choose Visual Studio 10.
An error will occur during the Configure process because CMake does not know the location of the protobuf library.
\item To satisfy CMake, check Advanced, enter ``protobuf'' in the Search field,
\begin{enumerate}
\item Set PROTOBUF\_INCLUDE\_DIR to Cockatrice/build/protobuf-2.5.0/protobuf-2.5.0/src/
\item Set PROTOBUF\_LIBRARY to Cockatrice/build/protobuf-2.5.0/protobuf-2.5.0/vsprojects/Release/libprotobuf.lib
\item Set PROTOBUF\_PROTOC\_EXECUTABLE to Cockatrice/build/protobuf-2.5.0/protobuf-2.5.0/vsprojects/Release/protoc.exe
\item Set PROTOBUF\_PROTOC\_LIBRARY to Cockatrice/build/protobuf-2.5.0/protobuf-2.5.0/vsprojects/Release/libprotoc.lib % TODO: Is this needed? I don't think so; but it doesn't hurt either.
\item Click Configure again.
\end{enumerate}
\item Click Generate, then close CMake GUI. The project files have been generated.
\item Start Visual C++ 2010 Express and from the File menu select Open Project/Solution, point to the Cockatrice/build directory and choose Cockatrice.sln.
\item Select Release or Debug in the toolbar exactly as you did for protobuf. We suggest Release.
\item Rightclick on ALL\_BUILD, choose Build.
\end{enumerate}
Cockatrice has now been downloaded and built for the first time. You do not have to repeat the process so far ever again.
\paragraph{Updating your Cockatrice build}
If you just compiled Cockatrice for the first time, you skip this step obviously.
@ -174,17 +202,19 @@ But if you want to update Cockatrice after the source code changed on github, do
\item \shellcmd{git pull origin master}
\item \shellcmd{Close Git Bash}
\end{enumerate}
\item Start cmd.exe, change to Cockatrice/build, type make like you did previously.
\item Start Visual C++ 2010 Express and build the Cockatrice sources again.
\end{enumerate}
Cockatrice has now been updated and built. You may repeat this process every time when the source code changed.
\paragraph{Cockatrice installation}
To install Cockatrice, you have to create an installer with NSIS now.
Change to the directory \shellcmd{nsis} in the Cockatrice root directory, right click the cockatrice.nsi file and select \shellcmd{Compile NSIS Script}.
Change to the directory \shellcmd{nsis} in the Cockatrice directory, right click the cockatrice.nsi file and select \shellcmd{Compile NSIS Script}.
The NSIS program then creates a file called cockatrice\_win32\_YYYYmmdd\_git-xxxxxxx.exe. This is the complete, redistributable installer for your Cockatrice build.
Now install Cockatrice by executing the installer.
Note: if you installed MinGW or Qt in other than the default paths, you have to fix the paths in the cockatrice.nsi file (also if some libraries change); you can edit this file with a text editor.
Note: if you installed Qt in other than the default path, you have to fix the paths in the cockatrice.nsi file; you can edit this file with a text editor.
We will remove this static NSIS file in the future and let CMake create the NSIS file on the fly.
\paragraph{Create a card database}
Start the oracle.exe (the installer does this automatically) and let it generate a current cards.xml file:
@ -204,7 +234,7 @@ Before you install new software, you should update your system. The following in
\begin{enumerate}
\item You need to install the build tools and dependencies. This varies between the Linux distributions.
\begin{description}
\item[Debian, Ubuntu and spin-offs] \shellcmd{sudo apt-get install build-essential git libqt4-dev qtmobility-dev libprotobuf-dev protobuf-compiler cmake} (see note below regarding pthread)
\item[Debian, Ubuntu and spin-offs] \shellcmd{sudo apt-get install build-essential git libqt4-dev qtmobility-dev libprotobuf-dev protobuf-compiler cmake}
\item[Fedora] \shellcmd{sudo yum groupinstall "Development Tools"\\
yum install qt-devel qt-mobility-devel protobuf-devel protobuf-compiler cmake}
\item[FreeBSD 9] \shellcmd{pkg\_add -r qt4 qt4-linguist qt4-moc qt4-qmake qt4-rcc qt4-uic git cmake protobuf}
@ -217,9 +247,6 @@ mkdir build \\
cd build \\
cmake ..\\
make}\\
\begin{framed}
If you have linking errors with pthread\_* add 'pthread' to the ``target\_link\_libraries'' entry in the \shellcmd{CMakeFiles.txt} in \shellcmd{Cockatrice/common}, e.g. for Xubuntu, then continue the make process.
\end{framed}
\item You may install the program into the directory \shellcmd{/usr/local} by typing \shellcmd{sudo make install} but you should also be able to start
cockatrice and the oracle from the build directory.
\item Before you start Cockatrice for the first time, run \shellcmd{oracle -dlsets} and download available cards, then run \shellcmd{cockatrice}.
@ -229,7 +256,7 @@ The default paths for decks, pics, cards and tokens are located in \\ \shellcmd{
\subsubsection{MacOS X}
TODO, please contribute this section! See Linux section, then use the \shellcmd{prepareMacRelease.sh} script from Cockatrice.
\subsection{Server compilation}
\subsection{Building the Server}
You don't need your own server if you plan to play only. But as Cockatrice is open source you are free to run your own.
The compilation works like already written above, but instead of invoking \shellcmd{cmake ..}, you have to do it like this:
\begin{itemize}

View file

@ -9,6 +9,9 @@ OutFile "cockatrice_win32_${TIMESTAMP}_git-${VERSION}.exe"
SetCompressor /SOLID lzma
InstallDir "$PROGRAMFILES\Cockatrice"
; set the Qt install dir here (and make sure you use the latest 4.8 version for packaging)
!define QTDIR "C:\Qt\4.8.6"
!define MUI_ABORTWARNING
!define MUI_WELCOMEFINISHPAGE_BITMAP "leftimage.bmp"
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "leftimage.bmp"
@ -34,35 +37,33 @@ InstallDir "$PROGRAMFILES\Cockatrice"
!insertmacro MUI_LANGUAGE "English"
Section "Application" SecApplication
SetShellVarContext all
SetOutPath "$INSTDIR"
File ..\build\cockatrice\cockatrice.exe
File ..\build\oracle\oracle.exe
File ..\build\cockatrice\Release\cockatrice.exe
File ..\build\oracle\Release\oracle.exe
File ..\doc\usermanual\Usermanual.pdf
File C:\MinGW\bin\libstdc++-6.dll
File C:\MinGW\bin\libgcc_s_dw2-1.dll
File C:\MinGW\bin\mingwm10.dll
File C:\MinGW\bin\libprotobuf-8.dll
File C:\Qt\4.8.4\bin\QtCore4.dll
File C:\Qt\4.8.4\bin\QtGui4.dll
File C:\Qt\4.8.4\bin\QtNetwork4.dll
File C:\Qt\4.8.4\bin\QtSvg4.dll
File C:\Qt\4.8.4\bin\QtXml4.dll
File C:\Qt\4.8.4\bin\QtMultimedia4.dll
File ..\build\protobuf-2.5.0\protobuf-2.5.0\vsprojects\Release\libprotobuf.lib
File "${QTDIR}\bin\QtCore4.dll"
File "${QTDIR}\bin\QtGui4.dll"
File "${QTDIR}\bin\QtNetwork4.dll"
File "${QTDIR}\bin\QtSvg4.dll"
File "${QTDIR}\bin\QtXml4.dll"
File "${QTDIR}\bin\QtMultimedia4.dll"
SetOutPath "$INSTDIR\zonebg"
File /r ..\zonebg\*.*
SetOutPath "$INSTDIR\plugins"
SetOutPath "$INSTDIR\plugins\codecs"
File C:\Qt\4.8.4\plugins\codecs\qcncodecs4.dll
File C:\Qt\4.8.4\plugins\codecs\qjpcodecs4.dll
File C:\Qt\4.8.4\plugins\codecs\qkrcodecs4.dll
File C:\Qt\4.8.4\plugins\codecs\qtwcodecs4.dll
File "${QTDIR}\plugins\codecs\qcncodecs4.dll"
File "${QTDIR}\plugins\codecs\qjpcodecs4.dll"
File "${QTDIR}\plugins\codecs\qkrcodecs4.dll"
File "${QTDIR}\plugins\codecs\qtwcodecs4.dll"
SetOutPath "$INSTDIR\plugins\iconengines"
File C:\Qt\4.8.4\plugins\iconengines\qsvgicon4.dll
File "${QTDIR}\plugins\iconengines\qsvgicon4.dll"
SetOutPath "$INSTDIR\plugins\imageformats"
File C:\Qt\4.8.4\plugins\imageformats\qjpeg4.dll
File C:\Qt\4.8.4\plugins\imageformats\qsvg4.dll
File "${QTDIR}\plugins\imageformats\qjpeg4.dll"
File "${QTDIR}\plugins\imageformats\qsvg4.dll"
SetOutPath "$INSTDIR\sounds"
File /r ..\sounds\*.*
@ -70,9 +71,9 @@ Section "Application" SecApplication
SetOutPath "$INSTDIR\translations"
File /r ..\build\cockatrice\*.qm
WriteUninstaller "$INSTDIR\uninstall.exe"
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteUninstaller "$INSTDIR\uninstall.exe"
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "DisplayName" "Cockatrice"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
@ -96,38 +97,36 @@ Section "Start menu item" SecStartMenu
SectionEnd
Section Uninstall
RMDir /r "$INSTDIR\zonebg"
RMDir /r "$INSTDIR\plugins"
RMDir /r "$INSTDIR\sounds"
SetShellVarContext all
RMDir /r "$INSTDIR\zonebg"
RMDir /r "$INSTDIR\plugins"
RMDir /r "$INSTDIR\sounds"
RMDir /r "$INSTDIR\translations"
Delete "$INSTDIR\uninstall.exe"
Delete "$INSTDIR\cockatrice.exe"
Delete "$INSTDIR\oracle.exe"
Delete "$INSTDIR\Usermanual.pdf"
Delete "$INSTDIR\libstdc++-6.dll"
Delete "$INSTDIR\libprotobuf-8.dll"
Delete "$INSTDIR\libgcc_s_dw2-1.dll"
Delete "$INSTDIR\mingwm10.dll"
Delete "$INSTDIR\QtCore4.dll"
Delete "$INSTDIR\QtGui4.dll"
Delete "$INSTDIR\QtNetwork4.dll"
Delete "$INSTDIR\QtSvg4.dll"
Delete "$INSTDIR\QtXml4.dll"
Delete "$INSTDIR\uninstall.exe"
Delete "$INSTDIR\cockatrice.exe"
Delete "$INSTDIR\oracle.exe"
Delete "$INSTDIR\Usermanual.pdf"
Delete "$INSTDIR\libprotobuf.lib"
Delete "$INSTDIR\QtCore4.dll"
Delete "$INSTDIR\QtGui4.dll"
Delete "$INSTDIR\QtNetwork4.dll"
Delete "$INSTDIR\QtSvg4.dll"
Delete "$INSTDIR\QtXml4.dll"
Delete "$INSTDIR\QtMultimedia4.dll"
RMDir "$INSTDIR"
RMDir "$INSTDIR"
RMDir /r "$SMPROGRAMS\Cockatrice"
DeleteRegKey HKCU "Software\Cockatrice"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice"
DeleteRegKey HKCU "Software\Cockatrice"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cockatrice"
SectionEnd
LangString DESC_SecApplication ${LANG_ENGLISH} "Cockatrice program files"
LangString DESC_SecUpdateConfig ${LANG_ENGLISH} "Update the paths in the application settings according to the installation paths."
LangString DESC_SecStartMenu ${LANG_ENGLISH} "Create start menu items for Cockatrice and Oracle."
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SecApplication} $(DESC_SecApplication)
!insertmacro MUI_DESCRIPTION_TEXT ${SecUpdateConfig} $(DESC_SecUpdateConfig)
!insertmacro MUI_DESCRIPTION_TEXT ${SecStartMenu} $(DESC_SecStartMenu)
!insertmacro MUI_DESCRIPTION_TEXT ${SecApplication} $(DESC_SecApplication)
!insertmacro MUI_DESCRIPTION_TEXT ${SecUpdateConfig} $(DESC_SecUpdateConfig)
!insertmacro MUI_DESCRIPTION_TEXT ${SecStartMenu} $(DESC_SecStartMenu)
!insertmacro MUI_FUNCTION_DESCRIPTION_END

View file

@ -26,7 +26,11 @@ INCLUDE_DIRECTORIES(../cockatrice/src)
# Build oracle binary and link it
ADD_EXECUTABLE(oracle WIN32 MACOSX_BUNDLE ${oracle_SOURCES} ${oracle_MOC_SRCS})
TARGET_LINK_LIBRARIES(oracle ${QT_LIBRARIES})
TARGET_LINK_LIBRARIES(oracle ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES})
if(MSVC)
set_target_properties(oracle PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS")
endif(MSVC)
if(UNIX)
if(APPLE)