diff --git a/.travis.yml b/.travis.yml index 9430365de..ee8290632 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,30 @@ language: cpp +branches: + except: + - latest-master before_install: - - export PSPDEV="$TRAVIS_BUILD_DIR/opt/pspsdk" - - export PSPSDK="$PSPDEV/psp/sdk" - - export PATH="$PATH:$PSPDEV/bin:$PSPSDK/bin" - - export ANDROID="android-sdk-linux/tools/android" +- export PSPDEV="$TRAVIS_BUILD_DIR/opt/pspsdk" +- export PSPSDK="$PSPDEV/psp/sdk" +- export PATH="$PATH:$PSPDEV/bin:$PSPSDK/bin" +- export ANDROID="android-sdk-linux/tools/android" install: - - sudo apt-get update -qq - - if [ `uname -m` = x86_64 ]; then sudo apt-get install -qq --force-yes libgd2-xpm ia32-libs ia32-libs-multiarch; fi - - wget -O sdk.lzma http://sourceforge.net/projects/minpspw/files/SDK%20%2B%20devpak/pspsdk%200.11.2/minpspw_0.11.2-amd64.tar.lzma/download - - tar -x --xz -f sdk.lzma - - wget http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64.tar.bz2 -nv - - wget http://dl.google.com/android/android-sdk_r22-linux.tgz -nv - - tar --absolute-names -jxf android-ndk-r9-linux-x86_64.tar.bz2 - - tar -zxf android-sdk_r22-linux.tgz - - echo yes | $ANDROID update sdk --filter 1,2,3,8 --no-ui --force > log.txt +- sudo add-apt-repository ppa:tobydox/mingw -y +- sudo apt-get update -qq +- if [ `uname -m` = x86_64 ]; then sudo apt-get install -qq --force-yes libgd2-xpm ia32-libs ia32-libs-multiarch jq mingw32-x-gcc mingw32-x-qt; fi +- sudo ln -s /opt/mingw32/bin/moc /opt/mingw32/bin/i686-w64-mingw32-moc +- wget -O sdk.lzma http://sourceforge.net/projects/minpspw/files/SDK%20%2B%20devpak/pspsdk%200.11.2/minpspw_0.11.2-amd64.tar.lzma/download +- tar -x --xz -f sdk.lzma +- wget http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64.tar.bz2 -nv +- wget http://dl.google.com/android/android-sdk_r22-linux.tgz -nv +- tar --absolute-names -jxf android-ndk-r9-linux-x86_64.tar.bz2 +- tar -zxf android-sdk_r22-linux.tgz +- $ANDROID list sdk --extended -a +- echo yes | $ANDROID update sdk -a --filter "tools","platform-tools","build-tools-19.0.1","android-10" --no-ui --force > log.txt +- sudo pip install pyjavaproperties +script: ./travis-script.sh +env: + global: + secure: "fJgWlCFbde96OSQNGKUmowGX+ERPeqP+n1EOMf1+FJzOU4DdkTLRAlV5+5qnEX9jB/3mWN6iPpmG1qEz/SdDG3KHxJYs4ZU/Lu485O24zZ/+GdYBNsrvhPD9ckPGEMLDa1foEVTDnW0Dlkz3BCFcszjhtXGUJv7v6Pj6LRk1Mg8=" + script: "./travis-script.sh" +after_success: ./upload-binaries.sh diff --git a/JGE/include/DebugRoutines.h b/JGE/include/DebugRoutines.h index 1ce188214..43569b162 100644 --- a/JGE/include/DebugRoutines.h +++ b/JGE/include/DebugRoutines.h @@ -61,7 +61,7 @@ std::string ToHex(T* pointer) { \ std::ostringstream stream; \ stream << inString << std::endl; \ - OutputDebugString(stream.str().c_str()); \ + OutputDebugStringA(stream.str().c_str()); \ } #endif // QT_CONFIG #endif // Win32, Linux diff --git a/JGE/include/Downloader.h b/JGE/include/Downloader.h new file mode 100644 index 000000000..96c643ae2 --- /dev/null +++ b/JGE/include/Downloader.h @@ -0,0 +1,128 @@ +#ifndef DOWNLOADER_H +#define DOWNLOADER_H + +//------------------------------------------------------------------------------------- +// +// This class handles download of remote resources (any kind of file) +// All the resources are stored locally in the userPath +// For every resources, the downloader verifies if the resource was modifed +// on the server before downloading the update. The Downloader maintains a catalogue +// of resource downloaded to be able to check if they need to be updated. +// +// The interface can be used completly synchronously by the application and some +// context or message loop is needed in the implementation of this interface +// +// Note that the Downloader could in theory by implemented on top of JNetwork. +// +//------------------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include "Threading.h" +#ifdef QT_CONFIG +#include +#include +#include +#include +#endif + +using namespace std; + +class DownloadRequest + #ifdef QT_CONFIG + : public QObject + #endif +{ +#ifdef QT_CONFIG + Q_OBJECT + +private slots: +#endif + void fileDownloaded(); + void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); + +#ifdef QT_CONFIG +signals: + void percentChanged(int percent); + void statusChanged(int); +#endif + +public: + typedef enum { + NOT_PRESENT, + DOWNLOADING, + DOWNLOADED, + DOWNLOAD_ERROR + } DownloadStatus; + +protected: + string mLocalPath; + string mRemoteResourceURL; + // previous one is the original, next one can change after redirection + string mRequestedRemoteResourceURL; + string mETag; + DownloadStatus mDownloadStatus; + bool mUpgradeAvailable; + size_t mTotalSize; + size_t mCurrentSize; + ofstream mFile; +#ifdef QT_CONFIG + QNetworkReply* mNetworkReply; + static QNetworkAccessManager networkAccessManager; +#endif + + +public: + DownloadRequest(string localPath="", + string remoteResourceURL="", + string ETag = "", + DownloadStatus downloadStatus=NOT_PRESENT, + size_t totalSize = 0, + size_t currentSize = 0); + ~DownloadRequest(); + static bool NetworkIsAccessible(); + + string getTempLocalPath() const { return (mLocalPath+".tmp"); }; + string getLocalPath() const { return mLocalPath; }; + string getRemoteResource() const { return mRemoteResourceURL; }; + string getETag() const { return mETag; }; + void startGet(); + void startHead(); + DownloadStatus getDownloadStatus() const { return mDownloadStatus; }; + bool upgradeAvailable() const { return mUpgradeAvailable; }; + void getSizes(size_t& totalSize, size_t¤tSize) { + totalSize = mTotalSize; + currentSize = mCurrentSize; + }; + + friend ostream& operator<<(ostream& out, const DownloadRequest& d); + friend istream& operator>>(istream&, DownloadRequest&); + friend class Downloader; +}; + + +class Downloader +{ +protected: + Downloader(string globalRemoteURL="", string localCacheRecords=""); + virtual ~Downloader(); + static Downloader* mInstance; + string mGlobalRemoteURL; + string mLocalCacheRecords; + boost::mutex mMutex; + map mRequestMap; + +public: + static Downloader* GetInstance(); + static void Release(); + + void Update(); + DownloadRequest* Get(string localPath, string remoteResourceURL=""); + + friend ostream& operator<<(ostream& out, const Downloader& d); + friend istream& operator>>(istream&, Downloader&); +}; + +#endif // DOWNLOADER_H diff --git a/JGE/include/JAnimator.h b/JGE/include/JAnimator.h index 794c6ce50..a525e3b88 100644 --- a/JGE/include/JAnimator.h +++ b/JGE/include/JAnimator.h @@ -297,7 +297,6 @@ public: private: float mTimer; float mFrameTime; - JAnimator* mAnimator; vector mObjects; }; diff --git a/JGE/include/JDistortionMesh.h b/JGE/include/JDistortionMesh.h index 10939a83e..171446a91 100644 --- a/JGE/include/JDistortionMesh.h +++ b/JGE/include/JDistortionMesh.h @@ -37,7 +37,6 @@ private: float mTexY; float mTexWidth; float mTexHeight; - JTexture* mTexture; JQuad* mQuad; diff --git a/JGE/include/JFileSystem.h b/JGE/include/JFileSystem.h index 6c658a8b3..25cdc7551 100644 --- a/JGE/include/JFileSystem.h +++ b/JGE/include/JFileSystem.h @@ -128,6 +128,7 @@ public: bool readIntoString(const string & FilePath, string & target); bool openForWrite(ofstream & File, const string & FilePath, ios_base::openmode mode = ios_base::out ); bool Rename(string from, string to); + bool Remove(string aFile); //Returns true if strFilename exists somewhere in the fileSystem bool FileExists(const string& strFilename); @@ -163,4 +164,4 @@ protected: -#endif \ No newline at end of file +#endif diff --git a/JGE/include/Threading.h b/JGE/include/Threading.h index 2c0667ce7..73036a27d 100644 --- a/JGE/include/Threading.h +++ b/JGE/include/Threading.h @@ -1,7 +1,7 @@ #ifndef THREADING_H #define THREADING_H -#if !defined(PSP) && !defined(QT_CONFIG) +#if !defined(PSP) && !defined(QT_CONFIG) && !(__cplusplus > 199711L) #include #ifdef WIN32 @@ -14,7 +14,7 @@ #endif #include -#elif !defined(QT_CONFIG) +#elif defined(PSP) #include #include @@ -26,7 +26,7 @@ namespace boost { /** - ** PSP specific variant of a boost mutex & scoped_lock + ** PSP specific variant of a boost mutex & scoped_lock */ template @@ -60,7 +60,7 @@ namespace boost { sceKernelDeleteSema(mID); } - + void lock() { int result = sceKernelWaitSema(mID, 1, 0); @@ -142,7 +142,7 @@ namespace boost } } - + int mID; int mThreadID; volatile int mRecursionCount; @@ -164,7 +164,7 @@ namespace boost /** - ** Emulating boost::thread configuration glue, with some shortcuts + ** Emulating boost::thread configuration glue, with some shortcuts ** This detail namespace is a distillation of boost's thread.hpp, thread_data.hpp. */ namespace detail @@ -212,13 +212,13 @@ namespace boost ** ** The intent of its usage is this form only: ** mWorkerThread = boost::thread(ThreadProc, this); - ** where ThreadProc is a static member function of the 'this' class,eg: - ** static void FOO::ThreadProc(void* inParam) - ** { - ** FOO* instance = reinterpret_cast(inParam); - ** // now you have class instance data available... - ** } - ** + ** where ThreadProc is a static member function of the 'this' class,eg: + ** static void FOO::ThreadProc(void* inParam) + ** { + ** FOO* instance = reinterpret_cast(inParam); + ** // now you have class instance data available... + ** } + ** ** Any other variant of a thread proc with more than one param is unimplemented. */ class thread @@ -227,7 +227,7 @@ namespace boost ** Helper class for sceKernelStartThread, which passes args by value, not by reference ** We use this struct to wrap any pointers that we want to pass to the worker thread. */ - struct CallbackData + struct CallbackData { CallbackData(detail::thread_data_ptr inThreadInfo) : mThreadInfo(inThreadInfo) @@ -307,7 +307,7 @@ namespace boost } } -#elif defined(QT_CONFIG) +#elif defined(QT_CONFIG) && (__cplusplus <= 199711L) #include #include @@ -537,6 +537,80 @@ namespace boost } } +#elif (__cplusplus > 199711L) + +#include +#include + +namespace boost +{ + typedef std::thread thread; + + template + struct unique_lock + { + unique_lock(Mutex& inMutex) : mMutex(&inMutex) + { + mMutex->lock(); + } + + ~unique_lock() + { + mMutex->unlock(); + } + + Mutex* mMutex; + }; + + class mutex + { + public: + + typedef unique_lock scoped_lock; + + mutex() + : mQMutex() + { + } + + ~mutex() + { + } + + void lock() + { + mQMutex.lock(); + } + + void unlock() + { + mQMutex.unlock(); + } + + std::mutex mQMutex; + + private: + mutex(mutex const&); + mutex& operator=(mutex const&); + }; + + namespace posix_time + { + typedef unsigned int milliseconds; + } + + /** + ** boost's platform neutral sleep call. + */ + namespace this_thread + { + inline void sleep(boost::posix_time::milliseconds const& time) + { + std::this_thread::sleep_for(std::chrono::milliseconds(time)); + } + } +} + #endif #endif // THREADING_H diff --git a/JGE/include/qt/corewrapper.h b/JGE/include/qt/corewrapper.h index 962f91bd4..cd019c6a7 100644 --- a/JGE/include/qt/corewrapper.h +++ b/JGE/include/qt/corewrapper.h @@ -136,6 +136,20 @@ signals: private slots: private: + int lastPosx(){ +#if QT_VERSION >= 0x050000 + return m_lastPos.x()*devicePixelRatio(); +#else + return m_lastPos.x(); +#endif + } + int lastPosy(){ +#if QT_VERSION >= 0x050000 + return m_lastPos.y()*devicePixelRatio(); +#else + return m_lastPos.y(); +#endif + } void timerEvent( QTimerEvent* ); void doAndEnqueue(JButton action) { m_engine->HoldKey_NoRepeat(action); @@ -154,6 +168,7 @@ private: int m_timerId; bool m_active; QRect m_viewPort; + QPoint m_lastPos; #ifdef QT_WIDGET #if (defined Q_WS_MAEMO_5) || (defined MEEGO_EDITION_HARMATTAN) || (defined Q_WS_ANDROID) int mMouseDownX; diff --git a/JGE/src/Downloader.cpp b/JGE/src/Downloader.cpp new file mode 100644 index 000000000..e1ba9eb26 --- /dev/null +++ b/JGE/src/Downloader.cpp @@ -0,0 +1,298 @@ +#include "DebugRoutines.h" +#include "JFileSystem.h" +#include "Downloader.h" + +#define RECORDS_DEFAULT_FILE "cache/records.txt" + +#ifdef QT_CONFIG +QNetworkAccessManager DownloadRequest::networkAccessManager; +#endif + +DownloadRequest::DownloadRequest(string localPath, + string remoteResourceURL, + string ETag, + DownloadStatus downloadStatus, + size_t totalSize, + size_t currentSize): + mLocalPath(localPath), + mRemoteResourceURL(remoteResourceURL), + mRequestedRemoteResourceURL(remoteResourceURL), + mETag(ETag), + mDownloadStatus(downloadStatus), + mUpgradeAvailable(false), + mTotalSize(totalSize), + mCurrentSize(currentSize) +{ +} + +DownloadRequest::~DownloadRequest() +{ +} + +void DownloadRequest::startHead() +{ +#ifdef QT_CONFIG + QNetworkRequest request(QUrl(QString(mRequestedRemoteResourceURL.c_str()))); + request.setRawHeader("If-None-Match", mETag.c_str()); + mNetworkReply = networkAccessManager.head(request); + connect(mNetworkReply, SIGNAL(finished()), SLOT(fileDownloaded())); +#endif +} + +void DownloadRequest::startGet() +{ +#ifdef QT_CONFIG + mNetworkReply = networkAccessManager.get(QNetworkRequest(QUrl(QString(mRequestedRemoteResourceURL.c_str())))); +#endif + mFile.close(); + JFileSystem::GetInstance()->Remove(getTempLocalPath()); + JFileSystem::GetInstance()->openForWrite(mFile, getTempLocalPath()); +#ifdef QT_CONFIG + connect(mNetworkReply, SIGNAL(downloadProgress(qint64, qint64)), + SLOT(downloadProgress(qint64, qint64))); + connect(mNetworkReply, SIGNAL(finished()), SLOT(fileDownloaded())); +#endif +} + +void DownloadRequest::fileDownloaded() +{ + do { + QByteArray eTagByteArray = mNetworkReply->rawHeader("ETag"); + if(!eTagByteArray.isEmpty()) { + string oldETag = mETag; + mETag = QString(eTagByteArray).toStdString(); + if(oldETag!="" && oldETag != mETag) + mUpgradeAvailable = true; + } + + // let's check some error + if(mNetworkReply->error() != QNetworkReply::NoError) { + DebugTrace(mNetworkReply->errorString().toStdString()); + mDownloadStatus = DownloadRequest::DOWNLOAD_ERROR; + mFile.close(); + JFileSystem::GetInstance()->Remove(getTempLocalPath()); + break; + } + + // check if we're getting redirected + QVariant redirectionTarget = mNetworkReply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (!redirectionTarget.isNull()) { + QUrl newUrl = QUrl(mRequestedRemoteResourceURL.c_str()).resolved(redirectionTarget.toUrl()); + DebugTrace(string("Redirect to ")+ newUrl.toString().toStdString()); + + mRequestedRemoteResourceURL = newUrl.toString().toStdString(); + mNetworkReply->deleteLater(); + if(mFile.is_open()) + startGet(); + else + startHead(); + return; + } + + if(mFile.is_open()) + { + QByteArray byteArray = mNetworkReply->readAll(); + mFile.write(byteArray.constData(), byteArray.size()); + mFile.close(); + if(!JFileSystem::GetInstance()->Rename(getTempLocalPath(), mLocalPath)) { + mDownloadStatus = DownloadRequest::DOWNLOAD_ERROR; + break; + } + } + mDownloadStatus = DownloadRequest::DOWNLOADED; + } while(0); + + Downloader::GetInstance()->Update(); + mNetworkReply->deleteLater(); + + emit statusChanged((int)mDownloadStatus); +} + +void DownloadRequest::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) +{ + QByteArray byteArray = mNetworkReply->readAll(); + mFile.write(byteArray.constData(), byteArray.size()); + mCurrentSize = bytesReceived; + mTotalSize = bytesTotal; + int percent = 0; + if(bytesTotal) + percent = (bytesReceived/bytesTotal)*100; + emit percentChanged(percent); +} + +Downloader* Downloader::mInstance = 0; + +Downloader::Downloader(string globalRemoteURL, string localcacheRecords): + mGlobalRemoteURL(globalRemoteURL), + mLocalCacheRecords(localcacheRecords) +{ + JFileSystem::GetInstance()->MakeDir("cache"); + + izfstream downloadRecords; + if(mLocalCacheRecords.empty()) + mLocalCacheRecords = RECORDS_DEFAULT_FILE; + if(JFileSystem::GetInstance()->openForRead(downloadRecords, mLocalCacheRecords)) + {// File exists, let's read it. + downloadRecords >> (*this); + } + JFileSystem::GetInstance()->CloseFile(); +} + +Downloader::~Downloader() +{ + map::iterator ite; + for(ite = mRequestMap.begin(); ite != mRequestMap.end(); ite++) + { + delete (*ite).second; + } + mRequestMap.erase(mRequestMap.begin(), mRequestMap.end()); +} + +Downloader* Downloader::GetInstance() +{ + if(!mInstance) + { + mInstance = new Downloader(); + } + return mInstance; +} + +void Downloader::Release() +{ + if(mInstance) + { + delete mInstance; + mInstance = 0; + } +} + +bool DownloadRequest::NetworkIsAccessible() +{ + bool result = false; + +#ifdef QT_CONFIG + networkAccessManager.setNetworkAccessible(QNetworkAccessManager::Accessible); + result = networkAccessManager.networkAccessible(); +#endif + + return result; +} + +DownloadRequest* Downloader::Get(string localPath, string remoteResourceURL) +{ + map::iterator ite = mRequestMap.find(localPath); + if(ite == mRequestMap.end()) + { // request does not exist, let's create it + DownloadRequest* request = new DownloadRequest(localPath, remoteResourceURL); + std::pair::iterator,bool> ret; + ret = mRequestMap.insert ( std::pair(localPath, request) ); + if (ret.second==false) { + DebugTrace("Downloader::Get Error inserting request in Map"); + return 0; + } + ite = ret.first; + } + + // Now, we can check the server + if((*ite).second->getDownloadStatus() == DownloadRequest::NOT_PRESENT || + (*ite).second->upgradeAvailable()) + { // File is not here or an update is available, let's get it + (*ite).second->startGet(); + (*ite).second->mDownloadStatus = DownloadRequest::DOWNLOADING; + } + else if ((*ite).second->getDownloadStatus() == DownloadRequest::DOWNLOADED) + { // File is here, let's check if there is some update without blocking the playback + (*ite).second->startHead(); + } + + return (*ite).second; +} + +void Downloader::Update() +{ + ofstream downloadRecords; + if(JFileSystem::GetInstance()->openForWrite(downloadRecords, mLocalCacheRecords)) + { + downloadRecords << (*this); + } + downloadRecords.close(); +} + +ostream& operator<<(ostream& out, const DownloadRequest& d) +{ +// HEAD request fails, so this line erase cache record after upgrade check :( +// if(d.getDownloadStatus() == DownloadRequest::DOWNLOADED) + { + out << "localPath=" << d.mLocalPath << endl; + out << "remoteResource=" << d.mRemoteResourceURL << endl; + out << "ETag=" << d.mETag << endl; + out << "upgradeAvailable=" << d.mUpgradeAvailable <>(istream& in, DownloadRequest& d) +{ + string s; + + while(std::getline(in, s)) + { + size_t limiter = s.find("="); + string areaS; + if (limiter != string::npos) + { + areaS = s.substr(0, limiter); + if (areaS.compare("localPath") == 0) + { + d.mLocalPath = s.substr(limiter + 1); + } + else if (areaS.compare("remoteResource") == 0) + { + d.mRemoteResourceURL = s.substr(limiter + 1); + d.mRequestedRemoteResourceURL = d.mRemoteResourceURL; + } + else if (areaS.compare("ETag") == 0) + { + d.mETag = s.substr(limiter + 1); + d.mDownloadStatus = DownloadRequest::DOWNLOADED; + } + else if (areaS.compare("upgradeAvailable") == 0) + { + d.mUpgradeAvailable = (bool)atoi(s.substr(limiter + 1).c_str()); + break; + } + } + } + + return in; +} + +ostream& operator<<(ostream& out, const Downloader& d) +{ + map::const_iterator ite; + for(ite = d.mRequestMap.begin(); ite != d.mRequestMap.end(); ite++) + { + out << (*(*ite).second) << endl; + } + return out; +} + +istream& operator>>(istream& in, Downloader& d) +{ + while(!in.eof()) + { + DownloadRequest* downloadRequest = new DownloadRequest(); + in >> (*downloadRequest); + + if(!downloadRequest->getLocalPath().empty() && + !downloadRequest->getRemoteResource().empty() && + !downloadRequest->getETag().empty()) { + d.mRequestMap[downloadRequest->getLocalPath()] = downloadRequest; + } else { + delete downloadRequest; + } + } + return in; +} + diff --git a/JGE/src/JFileSystem.cpp b/JGE/src/JFileSystem.cpp index cb377aa49..7d190c562 100644 --- a/JGE/src/JFileSystem.cpp +++ b/JGE/src/JFileSystem.cpp @@ -126,7 +126,7 @@ JFileSystem::JFileSystem(const string & _userPath, const string & _systemPath) DebugTrace("User path " << userPath); #elif defined (QT_CONFIG) - QDir sysDir("projects/mtg/bin/Res"); + QDir sysDir(RESDIR); QDir dir(QDir::homePath()); dir.mkdir(USERDIR); dir.cd(USERDIR); @@ -313,11 +313,15 @@ bool JFileSystem::readIntoString(const string & FilePath, string & target) int fileSize = GetFileSize(file); +#ifndef __MINGW32__ try { +#endif target.resize((std::string::size_type) fileSize); +#ifndef __MINGW32__ } catch (bad_alloc&) { return false; } +#endif if (fileSize) @@ -553,7 +557,13 @@ bool JFileSystem::Rename(string _from, string _to) string from = mUserFSPath + _from; string to = mUserFSPath + _to; std::remove(to.c_str()); - return rename(from.c_str(), to.c_str()) ? true: false; + return (rename(from.c_str(), to.c_str()) == 0); +} + +bool JFileSystem::Remove(string aFile) +{ + string toRemove = mUserFSPath + aFile; + return (std::remove(toRemove.c_str()) == 0); } int JFileSystem::GetFileSize(izfstream & file) diff --git a/JGE/src/Qtconsole.cpp b/JGE/src/Qtconsole.cpp index a09f5ba25..447f0d8ba 100644 --- a/JGE/src/Qtconsole.cpp +++ b/JGE/src/Qtconsole.cpp @@ -96,9 +96,8 @@ int main(int argc, char* argv[]) options.reloadProfile(); TestSuite testSuite("test/_tests.txt"); result = testSuite.run(); - int totalTests = testSuite.nbTests + testSuite.nbAITests; delete wagicCore; - DebugTrace("TestSuite done: failed test: " << result << " out of " << totalTests << " total"); + DebugTrace("TestSuite done: failed test: " << result << " out of " << testSuite.nbTests + testSuite.nbAITests << " total"); #ifdef CAPTURE_STDERR OutputCapturer::debugAndClear(); #endif diff --git a/JGE/src/Qtmain.cpp b/JGE/src/Qtmain.cpp index f21d6bdb7..2b0f22cbd 100644 --- a/JGE/src/Qtmain.cpp +++ b/JGE/src/Qtmain.cpp @@ -9,11 +9,11 @@ #include #include "qmlapplicationviewer.h" #endif //QT_WIDGET -#include "filedownloader.h" +#include "Downloader.h" #include "GameApp.h" #include "corewrapper.h" -QWidget* g_glwidget = NULL; +WagicCore* g_glwidget = NULL; static const struct { LocalKeySym keysym; JButton keycode; } gDefaultBindings[] = { @@ -69,18 +69,25 @@ int main(int argc, char* argv[]) #endif //QT_WIDGET - if(argc >= 2 && string(argv[1]) == "testsuite") - { - int result = 0; - result += WagicCore::runTestSuite(); - return result; - } - app->setApplicationName(WagicCore::getApplicationName()); - FileDownloader fileDownloader(USERDIR, WAGIC_RESOURCE_NAME); + DownloadRequest* downloadRequest = NULL; +#ifdef WAGIC_RESOURCE_URL + Downloader*downloader = Downloader::GetInstance(); + downloadRequest = downloader->Get( + "core.zip", + WAGIC_RESOURCE_URL + ); +#endif #ifdef QT_WIDGET g_glwidget = new WagicCore(); - g_glwidget->connect(&fileDownloader, SIGNAL(finished(int)), SLOT(start(int))); + if(!downloadRequest || downloadRequest->getDownloadStatus() == DownloadRequest::DOWNLOADED) + { + g_glwidget->start(0); + } + else + { + g_glwidget->connect(downloadRequest, SIGNAL(statusChanged(int)), SLOT(start(int))); + } #else qmlRegisterType("CustomComponents", 1, 0, "WagicCore"); diff --git a/JGE/src/SDLmain.cpp b/JGE/src/SDLmain.cpp index d3323890d..bf09628fd 100644 --- a/JGE/src/SDLmain.cpp +++ b/JGE/src/SDLmain.cpp @@ -78,7 +78,20 @@ extern "C" void Java_org_libsdl_app_SDLActivity_nativeResume( { if (!g_engine) return; - g_engine->Resume(); + g_engine->Resume(); +} + +#include "Wagic_Version.h" +extern "C" jstring Java_org_libsdl_app_SDLActivity_getResourceName( + JNIEnv* env, jclass cls) +{ + return env->NewStringUTF (WAGIC_RESOURCE_NAME); +} + +extern "C" jstring Java_org_libsdl_app_SDLActivity_getResourceUrl( + JNIEnv* env, jclass cls) +{ + return env->NewStringUTF (WAGIC_RESOURCE_URL); } #endif diff --git a/JGE/src/pc/JGfx.cpp b/JGE/src/pc/JGfx.cpp index ea71b167c..093e2035e 100644 --- a/JGE/src/pc/JGfx.cpp +++ b/JGE/src/pc/JGfx.cpp @@ -2486,7 +2486,7 @@ void JRenderer::Enable2D() #if (defined GL_VERSION_ES_CM_1_1) || (defined GL_OES_VERSION_1_1) glOrthof(0.0f, SCREEN_WIDTH_F, 0.0f, SCREEN_HEIGHT_F-1.0f, -1.0f, 1.0f); #else - gluOrtho2D(0.0f, SCREEN_WIDTH_F, 0.0f, SCREEN_HEIGHT_F-1.0f); + glOrtho(0.0f, SCREEN_WIDTH_F, 0.0f, SCREEN_HEIGHT_F-1.0f, -1.0f, 1.0f); #endif glMatrixMode (GL_MODELVIEW); // Select The Modelview Matrix diff --git a/JGE/src/qt/corewrapper.cpp b/JGE/src/qt/corewrapper.cpp index 656a35132..e121fc479 100644 --- a/JGE/src/qt/corewrapper.cpp +++ b/JGE/src/qt/corewrapper.cpp @@ -335,7 +335,7 @@ void WagicCore::resizeGL(int width, int height) #if (defined GL_VERSION_ES_CM_1_1 || defined GL_OES_VERSION_1_1) glOrthof(0.0f, (float) (m_viewPort.right()-m_viewPort.left())-1.0f, 0.0f, (float) (m_viewPort.bottom()-m_viewPort.top())-1.0f, -1.0f, 1.0f); #else - gluOrtho2D(0.0f, (float) (m_viewPort.right()-m_viewPort.left())-1.0f, 0.0f, (float) (m_viewPort.bottom()-m_viewPort.top())-1.0f); + glOrtho(0.0f, (float) (m_viewPort.right()-m_viewPort.left())-1.0f, 0.0f, (float) (m_viewPort.bottom()-m_viewPort.top())-1.0f, -1.0f, 1.0f); #endif glMatrixMode (GL_MODELVIEW); // Select The Modelview Matrix @@ -418,29 +418,29 @@ void WagicCore::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) { - QPoint lastPos = event->pos(); + m_lastPos = event->pos(); // this is intended to convert window coordinate into game coordinate. // this is correct only if the game and window have the same aspect ratio, otherwise, it's just wrong int actualWidth = (int) JRenderer::GetInstance()->GetActualWidth(); int actualHeight = (int) JRenderer::GetInstance()->GetActualHeight(); - if (lastPos.y() >= m_viewPort.top() && - lastPos.y() <= m_viewPort.bottom() && - lastPos.x() <= m_viewPort.right() && - lastPos.x() >= m_viewPort.left()) { + if (lastPosy() >= m_viewPort.top() && + lastPosy() <= m_viewPort.bottom() && + lastPosx() <= m_viewPort.right() && + lastPosx() >= m_viewPort.left()) { m_engine->LeftClicked( - ((lastPos.x()-m_viewPort.left())*SCREEN_WIDTH)/actualWidth, - ((lastPos.y()-m_viewPort.top())*SCREEN_HEIGHT)/actualHeight); + ((lastPosx()-m_viewPort.left())*SCREEN_WIDTH)/actualWidth, + ((lastPosy()-m_viewPort.top())*SCREEN_HEIGHT)/actualHeight); #if (!defined Q_WS_MAEMO_5) && (!defined MEEGO_EDITION_HARMATTAN) && (!defined Q_WS_ANDROID) m_engine->HoldKey_NoRepeat(JGE_BTN_OK); #else - mMouseDownX = lastPos.x(); - mMouseDownY = lastPos.y(); + mMouseDownX = lastPosx(); + mMouseDownY = lastPosy(); mLastFingerDownTime = g_startTimer.elapsed(); #endif - } else if(lastPos.y()HoldKey_NoRepeat(JGE_BTN_MENU); - } else if(lastPos.y()>m_viewPort.bottom()) { + } else if(lastPosy()>m_viewPort.bottom()) { m_engine->HoldKey_NoRepeat(JGE_BTN_NEXT); } event->accept(); @@ -465,33 +465,33 @@ void WagicCore::mouseReleaseEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) { - QPoint lastPos = event->pos(); + m_lastPos = event->pos(); - if (lastPos.y() >= m_viewPort.top() && - lastPos.y() <= m_viewPort.bottom() && - lastPos.x() <= m_viewPort.right() && - lastPos.x() >= m_viewPort.left()) { + if (lastPosy() >= m_viewPort.top() && + lastPosy() <= m_viewPort.bottom() && + lastPosx() <= m_viewPort.right() && + lastPosx() >= m_viewPort.left()) { #if (defined Q_WS_MAEMO_5) || (defined MEEGO_EDITION_HARMATTAN) || (defined Q_WS_ANDROID) if(g_startTimer.elapsed() - mLastFingerDownTime <= kTapEventTimeout ) { - if(abs(mMouseDownX - lastPos.x()) < kHitzonePliancy && - abs(mMouseDownY - lastPos.y()) < kHitzonePliancy) + if(abs(mMouseDownX - lastPosx()) < kHitzonePliancy && + abs(mMouseDownY - lastPosy()) < kHitzonePliancy) { m_engine->HoldKey_NoRepeat(JGE_BTN_OK); } } else if (g_startTimer.elapsed() - mLastFingerDownTime >= kSwipeEventMinDuration) { // Let's swipe - m_engine->Scroll(lastPos.x()-mMouseDownX, lastPos.y()-mMouseDownY); + m_engine->Scroll(lastPosx()-mMouseDownX, lastPosy()-mMouseDownY); } #else //#if (!defined Q_WS_MAEMO_5) && (!defined MEEGO_EDITION_HARMATTAN) m_engine->ReleaseKey(JGE_BTN_OK); #endif m_engine->ReleaseKey(JGE_BTN_MENU); - } else if(lastPos.y() < m_viewPort.top()) { + } else if(lastPosy() < m_viewPort.top()) { m_engine->ReleaseKey(JGE_BTN_MENU); - } else if(lastPos.y() > m_viewPort.bottom()) { + } else if(lastPosy() > m_viewPort.bottom()) { m_engine->ReleaseKey(JGE_BTN_NEXT); } event->accept(); @@ -517,15 +517,15 @@ void WagicCore::mouseMoveEvent(QMouseEvent *event) int actualWidth = (int) JRenderer::GetInstance()->GetActualWidth(); int actualHeight = (int) JRenderer::GetInstance()->GetActualHeight(); - QPoint lastPos = event->pos(); + m_lastPos = event->pos(); - if (lastPos.y() >= m_viewPort.top() && - lastPos.y() <= m_viewPort.bottom() && - lastPos.x() <= m_viewPort.right() && - lastPos.x() >= m_viewPort.left()) { + if (lastPosy() >= m_viewPort.top() && + lastPosy() <= m_viewPort.bottom() && + lastPosx() <= m_viewPort.right() && + lastPosx() >= m_viewPort.left()) { m_engine->LeftClicked( - ((lastPos.x()-m_viewPort.left())*SCREEN_WIDTH)/actualWidth, - ((lastPos.y()-m_viewPort.top())*SCREEN_HEIGHT)/actualHeight); + ((lastPosx()-m_viewPort.left())*SCREEN_WIDTH)/actualWidth, + ((lastPosy()-m_viewPort.top())*SCREEN_HEIGHT)/actualHeight); event->accept(); } else { super::mouseMoveEvent(event); diff --git a/JGE/src/zipFS/zstream.h b/JGE/src/zipFS/zstream.h index 2f5d9b9f9..0e8b3bf19 100644 --- a/JGE/src/zipFS/zstream.h +++ b/JGE/src/zipFS/zstream.h @@ -106,6 +106,7 @@ public: virtual int overflow(int c = EOF); virtual int underflow(); virtual int sync(); + using std::streambuf::setbuf; virtual std::streambuf * setbuf(char * pr, int nLength); virtual std::streampos seekoff(std::streamoff, std::ios::seekdir, std::ios::openmode); @@ -131,6 +132,7 @@ public: virtual int overflow(int c = EOF); virtual int underflow(); virtual int sync(); + using std::streambuf::setbuf; virtual std::streambuf * setbuf(char * pr, int nLength); virtual std::streampos seekoff(std::streamoff, std::ios::seekdir, std::ios::openmode); diff --git a/README.md b/README.md index 1ea3ee9bb..1ac0bfee0 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,6 @@ Wagic, the Homebrew, is a C++ game engine that allows to play card games against It is highly customizable and allows the player to tweak the rules / create their own cards, their own themes, etc... -Info, Downloads, and more at http://wololo.net +Info, downloads, discussions and more at http://wololo.net/forum/index.php -![alt text](http://wololo.net/wagic/wp-content/uploads/2009/10/shop.jpg "Screenshot") diff --git a/projects/mtg/Android/jni/Android.mk b/projects/mtg/Android/jni/Android.mk index e502bef9c..31f425266 100644 --- a/projects/mtg/Android/jni/Android.mk +++ b/projects/mtg/Android/jni/Android.mk @@ -136,6 +136,9 @@ LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.cpp \ $(MTG_PATH)/src/WFont.cpp \ $(MTG_PATH)/src/WGui.cpp \ $(MTG_PATH)/src/WResourceManager.cpp \ + $(MTG_PATH)/src/DeckView.cpp \ + $(MTG_PATH)/src/CarouselDeckView.cpp \ + $(MTG_PATH)/src/GridDeckView.cpp \ $(JGE_PATH)/src/SDLmain.cpp \ $(JGE_PATH)/src/Encoding.cpp \ $(JGE_PATH)/src/JAnimator.cpp \ diff --git a/projects/mtg/Android/src/org/libsdl/app/SDLActivity.java b/projects/mtg/Android/src/org/libsdl/app/SDLActivity.java index 0891808c8..847475a48 100644 --- a/projects/mtg/Android/src/org/libsdl/app/SDLActivity.java +++ b/projects/mtg/Android/src/org/libsdl/app/SDLActivity.java @@ -80,7 +80,6 @@ public class SDLActivity extends Activity implements OnKeyListener public Boolean mErrorHappened = false; public final static String RES_FOLDER = Environment.getExternalStorageDirectory().getPath() + "/Wagic/Res/"; public static String RES_FILENAME = "core_0184.zip"; - public static final String RES_URL = "http://wagic.googlecode.com/files/"; public String systemFolder = Environment.getExternalStorageDirectory().getPath() + "/Wagic/Res/"; private String userFolder; @@ -307,7 +306,7 @@ public class SDLActivity extends Activity implements OnKeyListener private void startDownload() { - String url = RES_URL + RES_FILENAME; + String url = getResourceUrl(); if (!checkStorageState()) { Log.e(TAG, "Error in initializing storage space."); @@ -437,7 +436,7 @@ public class SDLActivity extends Activity implements OnKeyListener mContext = this.getApplicationContext(); // get the current version of the app to set the core filename String versionCodeString = getApplicationCode(); - RES_FILENAME = "core_" + versionCodeString + ".zip"; + RES_FILENAME = getResourceName(); StorageOptions.determineStorageOptions(); checkStorageLocationPreference(); @@ -525,6 +524,9 @@ public class SDLActivity extends Activity implements OnKeyListener } // C functions we call + public static native String getResourceUrl(); + public static native String getResourceName(); + public static native void nativeInit(); public static native void nativeQuit(); diff --git a/projects/mtg/Makefile b/projects/mtg/Makefile index a77114104..a5db9bda5 100644 --- a/projects/mtg/Makefile +++ b/projects/mtg/Makefile @@ -27,7 +27,7 @@ OBJS = objs/InteractiveButton.o objs/AbilityParser.o objs/ActionElement.o\ objs/ThisDescriptor.o objs/Token.o objs/Translate.o objs/TranslateKeys.o\ objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o\ objs/WCachedResource.o objs/WDataSrc.o objs/WGui.o objs/WFilter.o objs/Tasks.o\ - objs/WFont.o + objs/WFont.o objs/CarouselDeckView.o objs/GridDeckView.o objs/DeckView.o DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS)) RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache) diff --git a/projects/mtg/bin/Res/createResourceZip.py b/projects/mtg/bin/Res/createResourceZip.py index 3699b882b..ff5ed73d5 100644 --- a/projects/mtg/bin/Res/createResourceZip.py +++ b/projects/mtg/bin/Res/createResourceZip.py @@ -7,10 +7,13 @@ from optparse import OptionParser def createResZipFile(filename): utilities = ZipUtilities() + rename = False if not os.path.isfile('settings/options.txt'): os.rename('settings/options.orig.txt', 'settings/options.txt') + remame = True if not os.path.isfile('player/options.txt'): os.rename('player/options.orig.txt', 'player/options.txt') + rename = True zip_file = zipfile.ZipFile(filename, 'w', zipfile.ZIP_STORED) utilities.addFolderToZip(zip_file, 'themes') @@ -25,6 +28,10 @@ def createResZipFile(filename): utilities.addFolderToZip(zip_file, 'campaigns') utilities.addFolderToZip(zip_file, 'ai') zip_file.close() + + if rename: + os.rename('settings/options.txt', 'settings/options.orig.txt') + os.rename('player/options.txt', 'player/options.orig.txt') def getFilename(): p = Properties(); diff --git a/projects/mtg/bin/Res/rules/mtg.txt b/projects/mtg/bin/Res/rules/mtg.txt index 10bbdd90f..38f2f9b84 100644 --- a/projects/mtg/bin/Res/rules/mtg.txt +++ b/projects/mtg/bin/Res/rules/mtg.txt @@ -16,6 +16,7 @@ auto=flashbackrule auto=retracerule auto=suspendrule auto=morphrule +auto=playfromgraveyardrule auto=attackrule auto=blockrule auto=combattriggerrule diff --git a/projects/mtg/bin/Res/sets/LRW/_cards.dat b/projects/mtg/bin/Res/sets/LRW/_cards.dat index c1af94093..58a8ff115 100644 --- a/projects/mtg/bin/Res/sets/LRW/_cards.dat +++ b/projects/mtg/bin/Res/sets/LRW/_cards.dat @@ -1513,3 +1513,8 @@ primitive=Zephyr Net id=142357 rarity=C [/card] +[card] +primitive=Avatar Token +id=-140233 +rarity=T +[/card] diff --git a/projects/mtg/bin/Res/sets/M10/_cards.dat b/projects/mtg/bin/Res/sets/M10/_cards.dat index c9c2592fa..d3c646fcd 100644 --- a/projects/mtg/bin/Res/sets/M10/_cards.dat +++ b/projects/mtg/bin/Res/sets/M10/_cards.dat @@ -1248,3 +1248,8 @@ primitive=Zombie Goliath id=190545 rarity=C [/card] +[card] +primitive=Avatar Token +id=-191239 +rarity=T +[/card] diff --git a/projects/mtg/bin/Res/sets/M11/_cards.dat b/projects/mtg/bin/Res/sets/M11/_cards.dat index 6d645a9c3..233184b6b 100644 --- a/projects/mtg/bin/Res/sets/M11/_cards.dat +++ b/projects/mtg/bin/Res/sets/M11/_cards.dat @@ -1257,4 +1257,9 @@ rarity=U primitive=Yavimaya Wurm id=205221 rarity=C -[/card] \ No newline at end of file +[/card] +[card] +primitive=Avatar Token +id=-205957 +rarity=T +[/card] diff --git a/projects/mtg/bin/Res/sets/M14/_cards.dat b/projects/mtg/bin/Res/sets/M14/_cards.dat new file mode 100644 index 000000000..c2c52c8be --- /dev/null +++ b/projects/mtg/bin/Res/sets/M14/_cards.dat @@ -0,0 +1,1259 @@ +[meta] +author=Wagic Team +name=Magic 2014 +year=2013 +[/meta] +[card] +primitive=Academy Raider +id=370735 +rarity=C +[/card] +[card] +primitive=Accorder's Shield +id=370581 +rarity=C +[/card] +[card] +primitive=Accursed Spirit +id=370811 +rarity=C +[/card] +[card] +primitive=Act of Treason +id=370618 +rarity=C +[/card] +[card] +primitive=Advocate of the Beast +id=370738 +rarity=C +[/card] +[card] +primitive=Air Servant +id=370688 +rarity=C +[/card] +[card] +primitive=Ajani, Caller of the Pride +id=370680 +rarity=M +[/card] +[card] +primitive=Ajani's Chosen +id=370750 +rarity=R +[/card] +[card] +primitive=Altar's Reap +id=370677 +rarity=C +[/card] +[card] +primitive=Angelic Accord +id=370612 +rarity=U +[/card] +[card] +primitive=Angelic Wall +id=370789 +rarity=C +[/card] +[card] +primitive=Archaeomancer +id=370753 +rarity=C +[/card] +[card] +primitive=Archangel of Thune +id=370627 +rarity=M +[/card] +[card] +primitive=Armored Cancrix +id=370632 +rarity=C +[/card] +[card] +primitive=Artificer's Hex +id=370634 +rarity=U +[/card] +[card] +primitive=Auramancer +id=370793 +rarity=C +[/card] +[card] +primitive=Awaken the Ancient +id=370613 +rarity=R +[/card] +[card] +primitive=Banisher Priest +id=370624 +rarity=U +[/card] +[card] +primitive=Barrage of Expendables +id=370822 +rarity=U +[/card] +[card] +primitive=Battle Sliver +id=370639 +rarity=U +[/card] +[card] +primitive=Blessing +id=370819 +rarity=U +[/card] +[card] +primitive=Blightcaster +id=370761 +rarity=U +[/card] +[card] +primitive=Blood Bairn +id=370698 +rarity=C +[/card] +[card] +primitive=Blur Sliver +id=370593 +rarity=U +[/card] +[card] +primitive=Bogbrew Witch +id=370758 +rarity=R +[/card] +[card] +primitive=Bonescythe Sliver +id=370801 +rarity=R +[/card] +[card] +primitive=Bramblecrush +id=370642 +rarity=U +[/card] +[card] +primitive=Brave the Elements +id=370816 +rarity=U +[/card] +[card] +primitive=Briarpack Alpha +id=370739 +rarity=U +[/card] +[card] +primitive=Brindle Boar +id=370778 +rarity=C +[/card] +[card] +primitive=Bubbling Cauldron +id=370661 +rarity=R +[/card] +[card] +primitive=Burning Earth +id=370696 +rarity=R +[/card] +[card] +primitive=Cancel +id=370755 +rarity=C +[/card] +[card] +primitive=Canyon Minotaur +id=370757 +rarity=C +[/card] +[card] +primitive=Capashen Knight +id=370821 +rarity=C +[/card] +[card] +primitive=Celestial Flare +id=370666 +rarity=C +[/card] +[card] +primitive=Chandra, Pyromaster +id=370637 +rarity=M +[/card] +[card] +primitive=Chandra's Outrage +id=370659 +rarity=C +[/card] +[card] +primitive=Chandra's Phoenix +id=370691 +rarity=R +[/card] +[card] +primitive=Charging Griffin +id=370768 +rarity=C +[/card] +[card] +primitive=Child of Night +id=370823 +rarity=C +[/card] +[card] +primitive=Claustrophobia +id=370653 +rarity=C +[/card] +[card] +primitive=Clone +id=370622 +rarity=R +[/card] +[card] +primitive=Colossal Whale +id=370685 +rarity=R +[/card] +[card] +primitive=Congregate +id=370804 +rarity=U +[/card] +[card] +primitive=Coral Merfolk +id=370667 +rarity=C +[/card] +[card] +primitive=Corpse Hauler +id=370800 +rarity=C +[/card] +[card] +primitive=Corrupt +id=370630 +rarity=U +[/card] +[card] +primitive=Cyclops Tyrant +id=370585 +rarity=C +[/card] +[card] +primitive=Dark Favor +id=370782 +rarity=C +[/card] +[card] +primitive=Dark Prophecy +id=370596 +rarity=R +[/card] +[card] +primitive=Darksteel Forge +id=370734 +rarity=R +[/card] +[card] +primitive=Darksteel Ingot +id=370675 +rarity=U +[/card] +[card] +primitive=Dawnstrike Paladin +id=370721 +rarity=C +[/card] +[card] +primitive=Deadly Recluse +id=370582 +rarity=C +[/card] +[card] +primitive=Deathgaze Cockatrice +id=370775 +rarity=C +[/card] +[card] +primitive=Demolish +id=370621 +rarity=C +[/card] +[card] +primitive=Devout Invocation +id=370726 +rarity=M +[/card] +[card] +primitive=Diabolic Tutor +id=370732 +rarity=U +[/card] +[card] +primitive=Dismiss into Dream +id=370796 +rarity=R +[/card] +[card] +primitive=Disperse +id=370818 +rarity=C +[/card] +[card] +primitive=Divination +id=370616 +rarity=C +[/card] +[card] +primitive=Divine Favor +id=370748 +rarity=C +[/card] +[card] +primitive=Domestication +id=370783 +rarity=R +[/card] +[card] +primitive=Doom Blade +id=370609 +rarity=C +[/card] +[card] +primitive=Door of Destinies +id=370699 +rarity=R +[/card] +[card] +primitive=Dragon Egg +id=370660 +rarity=U +[/card] +[card] +primitive=Dragon Hatchling +id=370717 +rarity=C +[/card] +[card] +primitive=Duress +id=370577 +rarity=C +[/card] +[card] +primitive=Elite Arcanist +id=370747 +rarity=R +[/card] +[card] +primitive=Elixir of Immortality +id=370681 +rarity=U +[/card] +[card] +primitive=Elvish Mystic +id=370744 +rarity=C +[/card] +[card] +primitive=Encroaching Wastes +id=370769 +rarity=U +[/card] +[card] +primitive=Enlarge +id=370797 +rarity=U +[/card] +[card] +primitive=Essence Scatter +id=370694 +rarity=C +[/card] +[card] +primitive=Festering Newt +id=370772 +rarity=C +[/card] +[card] +primitive=Fiendslayer Paladin +id=370786 +rarity=R +[/card] +[card] +primitive=Fireshrieker +id=370715 +rarity=U +[/card] +[card] +primitive=Flames of the Firebrand +id=370824 +rarity=U +[/card] +[card] +primitive=Fleshpulper Giant +id=370741 +rarity=U +[/card] +[card] +primitive=Fog +id=370633 +rarity=C +[/card] +[card] +primitive=Forest +id=370598 +rarity=C +[/card] +[card] +primitive=Forest +id=370729 +rarity=C +[/card] +[card] +primitive=Forest +id=370756 +rarity=C +[/card] +[card] +primitive=Forest +id=370771 +rarity=C +[/card] +[card] +primitive=Fortify +id=370712 +rarity=U +[/card] +[card] +primitive=Frost Breath +id=370678 +rarity=C +[/card] +[card] +primitive=Galerider Sliver +id=370590 +rarity=R +[/card] +[card] +primitive=Garruk, Caller of Beasts +id=370687 +rarity=M +[/card] +[card] +primitive=Garruk's Horde +id=370684 +rarity=R +[/card] +[card] +primitive=Giant Growth +id=370788 +rarity=C +[/card] +[card] +primitive=Giant Spider +id=370781 +rarity=C +[/card] +[card] +primitive=Gladecover Scout +id=370716 +rarity=C +[/card] +[card] +primitive=Glimpse the Future +id=370774 +rarity=U +[/card] +[card] +primitive=Gnawing Zombie +id=370682 +rarity=U +[/card] +[card] +primitive=Goblin Diplomats +id=370674 +rarity=R +[/card] +[card] +primitive=Goblin Shortcutter +id=370610 +rarity=C +[/card] +[card] +primitive=Griffin Sentinel +id=370792 +rarity=C +[/card] +[card] +primitive=Grim Return +id=370776 +rarity=R +[/card] +[card] +primitive=Groundshaker Sliver +id=370626 +rarity=C +[/card] +[card] +primitive=Guardian of the Ages +id=370603 +rarity=R +[/card] +[card] +primitive=Haunted Plate Mail +id=370594 +rarity=R +[/card] +[card] +primitive=Hive Stirrings +id=370817 +rarity=C +[/card] +[card] +primitive=Howl of the Night Pack +id=370718 +rarity=U +[/card] +[card] +primitive=Hunt the Weak +id=370743 +rarity=C +[/card] +[card] +primitive=Illusionary Armor +id=370701 +rarity=U +[/card] +[card] +primitive=Imposing Sovereign +id=370770 +rarity=R +[/card] +[card] +primitive=Indestructibility +id=370673 +rarity=R +[/card] +[card] +primitive=Into the Wilds +id=370579 +rarity=R +[/card] +[card] +primitive=Island +id=370608 +rarity=C +[/card] +[card] +primitive=Island +id=370611 +rarity=C +[/card] +[card] +primitive=Island +id=370647 +rarity=C +[/card] +[card] +primitive=Island +id=370773 +rarity=C +[/card] +[card] +primitive=Jace, Memory Adept +id=370728 +rarity=M +[/card] +[card] +primitive=Jace's Mindseeker +id=370638 +rarity=R +[/card] +[card] +primitive=Kalonian Hydra +id=370766 +rarity=R +[/card] +[card] +primitive=Kalonian Tusker +id=370700 +rarity=U +[/card] +[card] +primitive=Lava Axe +id=370595 +rarity= +[/card] +[card] +primitive=Lay of the Land +id=370767 +rarity=C +[/card] +[card] +primitive=Lifebane Zombie +id=370723 +rarity=R +[/card] +[card] +primitive=Lightning Talons +id=370795 +rarity=C +[/card] +[card] +primitive=Liliana of the Dark Realms +id=370658 +rarity=M +[/card] +[card] +primitive=Liliana's Reaver +id=370740 +rarity=R +[/card] +[card] +primitive=Zombie Token +id=-339967 +rarity=T +[/card] +[card] +primitive=Liturgy of Blood +id=370652 +rarity=C +[/card] +[card] +primitive=Manaweft Sliver +id=370599 +rarity=U +[/card] +[card] +primitive=Marauding Maulhorn +id=370648 +rarity=C +[/card] +[card] +primitive=Mark of the Vampire +id=370787 +rarity=C +[/card] +[card] +primitive=Master of Diversion +id=370708 +rarity=C +[/card] +[card] +primitive=Megantic Sliver +id=370794 +rarity=R +[/card] +[card] +primitive=Merfolk Spy +id=370762 +rarity=C +[/card] +[card] +primitive=Messenger Drake +id=370807 +rarity=C +[/card] +[card] +primitive=Millstone +id=370737 +rarity=U +[/card] +[card] +primitive=Mind Rot +id=370711 +rarity=C +[/card] +[card] +primitive=Mindsparker +id=370695 +rarity=R +[/card] +[card] +primitive=Minotaur Abomination +id=370683 +rarity=C +[/card] +[card] +primitive=Molten Birth +id=370604 +rarity=U +[/card] +[card] +primitive=Mountain +id=370583 +rarity=C +[/card] +[card] +primitive=Mountain +id=370588 +rarity=C +[/card] +[card] +primitive=Mountain +id=370591 +rarity=C +[/card] +[card] +primitive=Mountain +id=370725 +rarity=C +[/card] +[card] +primitive=Mutavault +id=370733 +rarity=R +[/card] +[card] +primitive=Naturalize +id=370802 +rarity=C +[/card] +[card] +primitive=Negate +id=370719 +rarity=C +[/card] +[card] +primitive=Nephalia Seakite +id=370760 +rarity=C +[/card] +[card] +primitive=Nightmare +id=370689 +rarity=R +[/card] +[card] +primitive=Nightwing Shade +id=370705 +rarity=U +[/card] +[card] +primitive=Oath of the Ancient Wood +id=370763 +rarity=R +[/card] +[card] +primitive=Ogre Battledriver +id=370662 +rarity=R +[/card] +[card] +primitive=Opportunity +id=370751 +rarity=U +[/card] +[card] +primitive=Pacifism +id=370812 +rarity=C +[/card] +[card] +primitive=Path of Bravery +id=370798 +rarity=R +[/card] +[card] +primitive=Pay No Heed +id=370742 +rarity=C +[/card] +[card] +primitive=Phantom Warrior +id=370650 +rarity=U +[/card] +[card] +primitive=Pillarfield Ox +id=370765 +rarity=C +[/card] +[card] +primitive=Pitchburn Devils +id=370649 +rarity=C +[/card] +[card] +primitive=Plains +id=370615 +rarity=C +[/card] +[card] +primitive=Plains +id=370669 +rarity=C +[/card] +[card] +primitive=Plains +id=370679 +rarity=C +[/card] +[card] +primitive=Plains +id=370754 +rarity=C +[/card] +[card] +primitive=Planar Cleansing +id=370808 +rarity=R +[/card] +[card] +primitive=Plummet +id=370601 +rarity=C +[/card] +[card] +primitive=Predatory Sliver +id=370745 +rarity=C +[/card] +[card] +primitive=Primeval Bounty +id=370656 +rarity=M +[/card] +[card] +primitive=Pyromancer's Guantlet +id=370686 +rarity=R +[/card] +[card] +primitive=Quag Sickness +id=370714 +rarity=U +[/card] +[card] +primitive=Quicken +id=370644 +rarity=R +[/card] +[card] +primitive=Ranger's Guile +id=370803 +rarity=C +[/card] +[card] +primitive=Ratchet Bomb +id=370623 +rarity=C +[/card] +[card] +primitive=Regathan Firecat +id=370805 +rarity=C +[/card] +[card] +primitive=Ring of Three Wishes +id=370580 +rarity=M +[/card] +[card] +primitive=Rise of the Dark Realms +id=370636 +rarity=M +[/card] +[card] +primitive=Rod of Ruin +id=370668 +rarity=U +[/card] +[card] +primitive=Rootwalla +id=370693 +rarity=C +[/card] +[card] +primitive=Rumbling Baloth +id=370764 +rarity=C +[/card] +[card] +primitive=Sanguine Bond +id=370671 +rarity=R +[/card] +[card] +primitive=Savage Summoning +id=370710 +rarity=R +[/card] +[card] +primitive=Scavenging Ooze +id=370629 +rarity=R +[/card] +[card] +primitive=Scourge of Valkas +id=370584 +rarity=R +[/card] +[card] +primitive=Scroll Thief +id=370651 +rarity=C +[/card] +[card] +primitive=Seacoast Drake +id=370617 +rarity=C +[/card] +[card] +primitive=Seismic Stomp +id=370713 +rarity=C +[/card] +[card] +primitive=Sengir Vampire +id=370724 +rarity=U +[/card] +[card] +primitive=Sensory Deprivation +id=370780 +rarity=C +[/card] +[card] +primitive=Sentinel Sliver +id=370813 +rarity=C +[/card] +[card] +primitive=Seraph of the Sword +id=370620 +rarity=R +[/card] +[card] +primitive=Serra Angel +id=370602 +rarity=U +[/card] +[card] +primitive=Shadowborn Apostle +id=370746 +rarity=C +[/card] +[card] +primitive=Shadowborn Demon +id=370655 +rarity=M +[/card] +[card] +primitive=Shimmering Grotto +id=370631 +rarity=C +[/card] +[card] +primitive=Shivan Dragon +id=370825 +rarity=R +[/card] +[card] +primitive=Shiv's Embrace +id=370707 +rarity=U +[/card] +[card] +primitive=Shock +id=370654 +rarity=C +[/card] +[card] +primitive=Show of Valor +id=370779 +rarity=C +[/card] +[card] +primitive=Shrivel +id=370722 +rarity=C +[/card] +[card] +primitive=Siege Mastodon +id=370704 +rarity=C +[/card] +[card] +primitive=Silence +id=370578 +rarity=R +[/card] +[card] +primitive=Sliver Construct +id=370643 +rarity=C +[/card] +[card] +primitive=Smelt +id=370784 +rarity=C +[/card] +[card] +primitive=Solemn Offering +id=370730 +rarity=C +[/card] +[card] +primitive=Soulmender +id=370587 +rarity=C +[/card] +[card] +primitive=Spell Blast +id=370645 +rarity=U +[/card] +[card] +primitive=Sporemound +id=370605 +rarity=C +[/card] +[card] +primitive=Staff of the Death Magus +id=370586 +rarity=U +[/card] +[card] +primitive=Staff of the Flame Magus +id=370625 +rarity=U +[/card] +[card] +primitive=Staff of the Mind Magus +id=370676 +[/card] +[card] +primitive=Staff of the Wild Magus +id=370592 +rarity=U +[/card] +[card] +primitive=Staff of the Sun Magus +id=370635 +rarity=U +[/card] +[card] +primitive=Steelform Sliver +id=370597 +rarity=U +[/card] +[card] +primitive=Stonehorn Chanter +id=370777 +rarity=U +[/card] +[card] +primitive=Striking Sliver +id=370589 +rarity=C +[/card] +[card] +primitive=Strionic Resonator +id=370670 +rarity=R +[/card] +[card] +primitive=Suntail Hawk +id=370720 +rarity=C +[/card] +[card] +primitive=Swamp +id=370703 +rarity=C +[/card] +[card] +primitive=Swamp +id=370727 +rarity=C +[/card] +[card] +primitive=Swamp +id=370731 +rarity=C +[/card] +[card] +primitive=Swamp +id=370785 +rarity=C +[/card] +[card] +primitive=Syphon Sliver +id=370752 +rarity=R +[/card] +[card] +primitive=Tenacious Dead +id=370606 +rarity=U +[/card] +[card] +primitive=Thorncaster Sliver +id=370820 +rarity=R +[/card] +[card] +primitive=Thunder Strike +id=370607 +rarity=U +[/card] +[card] +primitive=Tidebinder Mage +id=370736 +rarity=R +[/card] +[card] +primitive=Time Ebb +id=370641 +rarity=R +[/card] +[card] +primitive=Tome Scour +id=370706 +rarity=C +[/card] +[card] +primitive=Trading Post +id=370646 +rarity=R +[/card] +[card] +primitive=Trained Condor +id=370692 +rarity=C +[/card] +[card] +primitive=Traumatize +id=370663 +rarity=R +[/card] +[card] +primitive=Trollhide +id=370664 +rarity=C +[/card] +[card] +primitive=Undead Minotaur +id=370702 +rarity=C +[/card] +[card] +primitive=Vampire Warlord +id=370709 +rarity=U +[/card] +[card] +primitive=Vastwood Hydra +id=370749 +rarity=R +[/card] +[card] +primitive=Verdant Haven +id=370657 +rarity=C +[/card] +[card] +primitive=Vial of Poison +id=370640 +rarity=U +[/card] +[card] +primitive=Vile Rebirth +id=370799 +rarity=C +[/card] +[card] +primitive=Volcanic Geyser +id=370614 +rarity=U +[/card] +[card] +primitive=Voracious Wurm +id=370814 +rarity=U +[/card] +[card] +primitive=Wall of Frost +id=370690 +rarity=U +[/card] +[card] +primitive=Wall of Swords +id=370697 +rarity=U +[/card] +[card] +primitive=Warden of Evos Isle +id=370815 +rarity=U +[/card] +[card] +primitive=Water Servant +id=370809 +rarity=U +[/card] +[card] +primitive=Wild Guess +id=370791 +rarity=C +[/card] +[card] +primitive=Wild Ricochet +id=370790 +rarity=R +[/card] +[card] +primitive=Windreader Sphinx +id=370810 +rarity=U +[/card] +[card] +primitive=Windstorm +id=370628 +rarity=U +[/card] +[card] +primitive=Witchstalker +id=370806 +rarity=R +[/card] +[card] +primitive=Woodborn Behemoth +id=370665 +rarity=U +[/card] +[card] +primitive=Wring Flesh +id=370759 +rarity=C +[/card] +[card] +primitive=Xathrid Necromancer +id=370619 +rarity=R +[/card] +[card] +primitive=Zombie Token +id=-339968 +rarity=T +[/card] +[card] +primitive=Young Pyromancer +id=370600 +rarity=U +[/card] +[card] +primitive=Zephyr Charge +id=370672 +rarity=C +[/card] diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 038e29d22..de89aceea 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -18104,6 +18104,13 @@ mana={3}{R} type=Enchantment [/card] [card] +name=Crucible of Worlds +auto=lord(land|mygraveyard) CanPlayFromGraveyard +text=You may play land cards from your graveyard. +mana={3} +type=Artifact +[/card] +[card] name=Crude Rampart abilities=defender facedown={3} @@ -28197,7 +28204,7 @@ subtype=Equipment [card] name=Executioner's Swing text=Target creature that dealt damage this turn gets -5/-5 until end of turn. -target=creature[damaged] +target=creature[damager] auto=-5/-5 ueot mana={W}{B} type=Instant @@ -31450,7 +31457,7 @@ toughness=2 [/card] [card] name=Flourishing Defenses -auto=@counteradded(-1/-1) from(creature|mybattlefield):may token(Elf Warrior,Creature elf warrior,1/1,green) +auto=@counteradded(-1/-1) from(creature):may token(Elf Warrior,Creature elf warrior,1/1,green) text=Whenever a -1/-1 counter is placed on a creature, you may put a 1/1 green Elf Warrior creature token onto the battlefield. mana={4}{G} type=Enchantment @@ -37159,7 +37166,7 @@ type=Sorcery [/card] [card] name=Grave Pact -auto=@movedTo(creature|mygraveyard) from(mybattlefield):ability$!name(sacrifice) notatarget(creature|mybattlefield) sacrifice!$ opponent +auto=@movedTo(creature|graveyard) from(mybattlefield):ability$!name(sacrifice) notatarget(creature|mybattlefield) sacrifice!$ opponent text=Whenever a creature you control dies, each other player sacrifices a creature. mana={1}{B}{B}{B} type=Enchantment @@ -73579,7 +73586,7 @@ toughness=6 ###The 2 cards below should stay together (Flip Card)### [card] name=Rune-Tail, Kitsune Ascendant -auto=this(controllerlife >30) all(this) flip(Rune-Tail's Essence) +auto=this(controllerlife > 29) transforms((,newability[flip(Rune-Tail's Essence)])) text=When you have 30 or more life, flip Rune-Tail, Kitsune Ascendant. mana={2}{W} type=Legendary Creature @@ -78437,11 +78444,7 @@ toughness=2 [/card] [card] name=Shifting Sky -auto=choice name(choose white) all(this) transforms((,newability[lord(*[-land]) becomes(,white)])) forever -auto=choice name(choose blue) all(this) transforms((,newability[lord(*[-land]) becomes(,blue)])) forever -auto=choice name(choose black) all(this) transforms((,newability[lord(*[-land]) becomes(,black)])) forever -auto=choice name(choose red) all(this) transforms((,newability[lord(*[-land]) becomes(,red)])) forever -auto=choice name(choose green) all(this) transforms((,newability[lord(*[-land]) becomes(,green)])) forever +auto=chooseacolor lord(*[-land]) becomes(,chosencolor) chooseend text=As Shifting Sky enters the battlefield, choose a color. -- All nonland permanents are the chosen color. mana={2}{U} type=Enchantment @@ -103468,6 +103471,15 @@ mana={1}{B} type=Enchantment [/card] [card] +name=Yawgmoth's Will +auto=lord(*|mygraveyard) canPlayFromGraveyard +auto=emblem transforms((,newability[@movedTo(*|mygraveyard):all(trigger[to]) moveTo(exile)])) ueot +auto=moveTo(exile) +text=Until end of turn, you may play cards from your graveyard. -- If a card would be put into your graveyard from anywhere this turn, exile that card instead. +mana={2}{B} +type=Sorcery +[/card] +[card] name=Yawning Fissure auto=ability$!name(sacrifice land) notatarget(land|mybattlefield) sacrifice!$ opponent text=Each opponent sacrifices a land. @@ -104286,4 +104298,4 @@ type=Land Creature subtype=Forest Dryad power=1 toughness=1 -[/card] \ No newline at end of file +[/card] diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index b3a4789af..6443d6a53 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -3187,19 +3187,6 @@ mana={2} type=Artifact [/card] [card] -name=Crucible of Worlds -auto={0}:may moveTo(myBattlefield) target(land|mygraveyard) limit:1 myTurnOnly -# Above line does not work: "May moveto" from graveyards does -# not work due to interface issues. The "limit:1" doesn't work -# here either. Even if both worked, then the card would allow -# you to play lands *in addition* to the 1 land you can play per -# turn. Instead it should just give you the option to play this -# 1 land from your hand or your graveyard. -text=You may play land cards from your graveyard. -mana={3} -type=Artifact -[/card] -[card] name=Cruel Deceiver text={1}: Look at the top card of your library. -- {2}: Reveal the top card of your library. If it's a land card, Cruel Deceiver gains "Whenever Cruel Deceiver deals damage to a creature, destroy that creature" until end of turn. Activate this ability only once each turn. mana={1}{B} diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index 7a5448816..8262bf086 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -249,6 +249,7 @@ curiosity2_i217.txt crimson_kobolds.txt crosis_s_catacombs_1.txt crosis_s_catacombs_2.txt +crucible_of_worlds.txt crumble.txt crystal_rod_i172.txt cursed_land1_i188.txt @@ -307,6 +308,9 @@ evil_presence3.txt evil_presence_i647.txt evil_presence_i647_2.txt exaltedsourcekilled.txt +executioners_swing.txt +executioners_swing2.txt +executioners_swing3.txt explore.txt Faceless_Butcher.txt fading.txt diff --git a/projects/mtg/bin/Res/test/crucible_of_worlds.txt b/projects/mtg/bin/Res/test/crucible_of_worlds.txt new file mode 100644 index 000000000..6ceb346a0 --- /dev/null +++ b/projects/mtg/bin/Res/test/crucible_of_worlds.txt @@ -0,0 +1,26 @@ +# Testing crucible of worlds (keyword: CANPLAYFROMGRAVEYARD) + +# name=Crucible of Worlds +# text=You may play land cards from your graveyard. + +[INIT] +FIRSTMAIN +[PLAYER1] +hand:island,plains +inplay:crucible of worlds +graveyard:forest,mountain +[PLAYER2] +[DO] +forest +# all next lands shouldn't be played +island +mountain +plains +[ASSERT] +FIRSTMAIN +[PLAYER1] +inplay:crucible of worlds,forest +hand:island,plains +graveyard:mountain +[PLAYER2] +[END] diff --git a/projects/mtg/bin/Res/test/executioners_swing.txt b/projects/mtg/bin/Res/test/executioners_swing.txt new file mode 100644 index 000000000..baabe2c48 --- /dev/null +++ b/projects/mtg/bin/Res/test/executioners_swing.txt @@ -0,0 +1,42 @@ +#NAME: Executioner's Swing +#DESC: Checks targetability +#DESC: Test that can target creature that damaged creature this turn + +[INIT] +combatattackers + +[PLAYER1] +inplay:Grizzly Bears + +[PLAYER2] +inplay:Flying Men,Swamp,Plains +hand:Executioner's Swing + +[DO] +Grizzly Bears +next +Flying Men +next +next +next + +# second main +# kill bear +yes +Swamp +Plains +Executioner's Swing +Grizzly Bears +endinterruption + +[ASSERT] +secondmain + +[PLAYER1] +graveyard:Grizzly Bears + +[PLAYER2] +graveyard:Executioner's Swing,Flying Men +inplay:Plains,Swamp + +[END] diff --git a/projects/mtg/bin/Res/test/executioners_swing2.txt b/projects/mtg/bin/Res/test/executioners_swing2.txt new file mode 100644 index 000000000..cb484e8d7 --- /dev/null +++ b/projects/mtg/bin/Res/test/executioners_swing2.txt @@ -0,0 +1,42 @@ +#NAME: Executioner's Swing +#DESC: Checks targetability +#DESC: Test that can target creature that damaged player + +[INIT] +combatattackers + +[PLAYER1] +inplay:Grizzly Bears + +[PLAYER2] +inplay:Swamp,Plains +hand:Executioner's Swing + +[DO] +Grizzly Bears +next +next +next +next + +# second main +# kill bear +yes +Swamp +Plains +Executioner's Swing +Grizzly Bears +endinterruption + +[ASSERT] +secondmain + +[PLAYER1] +graveyard:Grizzly Bears + +[PLAYER2] +graveyard:Executioner's Swing +inplay:Plains,Swamp +life:18 + +[END] diff --git a/projects/mtg/bin/Res/test/executioners_swing3.txt b/projects/mtg/bin/Res/test/executioners_swing3.txt new file mode 100644 index 000000000..433164fed --- /dev/null +++ b/projects/mtg/bin/Res/test/executioners_swing3.txt @@ -0,0 +1,34 @@ +#NAME: Executioner's Swing +#DESC: Checks targetability +#DESC: Prove that can't target passive creature + +[INIT] +secondmain + +[PLAYER1] +inplay:Grizzly Bears + +[PLAYER2] +manapool:{B}{W} +hand:Executioner's Swing + +[DO] +# attempt to kill bear +yes +Swamp +Plains +Executioner's Swing +Grizzly Bears +endinterruption + +[ASSERT] +secondmain + +[PLAYER1] +inplay:Grizzly Bears + +[PLAYER2] +hand:Executioner's Swing +manapool:{W}{B} + +[END] diff --git a/projects/mtg/build.xml b/projects/mtg/build.xml index ca8ae4e6a..81210aa41 100644 --- a/projects/mtg/build.xml +++ b/projects/mtg/build.xml @@ -2,7 +2,8 @@ - + + @@ -76,19 +77,22 @@ Author: Michael Nguyen #define WAGIC_VERSION_MAJOR ${build.major} #define WAGIC_VERSION_MEDIUM ${build.minor} #define WAGIC_VERSION_MINOR ${build.point} +#define WAGIC_VERSION_REVISION ${env.TRAVIS_BUILD_NUMBER} -#define VERSION_DOT(a, b, c) a ##.## b ##.## c +#define VERSION_DOT(a, b, c, d) a ##.## b ##.## c ##.## d #define VERSION_WITHOUT_DOT(a, b, c) a ## b ## c -#define VERSION_GAME(a, b, c) VERSION_DOT(a, b, c) +#define VERSION_GAME(a, b, c, d) VERSION_DOT(a, b, c, d) #define VERSION_FILE(a, b, c) VERSION_WITHOUT_DOT(a, b, c) #define VERSION_TOSTRING(a) #a #define VERSION_STRINGIFY(a) VERSION_TOSTRING(a) -#define WAGIC_VERSION VERSION_GAME(WAGIC_VERSION_MAJOR, WAGIC_VERSION_MEDIUM, WAGIC_VERSION_MINOR) +#define WAGIC_VERSION VERSION_GAME(WAGIC_VERSION_MAJOR, WAGIC_VERSION_MEDIUM, WAGIC_VERSION_MINOR, WAGIC_VERSION_REVISION) #define WAGIC_RESOURCE_VERSION VERSION_FILE(WAGIC_VERSION_MAJOR, WAGIC_VERSION_MEDIUM, WAGIC_VERSION_MINOR) #define WAGIC_VERSION_STRING VERSION_STRINGIFY(WAGIC_VERSION) #define WAGIC_CORE_VERSION_STRING "core_" VERSION_STRINGIFY(WAGIC_RESOURCE_VERSION) -#define WAGIC_RESOURCE_NAME WAGIC_CORE_VERSION_STRING ".zip" +#define WAGIC_RESOURCE_NAME "Wagic-core.zip" +#define WAGIC_RELEASE_NAME "${env.RELEASE_NAME}" +#define WAGIC_RESOURCE_URL "https://github.com/WagicProject/wagic/releases/download/" WAGIC_RELEASE_NAME "/" WAGIC_RESOURCE_NAME #endif diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index d947a3db4..35743fbb1 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -2524,13 +2524,13 @@ public: ALord(GameObserver* observer, int _id, MTGCardInstance * card, TargetChooser * _tc, int _includeSelf, MTGAbility * a) : ListMaintainerAbility(observer, _id, card), NestedAbility(a) - { - tc = _tc; - tc->targetter = NULL; - includeSelf = _includeSelf; - if(ability->aType == MTGAbility::STANDARD_PREVENT) - aType = MTGAbility::STANDARD_PREVENT; - } + { + tc = _tc; + tc->targetter = NULL; + includeSelf = _includeSelf; + if(ability->aType == MTGAbility::STANDARD_PREVENT) + aType = MTGAbility::STANDARD_PREVENT; + } //returns true if it is me who created ability a attached to Damageable d bool isParentOf(Damageable * d, MTGAbility * a) @@ -2608,7 +2608,8 @@ public: int removed(MTGCardInstance * card) { - if (abilities.find(card) != abilities.end() && !(forceDestroy == -1 && forcedAlive == 1))//only embelms have forcedestroy = -1 and forcedalive = 1 + if (abilities.find(card) != abilities.end() + && !(forceDestroy == -1 && forcedAlive == 1)) //only embelms have forcedestroy = -1 and forcedalive = 1 { game->removeObserver(abilities[card]); abilities.erase(card); diff --git a/projects/mtg/include/CardDescriptor.h b/projects/mtg/include/CardDescriptor.h index 704e3d55f..fbe58f4db 100644 --- a/projects/mtg/include/CardDescriptor.h +++ b/projects/mtg/include/CardDescriptor.h @@ -64,6 +64,7 @@ class CardDescriptor: public MTGCardInstance string compareName; int CDopponentDamaged; int CDcontrollerDamaged; + int CDdamager; }; #endif diff --git a/projects/mtg/include/CardGui.h b/projects/mtg/include/CardGui.h index 1ad7d18f1..1957a5505 100644 --- a/projects/mtg/include/CardGui.h +++ b/projects/mtg/include/CardGui.h @@ -33,7 +33,7 @@ protected: /* ** Tries to render the Big version of a card picture, backups to text version in case of failure */ - static void RenderBig(MTGCard * card, const Pos& pos); + static void RenderBig(MTGCard * card, const Pos& pos, bool thumb = false); static void RenderCountersBig(MTGCard * card, const Pos& pos, int drawMode = DrawMode::kNormal); static void AlternateRender(MTGCard * card, const Pos& pos); @@ -55,8 +55,8 @@ public: virtual void Render(); virtual void Update(float dt); - void DrawCard(const Pos& inPosition, int inMode = DrawMode::kNormal); - static void DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode = DrawMode::kNormal); + void DrawCard(const Pos& inPosition, int inMode = DrawMode::kNormal, bool thumb = false); + static void DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode = DrawMode::kNormal, bool thumb = false); static JQuadPtr AlternateThumbQuad(MTGCard * card); virtual ostream& toString(ostream&) const; diff --git a/projects/mtg/include/CarouselDeckView.h b/projects/mtg/include/CarouselDeckView.h new file mode 100644 index 000000000..7514ed62d --- /dev/null +++ b/projects/mtg/include/CarouselDeckView.h @@ -0,0 +1,45 @@ +#ifndef _CAROUSEL_DECK_VIEW_H_ +#define _CAROUSEL_DECK_VIEW_H_ + +#include "DeckView.h" +#include "Easing.h" + +class CarouselDeckView : public DeckView +{ +private: + static const float max_scale; + static const float x_center; + static const float right_border; + static const float slide_animation_duration; + static const float scroll_animation_duration; + +public: + CarouselDeckView(); + virtual ~CarouselDeckView(); + void Reset(); + + void UpdateViewState(float dt); + void UpdateCardPosition(int index); + void renderCard(int index) + { + int alpha = (int) (255 * (mCards[index].scale + 1.0 - max_scale)); + DeckView::renderCard(index, alpha); + } + + void Render(); + + bool ButtonPressed(Buttons button); + MTGCard * Click(int x, int y); + MTGCard * Click(); + + void changePositionAnimated(int offset); + void changeFilterAnimated(int offset); + + MTGCard *getActiveCard(); +private: + float mScrollOffset, mSlideOffset; + InOutQuadEasing mScrollEasing; + InOutQuadEasing mSlideEasing; +}; + +#endif //_CAROUSEL_DECK_VIEW_H_ diff --git a/projects/mtg/include/DeckView.h b/projects/mtg/include/DeckView.h new file mode 100644 index 000000000..7feec1226 --- /dev/null +++ b/projects/mtg/include/DeckView.h @@ -0,0 +1,241 @@ +#ifndef _DECK_VIEW_H_ +#define _DECK_VIEW_H_ + +#include + +#include "MTGCard.h" +#include "DeckDataWrapper.h" +#include "WFont.h" +#include "WResourceManager.h" +#include "Pos.h" + +/*! \brief A abstract base class for deck views + * + * The deck editor uses a deck view to present the cards + * e.g. in a circular "Carousel" layout or in a flat grid + * layout. Both layouts inherit this base class to ensure + * a common interface which the deck editor can rely on. + */ +class DeckView +{ +protected: + /*! \brief defines the delay until additional card informations get shown + * + * \note I am not entirely sure about that + */ + static const float no_user_activity_show_card_delay; + + /*! \brief Represents a card for internal use in the deck view + * + * It stores positional information and a pointer to the actual card structure. + */ + struct CardRep{ + float x; + float y; + float scale; + MTGCard * card; + }; +public: + /*! \brief Defines if the filter needs an update + * + * The owner of the deck that is shown is responsible for updating the filters. + */ + bool dirtyFilters; + + /*! \brief Defines if the card positions need an update + * + * If the card positions are dirty, UpdateCardPosition will get called on + * all cards during Update(float dt); + * + * \see Update + * \see UpdateCardPosition + */ + bool dirtyCardPos; + + /*! \brief Constructs the view and initializes datamembers + * + * It sets the dirty states to true, the currently shown deck to NULL and selects filter 0. + * + * \param numberOfCards the number of cards the view handles (this includes hidden cards for caching) + */ + DeckView(int numberOfCards); + + /*! \brief Does nothing but is needed to ensure proper deletion of derived classes. + */ + virtual ~DeckView(); + + /*! \brief Resets nearly all datamembers to their initial values + * + * Does not reset mCards. + */ + virtual void Reset(); + + /*! \brief Advances the view by dt time units + * + * This method calls UpdateViewState unconditionally and UpdateCardPosition on every card + * if dirtyCardPos is set. It then resets dirtyCardPos. + * + * \param dt the number of time units to advance + * \see UpdateViewState + * \see UpdateCardPosition + */ + void Update(float dt); + + /*! \brief Sets the deck that this view shows + * + * This method replaces the currently shown deck with toShow, sets all dirty states and + * reloads the mtg cards. No ownership changes. + * + * \param toShow the deck to show + * \see reloadIndexes + */ + void SetDeck(DeckDataWrapper *toShow); + + /*! \brief Returns a pointer to the current deck. + */ + DeckDataWrapper *deck(); + + /*! \brief Performs an immediate switch of the filter without animations + * + * This method rotates the currently selected filter by delta and sets dirtyFilters. + * + * \param delta the filter to select relatively to the currently selected filter + * \see dirtyFilters + */ + void changeFilter(int delta); + + /*! \brief Performs an immediate switch of the position without animations + * + * If the i-th card stored in mCards points to the j-th card in the deck, it will point + * to the (j+delta)-th card after this method is called. No dirty states are set. + * + * \param delta the number of cards to advances + * \see mCards + */ + void changePosition(int delta); + + /*! \brief Returns the number of the currently selected filter + * + * \return the currently selected filter + */ + int filter(); + + /*! \brief Reloads the mtg card pointers of mCards from the deck + * + * This is called when: We change the position in the deck or the deck structure changes + * (due to filtering or addition or removal of cards). + */ + void reloadIndexes(); + + /*! \brief Returns the current position in the deck + */ + int getPosition(); + + /*! \brief Renders the view + */ + virtual void Render() = 0; + + /*! \brief Reacts to selections by a pointer device (e. g. mouse, touch) + * + * If the selection in view internal i. e. a card got selected, there is + * no outside action performed and this method will return NULL. If a action got + * triggered i. e. a selected card was activated, it returns that card + * for further handling by the caller. + * + * \param x the x coordinate of the pointer during the action + * \param y the y coordinate of the pointer during the action + * \returns the card the action corresponds to + */ + virtual MTGCard * Click(int x, int y) = 0; + + /*! \brief Reacts to selections by pointerless devices (e. g. buttons) + * + * \see Click(int x, int y) + * \returns the card the actions corresponds to + */ + virtual MTGCard * Click() = 0; + + /*! \brief Handles ordinary button presses + * + * \param the pressed JButton + * \returns true if the view reacted to the button and false otherwise + */ + virtual bool ButtonPressed(Buttons button) = 0; + + /*! \brief Returns the currently active card + */ + virtual MTGCard *getActiveCard() = 0; + + /*! \brief Changes the position by a given offset + * + * Advances the view by offset cards and animates the change. + * + * \param offset the number of positions to advance + */ + virtual void changePositionAnimated(int offset) = 0; + + /*! \brief Changes the filter by a given offset + * + * Rotates the selected filter by the given offset and animates the change. + */ + virtual void changeFilterAnimated(int offset) = 0; +protected: + + /*! \brief The number of time units since an user activity occurred + */ + float last_user_activity; + + /*! \brief The currently selected filter + */ + int mFilter; + + /*! \brief The currently selected deck + * + * This class does not take ownership of the deck + */ + DeckDataWrapper *mCurrentDeck; + + /*! \brief The card positions and pointers + */ + vector mCards; + + /*! \brief Renders a card with given alpha value + * + * \param index of the card in mCards to render + * \param alpha the alpha value of the card + * \param asThumbnail renders the thumbnail image of the card if set to true + * + * \see mCards + */ + void renderCard(int index, int alpha, bool asThumbnail = false); + + /*! \brief Returns the index in mCards of the card that is nearest to the given point + * + * \note This method uses the euclidian distance to the center of the card + * + * \param x the reference points x coordinate + * \param y the reference points y coordinate + * \returns the index of the nearest card to the reference point and -1 of mCards is empty + */ + int getCardIndexNextTo(int x, int y); +private: + + /*! \brief Updates the state of the view e. g. view transitions + * + * \param dt the passes time since the last update + */ + virtual void UpdateViewState(float dt) = 0; + + /*! \brief Updates the given card reps positional members + * + * This method is called from Update when dirtyCardPos is set + * + * \param index the index in mCards of the card to update + * + * \see Update + * \see mCards + */ + virtual void UpdateCardPosition(int index) = 0; +}; + +#endif // _DECK_VIEW_H_ diff --git a/projects/mtg/include/Easing.h b/projects/mtg/include/Easing.h new file mode 100644 index 000000000..49d574026 --- /dev/null +++ b/projects/mtg/include/Easing.h @@ -0,0 +1,245 @@ +#ifndef _EASING_H_ +#define _EASING_H_ + +/*! \brief A class for eased floats for use in animations + * + * Animations often defines values a floating point variable + * should have at given times and interpolates between them to + * calculate the value of that variable at any given intermediate + * time step. + * + * The simplest case would be linear interpolation: + * Suppose a float "position" should be a at time = 0 and + * b at time = x. If the current time is y, the value of + * "position" is then a + (b-a)*y/x. + * + * This class defines the interface needed to implement different + * kind of interpolations with a common interface. See + * http://www.gizma.com/easing/ for more information for a few + * examples. + */ +class Easing +{ +public: + /*! \brief The value at the start of an animation. + * + * start_value is undefined if no animation is running. + */ + float start_value; + + /*! \brief The amount the value should change during the animation. + * + * delta_value is undefined if no animation is running. + */ + float delta_value; + + /*! \brief The current value. + * + * Use this member to read the value or to write the value without + * to animate intermediate values and. Make sure that the easing + * is not used once value is deleted. + */ + float& value; + + /*! \brief The duration the animation should take + * + * It is not relevant which unit is used. This value is undefined + * if no animation is running. + */ + float duration; + + /*! \brief The accumulated time the animation did run until now. + * + * It is not relevant which unit is used. This values is undefined + * if no animation is running. + */ + float time_acc; + + /*! \brief Sets Easing::float to val and sets the animation as not running. + * + * Make sure that the easing is not used once value is deleted. + * + * \param val The value to ease + */ + Easing(float& val): start_value(val), delta_value(0), value(val), duration(0), time_acc(0) + { + } + + /*! \brief Resets the animation to its initial value + * + * This method does set the value to the start value and sets the passed time to 0. + * If there is no animation animation running, the resulting value is undefined. + */ + void reset() + { + value = start_value; + time_acc = 0; + } + + /*! \brief Finishes the animation immediately + * + * Sets the value to the animations target value and the passed time to the + * animations duration. If there is no animation running, the behaviour is undefined. + */ + void finish() + { + value = start_value + delta_value; + time_acc = duration; + } + + /*! \brief Lets dt time pass + * + * Advances the animation by dt time units and updates the value accordingly. + * + * \val dt The amount of time to jump forward + */ + void update(float dt) + { + if(time_acc < duration) + { + time_acc += dt; + + if(time_acc > duration) + { + time_acc = duration; + value = start_value + delta_value; + } + else + { + updateValue(); + } + } + } + + /*! \brief Calculates the value from all other members. + * + * This method gets implemented by all specific easing classes. + */ + virtual void updateValue() = 0; + + /*! \brief Starts the animation. + * + * Starts the interpolation from the current value (now) to + * targetValue (in now + _duration). + * + * If the animation is currently running, it gets replaced. + * + * \param targetValue The value to interpolate to + * \param _duration The duration the interpolation should take + */ + void start(float targetValue, float _duration) + { + start_value = value; + delta_value = targetValue - start_value; + time_acc = 0; + duration = _duration; + } + + /*! \brief Translates the current value and the target value by delta_value + * + * This method is mainly used for trickery. Suppose there is one object in the + * middle of the screen that should move to the top until it is outside of the + * screen and gets replaced by a second one entering the screen from the lower + * side once the first one disappeared. This method can be used to simulate this + * effect with one animation by translating (i.e. moving) the animation from the + * top to the bottom: + * + * Object1 and object2 are the same object: object1 whose y position is bound to value + * To start the transition, use start(SCREEN_HEIGHT, desired time); Once the first + * object left the screen (i.e. object.y < 0), change objects appearance to object2 + * and translate the easing by (SCREEN_HEIGHT). + * + * \param delta_value The change in start_value and value + */ + void translate(float delta_value) + { + start_value += delta_value; + value += delta_value; + } + + /*! \brief Returns if the passed time exceeds duration. + * + * If ther is no animation running, it is ensured that this is true. + */ + bool finished() + { + return time_acc >= duration; + } +}; + +/*! \brief This class defines an easing with quadratic acceleration + */ +class InQuadEasing : public Easing +{ +public: + /*! \brief Calls Easing::Easing(val). + * + * \see Easing::Easing(float& val) + */ + InQuadEasing(float& val): Easing(val) {} + + /*! \brief Implements the value calculation. + * + * \see Easing::updateValue() + */ + void updateValue() + { + float time_tmp = time_acc / duration; + value = delta_value * time_tmp * time_tmp + start_value; + } +}; + +/*! \brief This class defines an easing with quadratic decceleration + */ +class OutQuadEasing : public Easing +{ +public: + /*! \brief Calls Easing::Easing(val). + * + * \see Easing::Easing(float& val) + */ + OutQuadEasing(float& val): Easing(val) {} + + /*! \brief Implements the value calculation. + * + * \see Easing::updateValue() + */ + void updateValue() + { + float time_tmp = time_acc / duration; + value = (-delta_value) * time_tmp * (time_tmp - 2.0f) + start_value; + } +}; + +/*! \brief This class defines an easing with quadratic acceleration and decceleration. + */ +class InOutQuadEasing : public Easing +{ +public: + /*! \brief Calls Easing::Easing(val). + * + * \see Easing::Easing(float& val) + */ + InOutQuadEasing(float& val): Easing(val) {} + + /*! \brief Implements the value calculation. + * + * \see Easing::updateValue() + */ + void updateValue() + { + float time_tmp = (time_acc * 2) / duration; + if (time_tmp < 1) + { + value = (float)(delta_value * 0.5 * time_tmp * time_tmp + start_value); + } + else + { + time_tmp -= 1; + value = (float)(- delta_value * 0.5 * (time_tmp * (time_tmp - 2) - 1) + start_value); + } + } +}; + + +#endif //_EASING_H_ diff --git a/projects/mtg/include/GameStateAwards.h b/projects/mtg/include/GameStateAwards.h index cb614895c..64cc741a6 100644 --- a/projects/mtg/include/GameStateAwards.h +++ b/projects/mtg/include/GameStateAwards.h @@ -17,7 +17,6 @@ private: WSrcCards * setSrc; SimpleMenu * menu; bool showMenu; - bool showAlt; bool saveMe; int mState; int mDetailItem; diff --git a/projects/mtg/include/GameStateDeckViewer.h b/projects/mtg/include/GameStateDeckViewer.h index 426bb7226..50da6b4b3 100644 --- a/projects/mtg/include/GameStateDeckViewer.h +++ b/projects/mtg/include/GameStateDeckViewer.h @@ -19,22 +19,7 @@ #include "WGui.h" #include "InteractiveButton.h" -#define NO_USER_ACTIVITY_HELP_DELAY 10 -#define NO_USER_ACTIVITY_SHOWCARD_DELAY 0.1 - -enum -{ - STAGE_TRANSITION_RIGHT = 0, - STAGE_TRANSITION_LEFT = 1, - STAGE_WAITING = 2, - STAGE_TRANSITION_UP = 3, - STAGE_TRANSITION_DOWN = 4, - STAGE_ONSCREEN_MENU = 5, - STAGE_WELCOME = 6, - STAGE_MENU = 7, - STAGE_FILTERS = 8, - STAGE_TRANSITION_SELECTED = 9 -}; +class DeckView; // TODO: need a better name for MENU_FIRST_MENU, this is reused for the 1st submenu of // available options in the duel menu @@ -44,7 +29,7 @@ enum MENU_DECK_SELECTION = 10, MENU_DECK_BUILDER = 11, MENU_FIRST_DUEL_SUBMENU = 102, - MENU_LANGUAGE_SELECTION = 103, + MENU_LANGUAGE_SELECTION = 103 }; // enums for menu options @@ -64,79 +49,69 @@ enum DECK_VIEWER_MENU_ITEMS MENU_ITEM_NO = 21, MENU_ITEM_FILTER_BY = 22, MENUITEM_MORE_INFO = kInfoMenuID - }; -#define ALL_COLORS -1 - -#define ROTATE_LEFT 1; -#define ROTATE_RIGHT 0; - -#define HIGH_SPEED 15.0 -#define MED_SPEED 5.0f -#define LOW_SPEED 1.5 - -#define MAX_SAVED_FILTERS Constants::NB_Colors + 1 -#define CARDS_DISPLAYED 10 - class GameStateDeckViewer: public GameState, public JGuiListener { private: + enum DeckViewerStages + { + STAGE_WAITING = 0, + STAGE_ONSCREEN_MENU, + STAGE_WELCOME, + STAGE_MENU, + STAGE_FILTERS + }; + vector mIcons; JQuadPtr pspIcons[8]; JTexture * pspIconsTexture; float last_user_activity; float onScreenTransition; - float mRotation; - float mSlide; - int mAlpha; - int mStage; - int useFilter; + DeckViewerStages mStage; JMusic * bgMusic; - int lastPos; - int lastTotal; - int mSelected; - InteractiveButton *toggleDeckButton, *sellCardButton, *statsPrevButton, *filterButton; + InteractiveButton *toggleDeckButton, *sellCardButton, *statsPrevButton, *filterButton, *toggleViewButton; WGuiFilters * filterMenu; WSrcDeckViewer * source; DeckEditorMenu * welcome_menu; SimpleMenu * subMenu; - DeckEditorMenu * menu; + DeckEditorMenu * deckMenu; PriceList* pricelist; PlayerData * playerdata; - int price; - DeckDataWrapper * displayed_deck; DeckDataWrapper * myDeck; DeckDataWrapper * myCollection; - MTGCard * cardIndex[CARDS_DISPLAYED]; - StatsWrapper *stw; + StatsWrapper * mStatsWrapper; int hudAlpha; string newDeckname; bool isAIDeckSave; bool mSwitching; + + enum AvailableView{ + CAROUSEL_VIEW, + GRID_VIEW + }; + DeckView* mView; + AvailableView mCurrentView; + void saveDeck(); //Saves the deck and additional necessary information void saveAsAIDeck(string deckName); // saves deck as an AI Deck - int getCurrentPos(); void sellCard(); void setButtonState(bool state); bool userPressedButton(); void RenderButtons(); - - pair cardsCoordinates[CARDS_DISPLAYED]; - + void setupView(AvailableView view, DeckDataWrapper *deck); + void toggleView(); public: GameStateDeckViewer(GameApp* parent); virtual ~GameStateDeckViewer(); void updateDecks(); - void rotateCards(int direction); - void loadIndexes(); void updateFilters(); void rebuildFilters(); - void switchDisplay(); + void toggleCollection(); void Start(); virtual void End(); void addRemove(MTGCard * card); @@ -145,11 +120,8 @@ public: void renderSlideBar(); void renderDeckBackground(); void renderOnScreenMenu(); - virtual void renderCard(int id, float rotation); - virtual void renderCard(int id); virtual void Render(); int loadDeck(int deckid); - void LoadDeckStatistics(int deckId); void OnScroll(int inXVelocity, int inYVelocity); diff --git a/projects/mtg/include/GameStateShop.h b/projects/mtg/include/GameStateShop.h index 1de196b5f..f6765ab74 100644 --- a/projects/mtg/include/GameStateShop.h +++ b/projects/mtg/include/GameStateShop.h @@ -65,7 +65,6 @@ private: JQuadPtr pspIcons[8]; WSrcCards * srcCards; TaskList * taskList; - float mElapsed; WGuiMenu * shopMenu; WGuiFilters * filterMenu; //Filter menu slides in sideways from right, or up from bottom. WGuiCardImage * bigDisplay; diff --git a/projects/mtg/include/GridDeckView.h b/projects/mtg/include/GridDeckView.h new file mode 100644 index 000000000..0c164f1f1 --- /dev/null +++ b/projects/mtg/include/GridDeckView.h @@ -0,0 +1,154 @@ +#ifndef _GRID_DECK_VIEW_H +#define _GRID_DECK_VIEW_H + +#include "DeckView.h" +#include "Easing.h" + +/*! \brief Implements a grid view + * + * This view displays 12 cards in two rows as thumbnails. The currently + * selected card is dislayed bigger than the rest and uses the fullsize + * image. Scrolling the view horizontally and toggeling filters is + * animated and uses quadratic easing. + * + * It also implements a button mode for pointerless devices. + */ +class GridDeckView : public DeckView +{ +private: + static const float scroll_animation_duration; + static const float slide_animation_duration; + static const float card_scale_small; + static const float card_scale_big; +public: + /*! \brief Constructs a grid view with no decks set + */ + GridDeckView(); + + /*! \brief Does nothing but is needed to ensure proper deletion of derived classes. + */ + virtual ~GridDeckView(); + + /*! \brief Resets almost all member variables but mRows and mCols + */ + void Reset(); + + /*! \brief Advances scrolling and sliding animations + * + * \param dt the time since the last update + * + * \see DeckView::UpdateViewState() + */ + void UpdateViewState(float dt); + + /*! \brief Updates the cards position + * + * \see DeckView::UpdateCardPosition() + */ + void UpdateCardPosition(int index); + + /*! \brief Renders the view + * + * This method prefetches all rendered cards as thumbnails except the + * selected card to reduce cache pressure. + */ + void Render(); + + /*! \brief Handles button presses + * + * The mapping is as follows: + * JGE_BTN_LEFT moves the position to the left if not in button mode + * moves the selection otherwise + * JGE_BTN_RIGHT move the position to the right if not in button mode + * moves the selection otherwise + * JGE_BTN_UP select the previous filter if not in button mode + * moves the selection otherwise + * JGE_BTN_DOWN select the next filter if not in button mode + * moves the selection otherwise + * JGE_BTN_CTRL deactivate button mode + * + * \param button the pressed button + * \returns if the view handled the button + */ + bool ButtonPressed(Buttons button); + + /*! \brief Handles clicks and triggers scrolling and the selection of cards + * + * This method deactivates the button mode and searches for the nearest + * card to the given position. If this card is in column 0 or 1 it scrolls + * left. If it is in column (mCols-1) or (mCols-2) it scrolls to the right. + * In any other case, it selects the card. + * + * \param x the clicks x coordinate + * \param y the clicks y coordinate + * + * \return selected card c if c was already selected and no animation is running, NULL otherwise + */ + MTGCard * Click(int x, int y); + + /*! \brief Handles pointerless clicks (JGE_BTN_OK) + * + * If no card is selected, this method activates button mode and selects a card. + * + * \returns selected card, NULL otherwise + */ + MTGCard * Click(); + + /*! \brief Scrolls the view horizontally + * + * \param offset the number of columns to scroll + */ + void changePositionAnimated(int offset); + + /*! \brief Rotates the selected filter and slides vertically + * + * \param the number of filters to rotate + */ + void changeFilterAnimated(int offset); + + /*! \brief Returns the currently selected card + * + * \returns card c if c is selected and in column 4 to 6 and NULL otherwise*/ + MTGCard *getActiveCard(); +private: + /*! \brief The amount of columns (visible and hidden) + */ + const int mCols; + + /*! \brief The amount of rows + */ + const int mRows; + + /*! \brief The current scrolling offset + */ + float mScrollOffset; + + /*! \brief The current sliding offset + */ + float mSlideOffset; + + /*! \brief The easing functor that gets applied while scrolling + */ + InOutQuadEasing mScrollEasing; + + /*! \brief The easing functor that gets applied while sliding + */ + InOutQuadEasing mSlideEasing; + + /*! \brief The current selected card index + */ + int mCurrentSelection; + + /*! \brief Stores if we are in button mode. + */ + bool mButtonMode; + + /*! \brief Moves the card selection by an offset. + * + * \param offset the offset to move the selection + * \param alignIfOutOfBounds the view will scroll if the selection moves out of bound if set to true + */ + void moveSelection(int offset, bool alignIfOutOfBounds); +}; + +#endif //_GRID_DECK_VIEW_H diff --git a/projects/mtg/include/GuiMana.h b/projects/mtg/include/GuiMana.h index d18655bc9..de9f68641 100644 --- a/projects/mtg/include/GuiMana.h +++ b/projects/mtg/include/GuiMana.h @@ -6,8 +6,9 @@ #include #include "JGE.h" #include "MTGDefinitions.h" -#include "GameApp.h" +#include "Pos.h" #include "GuiLayers.h" +#include "WResource_Fwd.h" class ManaIcon : public Pos { diff --git a/projects/mtg/include/GuiPhaseBar.h b/projects/mtg/include/GuiPhaseBar.h index 49dafac6e..78cec2677 100644 --- a/projects/mtg/include/GuiPhaseBar.h +++ b/projects/mtg/include/GuiPhaseBar.h @@ -4,15 +4,25 @@ #include "GuiLayers.h" #include "PhaseRing.h" #include "WEvent.h" +#include "PlayGuiObject.h" + +#include "Easing.h" class GuiPhaseBar: public GuiLayer, public PlayGuiObject { -protected: - Phase* phase; +private: + static const float zoom_big; + static const float zoom_small; + static const float step; + + int displayedPhaseId; float angle; float zoomFactor; - DuelLayers* mpDuelLayers; + OutQuadEasing angleEasing; + InOutQuadEasing zoomFactorEasing; + DuelLayers* mpDuelLayers; + void DrawGlyph(JQuad *inQuad, int phaseId, float x, float y, float scale); public: GuiPhaseBar(DuelLayers* duelLayers); ~GuiPhaseBar(); diff --git a/projects/mtg/include/GuiPlay.h b/projects/mtg/include/GuiPlay.h index 4eadc959a..c900b30ba 100644 --- a/projects/mtg/include/GuiPlay.h +++ b/projects/mtg/include/GuiPlay.h @@ -47,7 +47,6 @@ protected: { static const float HEIGHT; unsigned attackers; - unsigned blockers; unsigned currentAttacker; float height; diff --git a/projects/mtg/include/InteractiveButton.h b/projects/mtg/include/InteractiveButton.h index 3a7f52aca..d15e768bc 100644 --- a/projects/mtg/include/InteractiveButton.h +++ b/projects/mtg/include/InteractiveButton.h @@ -28,6 +28,7 @@ const int kNextStatsButtonId = 10005; const int kPrevStatsButtonId = 10006; const int kCycleCardsButtonId = 10007; const int kShowCardListButtonId = 10008; +const int kSwitchViewButton = 10009; class InteractiveButton: public SimpleButton { diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index ab708e5db..82053bcf1 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -65,6 +65,7 @@ public: bool wasDealtDamage; bool damageToOpponent; bool damageToController; + bool damageToCreature; bool mPropertiesChangedSinceLastUpdate; int reduxamount; int flanked; diff --git a/projects/mtg/include/MTGDeck.h b/projects/mtg/include/MTGDeck.h index c17e83189..fcba1b192 100644 --- a/projects/mtg/include/MTGDeck.h +++ b/projects/mtg/include/MTGDeck.h @@ -4,7 +4,6 @@ #define MTG_ERROR -1 #include "MTGDefinitions.h" -#include "GameApp.h" #include "WResourceManager.h" #include #include diff --git a/projects/mtg/include/MTGDefinitions.h b/projects/mtg/include/MTGDefinitions.h index 86d11e14d..08667058e 100644 --- a/projects/mtg/include/MTGDefinitions.h +++ b/projects/mtg/include/MTGDefinitions.h @@ -218,7 +218,8 @@ class Constants soulbond = 100, LURE = 101, NOLEGEND = 102, - NB_BASIC_ABILITIES = 103, + CANPLAYFROMGRAVEYARD = 103, + NB_BASIC_ABILITIES = 104, RARITY_S = 'S', //Special Rarity diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index b524e42e2..5a5fbf2cb 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -66,6 +66,7 @@ public: MTGEventBonus(GameObserver* observer, int _id); virtual MTGEventBonus * clone() const; }; + class MTGPutInPlayRule: public PermanentAbility { public: @@ -172,6 +173,21 @@ public: virtual MTGMorphCostRule * clone() const; }; +class MTGPlayFromGraveyardRule: public MTGAlternativeCostRule +{ +public: + int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); + int reactToClick(MTGCardInstance * card); + virtual ostream& toString(ostream& out) const; + MTGPlayFromGraveyardRule(GameObserver* observer, int _id); + const string getMenuText() + { + return "cast card from graveyard"; + } + virtual MTGPlayFromGraveyardRule * clone() const; +}; + + class MTGSuspendRule: public MTGAlternativeCostRule { public: diff --git a/projects/mtg/include/ObjectAnalytics.h b/projects/mtg/include/ObjectAnalytics.h index db610a54c..43306f801 100644 --- a/projects/mtg/include/ObjectAnalytics.h +++ b/projects/mtg/include/ObjectAnalytics.h @@ -1,6 +1,8 @@ #ifndef OBJECTANALYTICS_H #define OBJECTANALYTICS_H +#include + #ifdef _DEBUG #define TRACK_OBJECT_USAGE #endif diff --git a/projects/mtg/include/OptionItem.h b/projects/mtg/include/OptionItem.h index 7664e82d8..998d9cb67 100644 --- a/projects/mtg/include/OptionItem.h +++ b/projects/mtg/include/OptionItem.h @@ -7,7 +7,6 @@ #include #include #include -#include "GameApp.h" #include "GameStateOptions.h" #include "WFilter.h" #include "WDataSrc.h" diff --git a/projects/mtg/include/PriceList.h b/projects/mtg/include/PriceList.h index 7af69b5e4..f08281e88 100644 --- a/projects/mtg/include/PriceList.h +++ b/projects/mtg/include/PriceList.h @@ -20,16 +20,18 @@ public: ~PriceList(); int save(); int getSellPrice(int cardid); + int getSellPrice(MTGCard* card); int getPurchasePrice(int cardid); + int getPrice(MTGCard *card); int getPrice(int cardId); int setPrice(int cardId, int price); + int setPrice(MTGCard *card, int price); int getOtherPrice(int amt); static float difficultyScalar(float price, int cardid = 0); static void updateKey() { randomKey = rand(); } - ; }; #endif diff --git a/projects/mtg/include/SimplePopup.h b/projects/mtg/include/SimplePopup.h index 154710e92..d61d7cc47 100644 --- a/projects/mtg/include/SimplePopup.h +++ b/projects/mtg/include/SimplePopup.h @@ -20,7 +20,6 @@ class SimplePopup: public JGuiController private: float mWidth, mX, mY; int mMaxLines; - int mFontId; DeckMetaData * mDeckInformation; string mTitle; WFont *mTextFont; diff --git a/projects/mtg/include/Tasks.h b/projects/mtg/include/Tasks.h index 2eb8b7340..2d96430db 100644 --- a/projects/mtg/include/Tasks.h +++ b/projects/mtg/include/Tasks.h @@ -2,6 +2,15 @@ #define TASK_H #include +#include + +#include "Easing.h" + +using namespace std; + +class GameObserver; +class JQuad; +class JTexture; // Task type constant @@ -70,8 +79,11 @@ class TaskList { protected: string fileName; + float vPos; - float mElapsed; + OutQuadEasing vPosInEasing; + InQuadEasing vPosOutEasing; + int mState; JQuad * mBg[9]; JTexture * mBgTex; @@ -95,7 +107,6 @@ public: { return mState; } - ; void addTask(string params, bool rand = false); void addTask(Task *task); void addRandomTask(int diff = 100); diff --git a/projects/mtg/include/WFilter.h b/projects/mtg/include/WFilter.h index 2ec34538a..16d30c59d 100644 --- a/projects/mtg/include/WFilter.h +++ b/projects/mtg/include/WFilter.h @@ -1,3 +1,5 @@ +#include "MTGDeck.h" + #ifndef _WFILTER_H_ #define _WFILTER_H_ /** diff --git a/projects/mtg/include/WGui.h b/projects/mtg/include/WGui.h index 60dab9a7b..008d29658 100644 --- a/projects/mtg/include/WGui.h +++ b/projects/mtg/include/WGui.h @@ -8,6 +8,7 @@ class hgeDistortionMesh; class GameStateOptions; +class SimpleMenu; /** @defgroup WGui Basic Gui diff --git a/projects/mtg/include/WResource_Fwd.h b/projects/mtg/include/WResource_Fwd.h index 139c08e01..c03b0b752 100644 --- a/projects/mtg/include/WResource_Fwd.h +++ b/projects/mtg/include/WResource_Fwd.h @@ -1,12 +1,12 @@ #ifndef WRESOURCE_FWD_H #define WRESOURCE_FWD_H -#ifndef WP8 -#include -typedef boost::shared_ptr JQuadPtr; -#else +#if (__cplusplus > 199711L) #include typedef std::shared_ptr JQuadPtr; +#else +#include +typedef boost::shared_ptr JQuadPtr; #endif #endif diff --git a/projects/mtg/include/config.h b/projects/mtg/include/config.h index ada8c7add..55dcb0e91 100644 --- a/projects/mtg/include/config.h +++ b/projects/mtg/include/config.h @@ -1,7 +1,7 @@ #ifndef _DEBUG_H_ #define _DEBUG_H_ -#if ((defined WIN32) || (defined WP8)) +#if ((defined WIN32) || (defined WP8)) && !defined(__MINGW32__) #define snprintf sprintf_s #endif diff --git a/projects/mtg/include/utils.h b/projects/mtg/include/utils.h index 3a3461b40..25a4c392d 100644 --- a/projects/mtg/include/utils.h +++ b/projects/mtg/include/utils.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "DebugRoutines.h" diff --git a/projects/mtg/src/AIHints.cpp b/projects/mtg/src/AIHints.cpp index 8280b211b..7c7eff197 100644 --- a/projects/mtg/src/AIHints.cpp +++ b/projects/mtg/src/AIHints.cpp @@ -316,7 +316,7 @@ bool AIHints::canWeCombo(GameObserver* observer,MTGCardInstance * card,AIPlayerB int comboPartsRestriction = 0; if(gotCombo) - return gotCombo;//because more then one might be possible at any time. + return gotCombo;//because more than one might be possible at any time. if (hints[i]->hold.size()) { for(unsigned int hPart = 0; hPart < hints[i]->hold.size(); hPart++) diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index d71bc98d5..12ab3b948 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -446,7 +446,7 @@ int OrderedAIAction::getEfficiency() } if ((drawer->getNumCards() >= p->game->library->nb_cards && (Targetable*)p == drawer->getTarget()) || (p->game->hand->nb_cards > 10 && (Targetable*)p == drawer->getTarget())) { - //if the amount im drawing will mill me to death or i have more then 10 cards in hand, eff is 0; + //if the amount im drawing will mill me to death or i have more than 10 cards in hand, eff is 0; efficiency = 0; } break; @@ -854,7 +854,7 @@ ManaCost * AIPlayerBaka::getPotentialMana(MTGCardInstance * target) if (card == target) used[card] = true; //http://code.google.com/p/wagic/issues/detail?id=76 if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost() == 1) - {//ai can't use cards which produce more then 1 converted while using the old pMana method. + {//ai can't use cards which produce more than 1 converted while using the old pMana method. result->add(amp->output); used[card] = true; } diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index feaccb371..26cd01faa 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -1994,28 +1994,23 @@ int AADynamic::resolve() break; case DYNAMIC_ABILITY_WHO_ITSELF: source = ((MTGCardInstance *) _target); - _target = _target; break; case DYNAMIC_ABILITY_WHO_TARGETCONTROLLER: - _target = _target; secondaryTarget = ((MTGCardInstance *) _target)->controller(); break; case DYNAMIC_ABILITY_WHO_TARGETOPPONENT: - _target = _target; secondaryTarget = ((MTGCardInstance *) _target)->controller()->opponent(); break; case DYNAMIC_ABILITY_WHO_TOSOURCE: tosrc = true; break; case DYNAMIC_ABILITY_WHO_SOURCECONTROLLER: - _target = _target; secondaryTarget = ((MTGCardInstance *) OriginalSrc)->controller(); break; case DYNAMIC_ABILITY_WHO_SOURCEOPPONENT: secondaryTarget = OriginalSrc->controller()->opponent(); break; default: - _target = _target; break; } if(amountsource == DYNAMIC_MYSELF_AMOUNT) @@ -4728,14 +4723,15 @@ void AVanishing::Update(float dt) int AVanishing::resolve() { - return 1; } const string AVanishing::getMenuText() { -if(counterName.find("fade") != string::npos) -return "Fading"; + if (counterName.find("fade") != string::npos) + { + return "Fading"; + } return "Vanishing"; } @@ -5419,83 +5415,83 @@ AACastCard::AACastCard(GameObserver* observer, int _id, MTGCardInstance * _sourc } - void AACastCard::Update(float dt) +void AACastCard::Update(float dt) +{ + MTGAbility::Update(dt); + if (processed) + return; + if(cardNamed.size() && !theNamedCard) + { + theNamedCard = makeCard(); + } + if (restricted) { - MTGAbility::Update(dt); - if (processed) - return; - if(cardNamed.size() && !theNamedCard) - { - theNamedCard = makeCard(); - } - if (restricted) - { - MTGCardInstance * toCheck = (MTGCardInstance*)target; - if(theNamedCard) - toCheck = theNamedCard; - if (game->currentActionPlayer->game->playRestrictions->canPutIntoZone(toCheck, source->controller()->game->stack) == PlayRestriction::CANT_PLAY) - { - processed = true; - this->forceDestroy = 1; - return ; - } - if(!allowedToCast(toCheck,source->controller())) - { - processed = true; - this->forceDestroy = 1; - return; - } - if(!toCheck->hasType(Subtypes::TYPE_INSTANT) && !(game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN || game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN)) - { - processed = true; - this->forceDestroy = 1; - return; - } - } MTGCardInstance * toCheck = (MTGCardInstance*)target; if(theNamedCard) toCheck = theNamedCard; - if (Spell * checkSpell = dynamic_cast(target)) + if (game->currentActionPlayer->game->playRestrictions->canPutIntoZone(toCheck, source->controller()->game->stack) == PlayRestriction::CANT_PLAY) { - toCheck = checkSpell->source; + processed = true; + this->forceDestroy = 1; + return ; } - if (!game->targetListIsSet(toCheck)) + if(!allowedToCast(toCheck,source->controller())) { - if(game->targetChooser) - game->targetChooser->Owner = source->controller();//sources controller is the caster + processed = true; + this->forceDestroy = 1; return; } - resolveSpell(); - this->forceDestroy = 1; + if(!toCheck->hasType(Subtypes::TYPE_INSTANT) && !(game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN || game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN)) + { + processed = true; + this->forceDestroy = 1; + return; + } + } + MTGCardInstance * toCheck = (MTGCardInstance*)target; + if(theNamedCard) + toCheck = theNamedCard; + if (Spell * checkSpell = dynamic_cast(target)) + { + toCheck = checkSpell->source; + } + if (!game->targetListIsSet(toCheck)) + { + if(game->targetChooser) + game->targetChooser->Owner = source->controller();//sources controller is the caster return; } - int AACastCard::isReactingToTargetClick(Targetable * card){return 0;} - int AACastCard::reactToTargetClick(Targetable * object) - { - if (MTGCardInstance * cObject = dynamic_cast(object)) - return reactToClick(cObject); + resolveSpell(); + this->forceDestroy = 1; + return; +} +int AACastCard::isReactingToTargetClick(Targetable * card){return 0;} +int AACastCard::reactToTargetClick(Targetable * object) +{ + if (MTGCardInstance * cObject = dynamic_cast(object)) + return reactToClick(cObject); - if (waitingForAnswer) + if (waitingForAnswer) + { + if (tc->toggleTarget(object) == TARGET_OK_FULL) { - if (tc->toggleTarget(object) == TARGET_OK_FULL) - { - waitingForAnswer = 0; - game->mLayers->actionLayer()->setCurrentWaitingAction(NULL); - return MTGAbility::reactToClick(source); - } - return 1; + waitingForAnswer = 0; + game->mLayers->actionLayer()->setCurrentWaitingAction(NULL); + return MTGAbility::reactToClick(source); } - return 0; + return 1; } + return 0; +} - MTGCardInstance * AACastCard::makeCard() - { - MTGCardInstance * card = NULL; - MTGCard * cardData = MTGCollection()->getCardByName(cardNamed); - card = NEW MTGCardInstance(cardData, source->controller()->game); - source->controller()->game->temp->addCard(card); - return card; - } +MTGCardInstance * AACastCard::makeCard() +{ + MTGCardInstance * card = NULL; + MTGCard * cardData = MTGCollection()->getCardByName(cardNamed); + card = NEW MTGCardInstance(cardData, source->controller()->game); + source->controller()->game->temp->addCard(card); + return card; +} int AACastCard::resolveSpell() { @@ -5708,7 +5704,8 @@ void ATutorialMessage::Update(float dt) mElapsed += dt; - IconButtonsController::Update(dt); + if(!mUserCloseRequest) + IconButtonsController::Update(dt); if (mIsImage) return; diff --git a/projects/mtg/src/CardDescriptor.cpp b/projects/mtg/src/CardDescriptor.cpp index f304e356d..c6ae1e7a7 100644 --- a/projects/mtg/src/CardDescriptor.cpp +++ b/projects/mtg/src/CardDescriptor.cpp @@ -23,6 +23,7 @@ CardDescriptor::CardDescriptor() colorComparisonMode = COMPARISON_NONE; CDopponentDamaged = 0; CDcontrollerDamaged = 0; + CDdamager = 0; } int CardDescriptor::init() @@ -226,16 +227,27 @@ MTGCardInstance * CardDescriptor::match(MTGCardInstance * card) { match = NULL; } - if(CDopponentDamaged == -1 || CDopponentDamaged == 1) - { - Player * p = card->controller()->opponent();//controller()->opponent(); - if ((CDopponentDamaged == -1 && card->damageToOpponent && card->controller() == p) || (CDopponentDamaged == 1 && !card->damageToOpponent && card->controller() == p) - || (CDopponentDamaged == -1 && card->damageToController && card->controller() == p->opponent()) || (CDopponentDamaged == 1 && !card->damageToController && card->controller() == p->opponent())) + + if ((CDdamager == -1 && (card->damageToOpponent || card->damageToController || card->damageToCreature)) + || (CDdamager == 1 && !(card->damageToOpponent || card->damageToController || card->damageToCreature))) { match = NULL; } - if ((CDcontrollerDamaged == -1 && card->damageToController && card->controller() == p) || (CDcontrollerDamaged == 1 && !card->damageToController && card->controller() == p) - || (CDcontrollerDamaged == -1 && card->damageToOpponent && card->controller() == p->opponent()) || (CDcontrollerDamaged == 1 && !card->damageToOpponent && card->controller() == p->opponent())) + + if(CDopponentDamaged == -1 || CDopponentDamaged == 1) + { + Player * p = card->controller()->opponent();//controller()->opponent(); + if ((CDopponentDamaged == -1 && card->damageToOpponent && card->controller() == p) + || (CDopponentDamaged == 1 && !card->damageToOpponent && card->controller() == p) + || (CDopponentDamaged == -1 && card->damageToController && card->controller() == p->opponent()) + || (CDopponentDamaged == 1 && !card->damageToController && card->controller() == p->opponent())) + { + match = NULL; + } + if ((CDcontrollerDamaged == -1 && card->damageToController && card->controller() == p) + || (CDcontrollerDamaged == 1 && !card->damageToController && card->controller() == p) + || (CDcontrollerDamaged == -1 && card->damageToOpponent && card->controller() == p->opponent()) + || (CDcontrollerDamaged == 1 && !card->damageToOpponent && card->controller() == p->opponent())) { match = NULL; } diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index 0c414ae94..0b5b9d44a 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -17,6 +17,7 @@ #include "Counters.h" #include "ModRules.h" #include "CardDescriptor.h" +#include "GameApp.h" const float CardGui::Width = 28.0; const float CardGui::Height = 40.0; @@ -110,17 +111,17 @@ void CardGui::Update(float dt) PlayGuiObject::Update(dt); } -void CardGui::DrawCard(const Pos& inPosition, int inMode) +void CardGui::DrawCard(const Pos& inPosition, int inMode, bool thumb) { - DrawCard(card, inPosition, inMode); + DrawCard(card, inPosition, inMode, thumb); } -void CardGui::DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode) +void CardGui::DrawCard(MTGCard* inCard, const Pos& inPosition, int inMode, bool thumb) { switch (inMode) { case DrawMode::kNormal: - RenderBig(inCard, inPosition); + RenderBig(inCard, inPosition, thumb); break; case DrawMode::kText: AlternateRender(inCard, inPosition); @@ -957,7 +958,7 @@ void CardGui::TinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad) } //Renders a big card on screen. Defaults to the "alternate" rendering if no image is found -void CardGui::RenderBig(MTGCard* card, const Pos& pos) +void CardGui::RenderBig(MTGCard* card, const Pos& pos, bool thumb) { JRenderer * renderer = JRenderer::GetInstance(); //GameObserver * game = GameObserver::GetInstance(); @@ -966,7 +967,8 @@ void CardGui::RenderBig(MTGCard* card, const Pos& pos) //i want this but ai targets cards so quickly that it can crash the game. float x = pos.actX; - JQuadPtr quad = WResourceManager::Instance()->RetrieveCard(card); + JQuadPtr quad = thumb ? WResourceManager::Instance()->RetrieveCard(card, RETRIEVE_THUMB) + : WResourceManager::Instance()->RetrieveCard(card); MTGCardInstance * kcard = dynamic_cast(card); if(kcard && !kcard->isToken && kcard->name != kcard->model->data->name) { @@ -1222,6 +1224,18 @@ bool CardGui::FilterCard(MTGCard * _card,string filter) cd.CDcontrollerDamaged = 1; } } + //creature dealt damage to anything + else if (attribute.find("damager") != string::npos) + { + if (minus) + { + cd.CDdamager = -1; + } + else + { + cd.CDdamager = 1; + } + } else if (attribute.find("multicolor") != string::npos) { //card is multicolored? diff --git a/projects/mtg/src/CardPrimitive.cpp b/projects/mtg/src/CardPrimitive.cpp index b399bfb07..462457492 100644 --- a/projects/mtg/src/CardPrimitive.cpp +++ b/projects/mtg/src/CardPrimitive.cpp @@ -6,6 +6,7 @@ #include "MTGDeck.h" #include "Subtypes.h" #include "Translate.h" +#include "GameApp.h" using std::string; diff --git a/projects/mtg/src/CarouselDeckView.cpp b/projects/mtg/src/CarouselDeckView.cpp new file mode 100644 index 000000000..7a219dfc0 --- /dev/null +++ b/projects/mtg/src/CarouselDeckView.cpp @@ -0,0 +1,200 @@ +#include "CarouselDeckView.h" + +const float CarouselDeckView::max_scale = 0.96f; +const float CarouselDeckView::x_center = 180; +const float CarouselDeckView::right_border = SCREEN_WIDTH + 180; +const float CarouselDeckView::slide_animation_duration = 0.6f; +const float CarouselDeckView::scroll_animation_duration = 0.3f; + +CarouselDeckView::CarouselDeckView() : + DeckView(10), mScrollOffset(0), mSlideOffset(0), mScrollEasing(mScrollOffset), mSlideEasing(mSlideOffset) +{ +} + +CarouselDeckView::~CarouselDeckView() +{} + +void CarouselDeckView::UpdateViewState(float dt) +{ + if(!mScrollEasing.finished()) + { + mScrollEasing.update(dt); + + if(mScrollOffset <= -1.0f) + { + changePosition(-1); + mScrollEasing.translate(1.0f); + } + else if(mScrollOffset >= 1.0f) + { + changePosition(1); + mScrollEasing.translate(-1.0f); + } + + dirtyCardPos = true; + } + + if(!mSlideEasing.finished()) + { + mSlideEasing.update(dt); + + if(mSlideOffset < mSlideEasing.start_value) + { + //going downwards + if(mSlideOffset < -1.0f) + { + mSlideEasing.translate(2.0f); + changeFilter(1); + } + } + else if(mSlideOffset > mSlideEasing.start_value) + { + //upwards + if(mSlideOffset > 1.0f) + { + mSlideEasing.translate(-2.0f); + changeFilter(-1); + } + } + + dirtyCardPos = true; + } +} + +void CarouselDeckView::UpdateCardPosition(int index) +{ + CardRep &rep = mCards[index]; + + float rotation = mScrollOffset + 8 - index; + + rep.x = x_center + cos((rotation) * M_PI / 12) * (right_border - x_center); + rep.scale = max_scale / 1.12f * cos((rep.x - x_center) * 1.5f / (right_border - x_center)) + 0.2f * max_scale * cos( + cos((rep.x - x_center) * 0.15f / (right_border - x_center))); + rep.y = (SCREEN_HEIGHT_F) / 2.0f + SCREEN_HEIGHT_F * mSlideOffset * (rep.scale + 0.2f); +} + +void CarouselDeckView::Reset() +{ + mSlideEasing.finish(); + mScrollEasing.finish(); + + DeckView::Reset(); +} + +void CarouselDeckView::Render() +{ + // even though we want to draw the cards in a particular z order for layering, we want to prefetch them + // in a different order, ie the center card should appear first, then the adjacent ones + if (WResourceManager::Instance()->IsThreaded()) + { + WResourceManager::Instance()->RetrieveCard(mCards[0].card); + WResourceManager::Instance()->RetrieveCard(mCards[3].card); + WResourceManager::Instance()->RetrieveCard(mCards[4].card); + WResourceManager::Instance()->RetrieveCard(mCards[2].card); + WResourceManager::Instance()->RetrieveCard(mCards[5].card); + WResourceManager::Instance()->RetrieveCard(mCards[1].card); + WResourceManager::Instance()->RetrieveCard(mCards[6].card); + } + + renderCard(6); + renderCard(5); + renderCard(4); + renderCard(0); + + if (mScrollOffset < 0.5 && mScrollOffset > -0.5) + { + renderCard(1); + renderCard(3); + renderCard(2); + } + else if (mScrollOffset < -0.5) + { + renderCard(3); + renderCard(2); + renderCard(1); + } + else + { + renderCard(1); + renderCard(2); + renderCard(3); + } +} + +bool CarouselDeckView::ButtonPressed(Buttons button) +{ + switch(button) + { + case JGE_BTN_LEFT: + changePositionAnimated(-1); + last_user_activity = 0; + break; + case JGE_BTN_RIGHT: + changePositionAnimated(1); + last_user_activity = 0; + break; + case JGE_BTN_UP: + changeFilterAnimated(1); + last_user_activity = 0; + break; + case JGE_BTN_DOWN: + changeFilterAnimated(-1); + last_user_activity = 0; + break; + default: + return false; + } + return true; +} +MTGCard * CarouselDeckView::Click(int x, int y) +{ + int n = getCardIndexNextTo(x, y); + last_user_activity = 0; + + //clicked active card, and no animation is running + if(mSlideEasing.finished() && mScrollEasing.finished()) + { + if(n == 2) + { + return getActiveCard(); + } + else + { + changePositionAnimated(n - 2); + } + } + + return NULL; +} + +MTGCard *CarouselDeckView::Click() +{ + if(mSlideEasing.finished() && mScrollEasing.finished()) + { + return getActiveCard(); + } + else + { + return NULL; + } +} + +void CarouselDeckView::changePositionAnimated(int offset) +{ + if(mScrollEasing.finished()) + mScrollEasing.start((float)offset, (float)(scroll_animation_duration * abs(offset))); + last_user_activity = 0; +} + +void CarouselDeckView::changeFilterAnimated(int offset) +{ + if(mSlideEasing.finished()) + mSlideEasing.start(2.0f * float(offset), float(slide_animation_duration * abs(offset))); + last_user_activity = 0; +} + +MTGCard *CarouselDeckView::getActiveCard() +{ + return mCards[2].card; +} + diff --git a/projects/mtg/src/Credits.cpp b/projects/mtg/src/Credits.cpp index d5c8062b1..84f6d0e67 100644 --- a/projects/mtg/src/Credits.cpp +++ b/projects/mtg/src/Credits.cpp @@ -386,7 +386,7 @@ void Credits::computeTournament(GameObserver* g, GameApp * _app,bool tournament, } if (mGamesWon>mGamesPlayed*0.80 && mGamesWondealDamage(damage); target->damageCount += damage;//the amount must be the actual damage so i changed this from 1 to damage, this fixes pdcount and odcount - if (target->type_as_damageable == Damageable::DAMAGEABLE_MTGCARDINSTANCE) + if (target->type_as_damageable == Damageable::DAMAGEABLE_MTGCARDINSTANCE){ ((MTGCardInstance*)target)->wasDealtDamage = true; + ((MTGCardInstance*)source)->damageToCreature = true; + } if (target->type_as_damageable == Damageable::DAMAGEABLE_PLAYER) { if(target == source->controller()) diff --git a/projects/mtg/src/DeckView.cpp b/projects/mtg/src/DeckView.cpp new file mode 100644 index 000000000..682b75957 --- /dev/null +++ b/projects/mtg/src/DeckView.cpp @@ -0,0 +1,213 @@ +#include "DeckView.h" + +#include "GameOptions.h" +#include "CardGui.h" + +const float DeckView::no_user_activity_show_card_delay = 0.1f; + +DeckView::DeckView(int numberOfCards) + : dirtyFilters(true), dirtyCardPos(true), last_user_activity(0.0f), mFilter(0), mCurrentDeck(NULL) +{ + mCards.resize(numberOfCards); +} + +DeckView::~DeckView() +{ + +} + +void DeckView::Reset() +{ + dirtyFilters = true; + dirtyCardPos = true; + last_user_activity = 0; + mFilter = 0; + mCurrentDeck = NULL; +} + +void DeckView::Update(float dt) +{ + last_user_activity += dt; + + UpdateViewState(dt); + + if(dirtyCardPos) + { + for(unsigned int i = 0; i < mCards.size(); ++i) + { + UpdateCardPosition(i); + } + dirtyCardPos = false; + } +} + +void DeckView::SetDeck(DeckDataWrapper *toShow) +{ + mCurrentDeck = toShow; + dirtyCardPos = true; + dirtyFilters = true; + reloadIndexes(); +} + +DeckDataWrapper* DeckView::deck() +{ + return mCurrentDeck; +} + +void DeckView::changeFilter(int delta) +{ + unsigned int FilterCount = Constants::NB_Colors + 1; + mFilter = (FilterCount + mFilter + delta) % FilterCount; + dirtyFilters = true; +} + +void DeckView::changePosition(int delta) +{ + for(int i = 0; i < delta; ++i) + { + mCurrentDeck->next(); + } + + for(int i = 0; i > delta; --i) + { + mCurrentDeck->prev(); + } + + reloadIndexes(); +} + +int DeckView::filter() +{ + return mFilter; +} + +void DeckView::reloadIndexes() +{ + if(mCurrentDeck != NULL) + { + for (unsigned int i = 0; i < mCards.size(); i++) + { + mCards[i].card = deck()->getCard(i); + } + } +} + +void DeckView::renderCard(int index, int alpha, bool asThumbnail) +{ + WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); + + const CardRep& cardPosition = mCards[index]; + + if (!cardPosition.card) return; + + if (!WResourceManager::Instance()->IsThreaded()) + { + JQuadPtr backQuad = WResourceManager::Instance()->GetQuad(kGenericCardID); + JQuadPtr quad; + + int cacheError = CACHE_ERROR_NONE; + + if (!options[Options::DISABLECARDS].number) + { + quad = WResourceManager::Instance()->RetrieveCard(cardPosition.card, RETRIEVE_EXISTING); + cacheError = WResourceManager::Instance()->RetrieveError(); + if (!quad.get() && cacheError != CACHE_ERROR_404) + { + if (last_user_activity > (abs(2 - index) + 1) * no_user_activity_show_card_delay) + quad = WResourceManager::Instance()->RetrieveCard(cardPosition.card); + else + { + quad = backQuad; + } + } + } + + if (quad.get()) + { + if (quad == backQuad) + { + quad->SetColor(ARGB(255,255,255,255)); + float _scale = cardPosition.scale * (285 / quad->mHeight); + JRenderer::GetInstance()->RenderQuad(quad.get(), cardPosition.x, cardPosition.y, 0.0f, _scale, _scale); + } + else + { + Pos pos = Pos(cardPosition.x, cardPosition.y, cardPosition.scale * 285 / 250, 0.0, 255); + CardGui::DrawCard(cardPosition.card, pos, asThumbnail); + } + } + else + { + Pos pos = Pos(cardPosition.x, cardPosition.y, cardPosition.scale * 285 / 250, 0.0, 255); + CardGui::DrawCard(cardPosition.card, pos, DrawMode::kText, asThumbnail); + } + } + else + { + int mode = !options[Options::DISABLECARDS].number ? DrawMode::kNormal : DrawMode::kText; + + Pos pos = Pos(cardPosition.x, cardPosition.y, cardPosition.scale * 285 / 250, 0.0, 255); + CardGui::DrawCard(cardPosition.card, pos, mode, asThumbnail); + } + + int quadAlpha = alpha; + if (!deck()->count(cardPosition.card)) quadAlpha /= 2; + quadAlpha = 255 - quadAlpha; + if (quadAlpha > 0) + { + JRenderer::GetInstance()->FillRect(cardPosition.x - cardPosition.scale * 100.0f, cardPosition.y - cardPosition.scale * 142.5f, cardPosition.scale * 200.0f, cardPosition.scale * 285.0f, + ARGB(quadAlpha,0,0,0)); + } + if (last_user_activity < 3) + { + int fontAlpha = alpha; + float qtY = cardPosition.y - 135 * cardPosition.scale; + float qtX = cardPosition.x + 40 * cardPosition.scale; + char buffer[4096]; + sprintf(buffer, "x%i", deck()->count(cardPosition.card)); + WFont * font = mFont; + font->SetColor(ARGB(fontAlpha/2,0,0,0)); + JRenderer::GetInstance()->FillRect(qtX, qtY, font->GetStringWidth(buffer) + 6, 16, ARGB(fontAlpha/2,0,0,0)); + font->DrawString(buffer, qtX + 4, qtY + 4); + font->SetColor(ARGB(fontAlpha,255,255,255)); + font->DrawString(buffer, qtX + 2, qtY + 2); + font->SetColor(ARGB(255,255,255,255)); + } +} + +int DeckView::getCardIndexNextTo(int x, int y) +{ + int bestCardIndex = -1; + float bestDistance = 0; + + for(unsigned int i = 0; i < mCards.size(); i++) + { + const CardRep& cardPosition = mCards[i]; + + float dx = (x - cardPosition.x); + float dy = (y - cardPosition.y); + float dist = dx*dx + dy*dy; + + if(dist < bestDistance || bestCardIndex == -1) + { + bestDistance = dist; + bestCardIndex = i; + } + } + + return bestCardIndex; +} + +int DeckView::getPosition() +{ + if(!mCurrentDeck) + { + return 0; + } + + int total = mCurrentDeck->Size(); + int currentPos = (mCurrentDeck->getOffset() + 3) % total; + + while (currentPos <= 0) currentPos += total; + return currentPos; +} diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index aedf0e8b3..b72c2837c 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -795,6 +795,7 @@ void GameObserver::gameStateBasedEffects() c->wasDealtDamage = false; c->damageToController = false; c->damageToOpponent = false; + c->damageToCreature = false; c->isAttacking = NULL; } for (int t = 0; t < nbcards; t++) diff --git a/projects/mtg/src/GameStateDeckViewer.cpp b/projects/mtg/src/GameStateDeckViewer.cpp index a5ef15507..6fba9e779 100644 --- a/projects/mtg/src/GameStateDeckViewer.cpp +++ b/projects/mtg/src/GameStateDeckViewer.cpp @@ -21,13 +21,17 @@ #include "SimpleMenu.h" #include "utils.h" #include "AIPlayer.h" +#include "GameApp.h" +#include "CarouselDeckView.h" +#include "GridDeckView.h" + +#define NO_USER_ACTIVITY_HELP_DELAY 10 GameStateDeckViewer::GameStateDeckViewer(GameApp* parent) : - GameState(parent, "deckeditor") + GameState(parent, "deckeditor"), mView(NULL), mCurrentView(CAROUSEL_VIEW) { bgMusic = NULL; - useFilter = 0; isAIDeckSave = false; mSwitching = false; welcome_menu = NULL; @@ -37,16 +41,15 @@ GameStateDeckViewer::GameStateDeckViewer(GameApp* parent) : source = NULL; hudAlpha = 0; subMenu = NULL; - mRotation = 0; - mSlide = 0; - mAlpha = 255; - menu = NULL; - stw = NULL; + deckMenu = NULL; + mStatsWrapper = NULL; statsPrevButton = NEW InteractiveButton(NULL, kPrevStatsButtonId, Fonts::MAIN_FONT, "Stats", SCREEN_WIDTH_F - 50, SCREEN_HEIGHT_F - 20, JGE_BTN_PREV); toggleDeckButton = NEW InteractiveButton(NULL, kToggleDeckActionId, Fonts::MAIN_FONT, "View Deck", 10, SCREEN_HEIGHT_F - 20, JGE_BTN_PRI); sellCardButton = NEW InteractiveButton(NULL, kSellCardActionId, Fonts::MAIN_FONT, "Sell Card", (SCREEN_WIDTH_F/ 2) - 100, SCREEN_HEIGHT_F - 20, JGE_BTN_SEC); filterButton = NEW InteractiveButton(NULL, kFilterButtonId, Fonts::MAIN_FONT, "filter", (SCREEN_WIDTH_F - 110), SCREEN_HEIGHT_F - 20, JGE_BTN_CTRL); + //TODO: Check if that button is available: + toggleViewButton = NEW InteractiveButton(NULL, kSwitchViewButton, Fonts::MAIN_FONT, "Grid", (SCREEN_WIDTH_F/ 2) + 50, SCREEN_HEIGHT_F - 20, JGE_BTN_MAX); } GameStateDeckViewer::~GameStateDeckViewer() @@ -56,6 +59,8 @@ GameStateDeckViewer::~GameStateDeckViewer() SAFE_DELETE(sellCardButton); SAFE_DELETE(statsPrevButton); SAFE_DELETE(filterButton); + SAFE_DELETE(toggleViewButton); + SAFE_DELETE(mView); if (myDeck) { @@ -70,24 +75,6 @@ GameStateDeckViewer::~GameStateDeckViewer() SAFE_DELETE(filterMenu); } -void GameStateDeckViewer::rotateCards(int direction) -{ - int left = direction; - if (left) - displayed_deck->next(); - else - displayed_deck->prev(); - loadIndexes(); - - int total = displayed_deck->Size(); - if (total) - { - lastPos = getCurrentPos(); - lastTotal = total; - } - -} - void GameStateDeckViewer::rebuildFilters() { if (!filterMenu) filterMenu = NEW WGuiFilters("Filter by...", NULL); @@ -95,108 +82,73 @@ void GameStateDeckViewer::rebuildFilters() SAFE_DELETE(source); source = NEW WSrcDeckViewer(myDeck, myCollection); filterMenu->setSrc(source); - if (displayed_deck != myDeck) source->swapSrc(); + if (mView->deck() != myDeck) source->swapSrc(); filterMenu->Finish(true); - // no stats need updating if there isn't a deck to update - if (stw && myDeck) - stw->updateStats( myDeck );; + // no stats need updating if there isn't a deck to update + if (mStatsWrapper && myDeck) + mStatsWrapper->updateStats( myDeck );; } void GameStateDeckViewer::updateFilters() { - if (!displayed_deck) return; + if (!mView->deck() || !filterMenu) return; - filterMenu->recolorFilter(useFilter - 1); + filterMenu->recolorFilter(mView->filter() - 1); filterMenu->Finish(true); - int totalAfter = displayed_deck->Size(); - if (totalAfter && lastTotal) - { - - //This part is a hack. I don't understand why in some cases "displayed_deck's" currentPos is not 0 at this stage - { - while (int currentPos = displayed_deck->getOffset()) - { - if (currentPos > 0) - displayed_deck->prev(); - else - displayed_deck->next(); - } - } - - int pos = (totalAfter * lastPos) / lastTotal; - for (int i = 0; i < pos - 3; ++i) - { // "-3" because card "0" is displayed at position 3 initially - displayed_deck->next(); - } - } - stw->updateStats( myDeck );; + mStatsWrapper->updateStats( myDeck );; return; } -void GameStateDeckViewer::loadIndexes() +void GameStateDeckViewer::toggleCollection() { - for (int i = 0; i < 7; i++) + if (mView->deck() == myCollection) { - cardIndex[i] = displayed_deck->getCard(i); - } -} - -void GameStateDeckViewer::switchDisplay() -{ - if (displayed_deck == myCollection) - { - displayed_deck = myDeck; toggleDeckButton->setText("View Collection"); + mView->SetDeck(myDeck); } else { toggleDeckButton->setText("View Deck"); - displayed_deck = myCollection; + mView->SetDeck(myCollection); } source->swapSrc(); updateFilters(); - loadIndexes(); } +//after renaming and on the first start. +//reloadWelcomeMenu void GameStateDeckViewer::updateDecks() { SAFE_DELETE(welcome_menu); welcome_menu = NEW DeckEditorMenu(MENU_DECK_SELECTION, this, Fonts::OPTION_FONT, "Choose Deck To Edit"); - DeckManager * deckManager = DeckManager::GetInstance(); vector playerDeckList = fillDeckMenu(welcome_menu, options.profileFile()); newDeckname = ""; welcome_menu->Add(MENU_ITEM_NEW_DECK, "--NEW--"); - if (options[Options::CHEATMODE].number && (!myCollection || myCollection->getCount(WSrcDeck::UNFILTERED_MIN_COPIES) < 4)) welcome_menu->Add( - MENU_ITEM_CHEAT_MODE, "--UNLOCK CARDS--"); + if (options[Options::CHEATMODE].number && (!myCollection || myCollection->getCount(WSrcDeck::UNFILTERED_MIN_COPIES) < 4)) + { + welcome_menu->Add(MENU_ITEM_CHEAT_MODE, "--UNLOCK CARDS--"); + } welcome_menu->Add(MENU_ITEM_CANCEL, "Cancel"); // update the deckmanager with the latest information - deckManager->updateMetaDataList(&playerDeckList, false); - // is this necessary to ensure no memory leaks? - playerDeckList.clear(); + DeckManager::GetInstance()->updateMetaDataList(&playerDeckList, false); } void GameStateDeckViewer::buildEditorMenu() { - ostringstream deckSummaryInformation; - deckSummaryInformation << _("All changes are final.").c_str() << endl; + SAFE_DELETE(deckMenu); - if (menu) - SAFE_DELETE( menu ); - //Build menu. - JRenderer::GetInstance()->FillRoundRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 100, ARGB(0, 0, 0, 0) ); - menu = NEW DeckEditorMenu(MENU_DECK_BUILDER, this, Fonts::OPTION_FONT, "Deck Editor", myDeck, stw); - - menu->Add(MENU_ITEM_FILTER_BY, _("Filter By...").c_str(), _("Narrow down the list of cards. ").c_str()); - menu->Add(MENU_ITEM_SWITCH_DECKS_NO_SAVE, _("Switch Decks").c_str(), _("Do not make any changes. View another deck.").c_str()); - menu->Add(MENU_ITEM_SAVE_RENAME, _("Rename Deck").c_str(), _("Change the name of the deck").c_str()); - menu->Add(MENU_ITEM_SAVE_RETURN_MAIN_MENU, _("Save & Quit Editor").c_str(), _("Save changes. Return to the main menu").c_str()); - menu->Add(MENU_ITEM_SAVE_AS_AI_DECK, _("Save As AI Deck").c_str(), deckSummaryInformation.str()); - menu->Add(MENU_ITEM_MAIN_MENU, _("Quit Editor").c_str(), _("Do not make any changes to deck. Return to the main menu.").c_str()); - menu->Add(MENU_ITEM_EDITOR_CANCEL, _("Cancel").c_str(), _("Close menu.").c_str()); + deckMenu = NEW DeckEditorMenu(MENU_DECK_BUILDER, this, Fonts::OPTION_FONT, "Deck Editor", myDeck, mStatsWrapper); + deckMenu->Add(MENU_ITEM_FILTER_BY, _("Filter By..."), _("Narrow down the list of cards. ")); + deckMenu->Add(MENU_ITEM_SWITCH_DECKS_NO_SAVE, _("Switch Decks"), _("Do not make any changes. View another deck.")); + deckMenu->Add(MENU_ITEM_SAVE_RENAME, _("Rename Deck"), _("Change the name of the deck")); + deckMenu->Add(MENU_ITEM_SAVE_RETURN_MAIN_MENU, _("Save & Quit Editor"), _("Save changes. Return to the main menu")); + deckMenu->Add(MENU_ITEM_SAVE_AS_AI_DECK, _("Save As AI Deck"), _("All changes are final.")); + deckMenu->Add(MENU_ITEM_MAIN_MENU, _("Quit Editor"), _("Do not make any changes to deck. Return to the main menu.")); + deckMenu->Add(MENU_ITEM_EDITOR_CANCEL, _("Cancel"), _("Close menu.")); } void GameStateDeckViewer::Start() @@ -206,20 +158,16 @@ void GameStateDeckViewer::Start() subMenu = NULL; myDeck = NULL; mStage = STAGE_WELCOME; - mRotation = 0; - mSlide = 0; - mAlpha = 255; + last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; onScreenTransition = 0; - useFilter = 0; - lastPos = 0; - lastTotal = 0; pricelist = NEW PriceList("settings/prices.dat", MTGCollection()); playerdata = NEW PlayerData(MTGCollection()); myCollection = NEW DeckDataWrapper(playerdata->collection); myCollection->Sort(WSrcCards::SORT_ALPHA); - displayed_deck = myCollection; + setupView(mCurrentView, myCollection); + toggleDeckButton->setText("View Deck"); //Icons mIcons = manaIcons; @@ -248,7 +196,6 @@ void GameStateDeckViewer::Start() GameApp::playMusic("Track1.mp3"); - loadIndexes(); mEngine->ResetInput(); JRenderer::GetInstance()->EnableVSync(true); } @@ -258,7 +205,7 @@ void GameStateDeckViewer::End() JRenderer::GetInstance()->EnableVSync(false); SAFE_DELETE(welcome_menu); - SAFE_DELETE(menu); + SAFE_DELETE(deckMenu); SAFE_DELETE(subMenu); WResourceManager::Instance()->Release(pspIconsTexture); @@ -280,9 +227,9 @@ void GameStateDeckViewer::End() void GameStateDeckViewer::addRemove(MTGCard * card) { if (!card) return; - if (displayed_deck->Remove(card, 1, (displayed_deck == myDeck))) + if (mView->deck()->Remove(card, 1, (mView->deck() == myDeck))) { - if (displayed_deck == myCollection) + if (mView->deck() == myCollection) { myDeck->Add(card); myDeck->Sort(WSrcCards::SORT_ALPHA); @@ -294,8 +241,8 @@ void GameStateDeckViewer::addRemove(MTGCard * card) } myCollection->validate(); myDeck->validate(); - stw->needUpdate = true; - loadIndexes(); + mStatsWrapper->needUpdate = true; + mView->reloadIndexes(); } void GameStateDeckViewer::saveDeck() @@ -340,10 +287,10 @@ void GameStateDeckViewer::sellCard() SAFE_DELETE(subMenu); char buffer[4096]; { - MTGCard * card = cardIndex[2]; - if (card && displayed_deck->count(card)) + MTGCard * card = mView->getActiveCard(); + if (card && mView->deck()->count(card)) { - price = pricelist->getSellPrice(card->getMTGId()); + int price = pricelist->getSellPrice(card); sprintf(buffer, "%s : %i %s", _(card->data->getName()).c_str(), price, _("credits").c_str()); const float menuXOffset = SCREEN_WIDTH_F - 300; const float menuYOffset = SCREEN_HEIGHT_F / 2; @@ -352,18 +299,18 @@ void GameStateDeckViewer::sellCard() subMenu->Add(MENU_ITEM_NO, "No", "", true); } } - stw->needUpdate = true; + mStatsWrapper->needUpdate = true; } bool GameStateDeckViewer::userPressedButton() { - return ( - (toggleDeckButton->ButtonPressed()) + return ((toggleDeckButton->ButtonPressed()) || (sellCardButton->ButtonPressed()) || (statsPrevButton->ButtonPressed()) || (filterButton->ButtonPressed()) + || (toggleViewButton->ButtonPressed()) ); - } +} void GameStateDeckViewer::setButtonState(bool state) { @@ -371,6 +318,7 @@ void GameStateDeckViewer::setButtonState(bool state) sellCardButton->setIsSelectionValid(state); statsPrevButton->setIsSelectionValid(state); filterButton->setIsSelectionValid(state); + toggleViewButton->setIsSelectionValid(state); } @@ -380,16 +328,37 @@ void GameStateDeckViewer::RenderButtons() sellCardButton->Render(); filterButton->Render(); statsPrevButton->Render(); + toggleViewButton->Render(); +} + +void GameStateDeckViewer::setupView(GameStateDeckViewer::AvailableView view, DeckDataWrapper *deck) +{ + SAFE_DELETE(mView); + + if(view == CAROUSEL_VIEW) mView = NEW CarouselDeckView(); + else if(view == GRID_VIEW) mView = NEW GridDeckView(); + + mView->SetDeck(deck); + updateFilters(); +} + +void GameStateDeckViewer::toggleView() +{ + if(mCurrentView == CAROUSEL_VIEW) + { + mCurrentView = GRID_VIEW; + toggleViewButton->setText("Carousel"); + } + else + { + mCurrentView = CAROUSEL_VIEW; + toggleViewButton->setText("Grid"); + } + setupView(mCurrentView, mView->deck()); } void GameStateDeckViewer::Update(float dt) -{ - - int x, y; - unsigned int distance2; - unsigned int minDistance2 = -1; - int n = 0; - +{ if (options.keypadActive()) { options.keypadUpdate(dt); @@ -418,7 +387,7 @@ void GameStateDeckViewer::Update(float dt) //Prevent screen from updating. return; } - hudAlpha = 255 - ((int) last_user_activity * 500); + hudAlpha = 255 - (int)(MAX(last_user_activity-2.0f, 0) * 500); if (hudAlpha < 0) hudAlpha = 0; if (subMenu) { @@ -431,27 +400,18 @@ void GameStateDeckViewer::Update(float dt) } if (mStage == STAGE_WAITING || mStage == STAGE_ONSCREEN_MENU) { - switch (mEngine->ReadButton()) + JButton button = mEngine->ReadButton(); + switch (button) { case JGE_BTN_LEFT: - last_user_activity = 0; - mStage = STAGE_TRANSITION_LEFT; - break; case JGE_BTN_RIGHT: - last_user_activity = 0; - mStage = STAGE_TRANSITION_RIGHT; - break; case JGE_BTN_UP: - last_user_activity = 0; - mStage = STAGE_TRANSITION_UP; - useFilter++; - if (useFilter >= MAX_SAVED_FILTERS) useFilter = 0; - break; case JGE_BTN_DOWN: - last_user_activity = 0; - mStage = STAGE_TRANSITION_DOWN; - useFilter--; - if (useFilter < 0) useFilter = MAX_SAVED_FILTERS - 1; + if(mView->ButtonPressed(button)) + { + last_user_activity = 0; + mStage = STAGE_WAITING; + } break; case JGE_BTN_CANCEL: options[Options::DISABLECARDS].number = !options[Options::DISABLECARDS].number; @@ -460,45 +420,46 @@ void GameStateDeckViewer::Update(float dt) if (last_user_activity > 0.2) { last_user_activity = 0; - switchDisplay(); + toggleCollection(); + } + break; + case JGE_BTN_MAX: + if (last_user_activity > 0.2) + { + last_user_activity = 0; + toggleView(); } break; case JGE_BTN_OK: + { + // verify that none of the buttons fired + if (userPressedButton()) + { + Update(dt); + break; + } + + int x, y; if (mEngine->GetLeftClickCoordinates(x, y)) { - // verify that none of the buttons fired - if (userPressedButton()) - { - Update(dt); - break; - } - - for(int i=0; i < CARDS_DISPLAYED; i++) - { - distance2 = static_cast((cardsCoordinates[i].second - y) * (cardsCoordinates[i].second - y) + (cardsCoordinates[i].first - x) * (cardsCoordinates[i].first - x)); - if (distance2 < minDistance2) - { - minDistance2 = distance2; - n = i; - } - } - - if(n != 2) - { - mSelected = n; - last_user_activity = 0; - mStage = STAGE_TRANSITION_SELECTED; - } mEngine->LeftClickedProcessed(); + if(mView->Click(x, y) != NULL) + { + addRemove(mView->getActiveCard()); + } } - - if(mStage != STAGE_TRANSITION_SELECTED && last_user_activity > .05) + else { - last_user_activity = 0; - addRemove(cardIndex[2]); + if(mView->Click() != NULL) + { + addRemove(mView->getActiveCard()); + } } - + + last_user_activity = 0; + mStage = STAGE_WAITING; break; + } case JGE_BTN_SEC: sellCard(); break; @@ -508,27 +469,30 @@ void GameStateDeckViewer::Update(float dt) buildEditorMenu(); break; case JGE_BTN_CTRL: - mStage = STAGE_FILTERS; - if (!filterMenu) + if(!mView->ButtonPressed(JGE_BTN_CTRL)) { - filterMenu = NEW WGuiFilters("Filter by...", NULL); - if (source) - SAFE_DELETE(source); - source = NEW WSrcDeckViewer(myDeck, myCollection); - filterMenu->setSrc(source); - if (displayed_deck != myDeck) source->swapSrc(); + mStage = STAGE_FILTERS; + if (!filterMenu) + { + filterMenu = NEW WGuiFilters("Filter by...", NULL); + if (source) + SAFE_DELETE(source); + source = NEW WSrcDeckViewer(myDeck, myCollection); + filterMenu->setSrc(source); + if (mView->deck() != myDeck) source->swapSrc(); + } + filterMenu->Entering(JGE_BTN_NONE); } - filterMenu->Entering(JGE_BTN_NONE); break; case JGE_BTN_PREV: if (last_user_activity < NO_USER_ACTIVITY_HELP_DELAY) last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; - else if ((mStage == STAGE_ONSCREEN_MENU) && (--stw->currentPage < 0)) stw->currentPage = stw->pageCount; + else if ((mStage == STAGE_ONSCREEN_MENU) && (--mStatsWrapper->currentPage < 0)) mStatsWrapper->currentPage = mStatsWrapper->pageCount; break; case JGE_BTN_NEXT: if (last_user_activity < NO_USER_ACTIVITY_HELP_DELAY) last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; - else if ((mStage == STAGE_ONSCREEN_MENU) && (++stw->currentPage > stw->pageCount)) stw->currentPage = 0; + else if ((mStage == STAGE_ONSCREEN_MENU) && (++mStatsWrapper->currentPage > mStatsWrapper->pageCount)) mStatsWrapper->currentPage = 0; break; default: // no keypress if (last_user_activity > NO_USER_ACTIVITY_HELP_DELAY) @@ -548,111 +512,24 @@ void GameStateDeckViewer::Update(float dt) } else last_user_activity += dt; - + break; } } - if (mStage == STAGE_TRANSITION_SELECTED) - { - if (mSelected < 2) - { - mRotation -= dt * MED_SPEED; - if (mRotation < mSelected-2) - { - do - { - rotateCards(STAGE_TRANSITION_RIGHT); - mRotation += 1; - } while (mRotation < -1.0f); - mStage = STAGE_WAITING; - mRotation = 0; - } - } - else if (mSelected > 2) - { - mRotation += dt * MED_SPEED; - if (mRotation > mSelected - 2) - { - do - { - rotateCards(STAGE_TRANSITION_LEFT); - mRotation -= 1; - } while (mRotation > 1.0f); - mStage = STAGE_WAITING; - mRotation = 0; - } - } - } - if (mStage == STAGE_TRANSITION_RIGHT || mStage == STAGE_TRANSITION_LEFT) - { - if (mStage == STAGE_TRANSITION_RIGHT) - { - mRotation -= dt * MED_SPEED; - if (mRotation < -1.0f) - { - do - { - rotateCards(mStage); - mRotation += 1; - } while (mRotation < -1.0f); - mStage = STAGE_WAITING; - mRotation = 0; - } - } - else if (mStage == STAGE_TRANSITION_LEFT) - { - mRotation += dt * MED_SPEED; - if (mRotation > 1.0f) - { - do - { - rotateCards(mStage); - mRotation -= 1; - } while (mRotation > 1.0f); - mStage = STAGE_WAITING; - mRotation = 0; - } - } - } - if (mStage == STAGE_TRANSITION_DOWN || mStage == STAGE_TRANSITION_UP) - { - if (mStage == STAGE_TRANSITION_DOWN) - { - mSlide -= 0.05f; - if (mSlide < -1.0f) - { - updateFilters(); - loadIndexes(); - mSlide = 1; - } - else if (mSlide > 0 && mSlide < 0.05) - { - mStage = STAGE_WAITING; - mSlide = 0; - } - } - if (mStage == STAGE_TRANSITION_UP) - { - mSlide += 0.05f; - if (mSlide > 1.0f) - { - updateFilters(); - loadIndexes(); - mSlide = -1; - } - else if (mSlide < 0 && mSlide > -0.05) - { - mStage = STAGE_WAITING; - mSlide = 0; - } - } + mView->Update(dt); + if(mView->dirtyFilters) + { + updateFilters(); + mView->reloadIndexes(); + mView->dirtyFilters = false; } - else if (mStage == STAGE_WELCOME) + + if (mStage == STAGE_WELCOME) welcome_menu->Update(dt); else if (mStage == STAGE_MENU) - menu->Update(dt); + deckMenu->Update(dt); else if (mStage == STAGE_FILTERS) { JButton key = mEngine->ReadButton(); @@ -663,19 +540,20 @@ void GameStateDeckViewer::Update(float dt) //useFilter = 0; filterMenu->Finish(true); filterMenu->Update(dt); - loadIndexes(); + mView->reloadIndexes(); return; } if (!filterMenu->isFinished()) { filterMenu->CheckUserInput(key); filterMenu->Update(dt); + mView->reloadIndexes(); } else { mStage = STAGE_WAITING; updateFilters(); - loadIndexes(); + mView->reloadIndexes(); } } } @@ -689,16 +567,16 @@ void GameStateDeckViewer::renderOnScreenBasicInfo() float y = 0; int allCopies, nowCopies; - nowCopies = displayed_deck->getCount(WSrcDeck::FILTERED_COPIES); - allCopies = displayed_deck->getCount(WSrcDeck::UNFILTERED_COPIES); - WCardFilter * wc = displayed_deck->getFiltersRoot(); + nowCopies = mView->deck()->getCount(WSrcDeck::FILTERED_COPIES); + allCopies = mView->deck()->getCount(WSrcDeck::UNFILTERED_COPIES); + WCardFilter * wc = mView->deck()->getFiltersRoot(); if (wc) - sprintf(buffer, "%s %i of %i cards (%i unique)", (displayed_deck == myDeck) ? "DECK: " : " ", nowCopies, allCopies, - displayed_deck->getCount(WSrcDeck::FILTERED_UNIQUE)); + sprintf(buffer, "%s %i of %i cards (%i unique)", (mView->deck() == myDeck) ? "DECK: " : " ", nowCopies, allCopies, + mView->deck()->getCount(WSrcDeck::FILTERED_UNIQUE)); else - sprintf(buffer, "%s%i cards (%i unique)", (displayed_deck == myDeck) ? "DECK: " : " ", allCopies, displayed_deck->getCount( - WSrcDeck::UNFILTERED_UNIQUE)); + sprintf(buffer, "%s%i cards (%i unique)", (mView->deck() == myDeck) ? "DECK: " : " ", allCopies, + mView->deck()->getCount(WSrcDeck::UNFILTERED_UNIQUE)); float w = mFont->GetStringWidth(buffer); PIXEL_TYPE backupColor = mFont->GetColor(); @@ -708,34 +586,21 @@ void GameStateDeckViewer::renderOnScreenBasicInfo() mFont->DrawString(buffer, SCREEN_WIDTH - 22, y + 15, JGETEXT_RIGHT); mFont->SetColor(backupColor); - if (useFilter != 0) renderer->RenderQuad(mIcons[useFilter - 1].get(), SCREEN_WIDTH - 10, y + 15, 0.0f, 0.5, 0.5); -} - -//returns position of the current card (cusor) in the currently viewed color/filter -int GameStateDeckViewer::getCurrentPos() -{ - int total = displayed_deck->Size(); - - int currentPos = displayed_deck->getOffset(); - currentPos += 2; //we start by displaying card number 3 - currentPos = currentPos % total + 1; - if (currentPos < 0) currentPos = (total + currentPos); - if (!currentPos) currentPos = total; - return currentPos; + if (mView->filter() != 0) renderer->RenderQuad(mIcons[mView->filter() - 1].get(), SCREEN_WIDTH - 10, y + 15, 0.0f, 0.5, 0.5); } void GameStateDeckViewer::renderSlideBar() { WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); - int total = displayed_deck->Size(); + int total = mView->deck()->Size(); if (total == 0) return; float filler = 15; float y = SCREEN_HEIGHT_F - 25; float bar_size = SCREEN_WIDTH_F - 2 * filler; JRenderer * r = JRenderer::GetInstance(); - int currentPos = getCurrentPos(); + int currentPos = mView->getPosition(); float cursor_pos = bar_size * currentPos / total; @@ -746,7 +611,7 @@ void GameStateDeckViewer::renderSlideBar() r->DrawLine(filler + cursor_pos, y, filler + cursor_pos, y + 5, ARGB(hudAlpha,255,255,255)); char buffer[256]; string deckname = _("Collection"); - if (displayed_deck == myDeck) + if (mView->deck() == myDeck) { deckname = _("Deck"); } @@ -785,9 +650,9 @@ void GameStateDeckViewer::renderDeckBackground() maxC2 = maxC1; } PIXEL_TYPE colors[] = { ARGB(255, Constants::_r[maxC1], Constants::_g[maxC1], Constants::_b[maxC1]), - ARGB(255, Constants::_r[maxC1], Constants::_g[maxC1], Constants::_b[maxC1]), - ARGB(255, Constants::_r[maxC2], Constants::_g[maxC2], Constants::_b[maxC2]), - ARGB(255, Constants::_r[maxC2], Constants::_g[maxC2], Constants::_b[maxC2]), }; + ARGB(255, Constants::_r[maxC1], Constants::_g[maxC1], Constants::_b[maxC1]), + ARGB(255, Constants::_r[maxC2], Constants::_g[maxC2], Constants::_b[maxC2]), + ARGB(255, Constants::_r[maxC2], Constants::_g[maxC2], Constants::_b[maxC2]), }; JRenderer::GetInstance()->FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, colors); @@ -814,7 +679,7 @@ void GameStateDeckViewer::renderOnScreenMenu() bool renderPSPIcons = true; #endif - if (stw->currentPage == 0) + if (mStatsWrapper->currentPage == 0) { //FillRects r->FillRect(0 - (onScreenTransition * 84), 0, 84, SCREEN_HEIGHT, ARGB(128,0,0,0)); @@ -845,7 +710,7 @@ void GameStateDeckViewer::renderOnScreenMenu() font->DrawString(_("Toggle Images"), rightPspX - 35, rightPspY - 40); - if (displayed_deck == myCollection) + if (mView->deck() == myCollection) { font->DrawString(_("Add card"), rightPspX + 20, rightPspY - 15); font->DrawString(_("View Deck"), rightPspX - 20, rightPspY - 15, JGETEXT_RIGHT); @@ -860,7 +725,7 @@ void GameStateDeckViewer::renderOnScreenMenu() font->DrawString(_("menu"), SCREEN_WIDTH - 35 + rightTransition, SCREEN_HEIGHT - 15); font->DrawString(_("filter"), SCREEN_WIDTH - 95 + rightTransition, SCREEN_HEIGHT - 15); - if (displayed_deck == myCollection) + if (mView->deck() == myCollection) { font->DrawString(_("in: collection"), 5 - leftTransition, 5); font->DrawString(_("Use SQUARE to view your deck,"), SCREEN_WIDTH - 200 + rightTransition, 5); @@ -879,7 +744,7 @@ void GameStateDeckViewer::renderOnScreenMenu() // print stuff here about the editor commands float textYOffset = SCREEN_HEIGHT_F/2; font->DrawString(_("Click on the card image"), SCREEN_WIDTH - 200 + rightTransition, textYOffset - (2 * fH)); - if (displayed_deck == myCollection) + if (mView->deck() == myCollection) font->DrawString(_("to add card to deck."), SCREEN_WIDTH - 200 + rightTransition, textYOffset - fH); else font->DrawString(_("to remove card from deck."), SCREEN_WIDTH - 200 + rightTransition, textYOffset - fH); @@ -915,7 +780,7 @@ void GameStateDeckViewer::renderOnScreenMenu() } else { - stw->updateStats( myDeck );; + mStatsWrapper->updateStats( myDeck );; char buffer[300]; @@ -937,16 +802,16 @@ void GameStateDeckViewer::renderOnScreenMenu() graphColor = ARGB(200, 155, 155, 155); string STATS_TITLE_FORMAT = _("%i: %s"); - switch (stw->currentPage) + switch (mStatsWrapper->currentPage) { case 1: // Counts, price // Title - sprintf(buffer, STATS_TITLE_FORMAT.c_str(), stw->currentPage, _("Statistics Summary").c_str()); + sprintf(buffer, STATS_TITLE_FORMAT.c_str(), mStatsWrapper->currentPage, _("Statistics Summary").c_str()); font->DrawString(buffer, 10 + leftTransition, 10); posY = 30; posX = 180; - sprintf(buffer, _("Your Deck: %i cards").c_str(), stw->cardCount); + sprintf(buffer, _("Your Deck: %i cards").c_str(), mStatsWrapper->cardCount); font->DrawString(buffer, 20 + leftTransition, posY); posY += 10; @@ -978,34 +843,34 @@ void GameStateDeckViewer::renderOnScreenMenu() r->DrawLine(20 + leftTransition, posY - 1, posX + 40 + leftTransition, posY - 1, ARGB(128, 255, 255, 255)); font->DrawString(_("Lands"), 20 + leftTransition, posY); - sprintf(buffer, _("%i").c_str(), stw->countLands); + sprintf(buffer, _("%i").c_str(), mStatsWrapper->countLands); font->DrawString(buffer, posX + leftTransition, posY); posY += 14; r->DrawLine(20 + leftTransition, posY - 1, posX + 40 + leftTransition, posY - 1, ARGB(128, 255, 255, 255)); font->DrawString(_("Creatures"), 20 + leftTransition, posY); - sprintf(buffer, _("%i").c_str(), stw->countCreatures); + sprintf(buffer, _("%i").c_str(), mStatsWrapper->countCreatures); font->DrawString(buffer, posX + leftTransition, posY); posY += 14; r->DrawLine(20 + leftTransition, posY - 1, posX + 40 + leftTransition, posY - 1, ARGB(128, 255, 255, 255)); font->DrawString(_("Spells"), 20 + leftTransition, posY); - sprintf(buffer, _("%i").c_str(), stw->countSpells); + sprintf(buffer, _("%i").c_str(), mStatsWrapper->countSpells); font->DrawString(buffer, posX + leftTransition, posY); posY += 10; font->DrawString(_("Instants"), 30 + leftTransition, posY); - sprintf(buffer, _("%i").c_str(), stw->countInstants); + sprintf(buffer, _("%i").c_str(), mStatsWrapper->countInstants); font->DrawString(buffer, posX + leftTransition, posY); posY += 10; font->DrawString(_("Enchantments"), 30 + leftTransition, posY); - sprintf(buffer, _("%i").c_str(), stw->countEnchantments); + sprintf(buffer, _("%i").c_str(), mStatsWrapper->countEnchantments); font->DrawString(buffer, posX + leftTransition, posY); posY += 10; font->DrawString(_("Sorceries"), 30 + leftTransition, posY); - sprintf(buffer, _("%i").c_str(), stw->countSorceries); + sprintf(buffer, _("%i").c_str(), mStatsWrapper->countSorceries); font->DrawString(buffer, posX + leftTransition, posY); //sprintf(buffer, "Artifacts: %i", stw->countArtifacts); //mFont->DrawString(buffer, 20, 123); @@ -1014,7 +879,7 @@ void GameStateDeckViewer::renderOnScreenMenu() r->DrawLine(20 + leftTransition, posY - 1, posX + 40 + leftTransition, posY - 1, ARGB(128, 255, 255, 255)); font->DrawString(_("Average converted mana cost"), 20 + leftTransition, posY); - sprintf(buffer, _("%2.2f").c_str(), stw->avgManaCost); + sprintf(buffer, _("%2.2f").c_str(), mStatsWrapper->avgManaCost); font->DrawString(buffer, posX + leftTransition, posY); posY += 14; @@ -1023,17 +888,17 @@ void GameStateDeckViewer::renderOnScreenMenu() posY += 10; font->DrawString(_("No land in 1st hand"), 30 + leftTransition, posY); - sprintf(buffer, _("%2.2f%%").c_str(), stw->noLandsProbInTurn[0]); + sprintf(buffer, _("%2.2f%%").c_str(), mStatsWrapper->noLandsProbInTurn[0]); font->DrawString(buffer, posX + leftTransition, posY); posY += 10; font->DrawString(_("No land in 9 cards"), 30 + leftTransition, posY); - sprintf(buffer, _("%2.2f%%").c_str(), stw->noLandsProbInTurn[2]); + sprintf(buffer, _("%2.2f%%").c_str(), mStatsWrapper->noLandsProbInTurn[2]); font->DrawString(buffer, posX + leftTransition, posY); posY += 10; font->DrawString(_("No creatures in 1st hand"), 30 + leftTransition, posY); - sprintf(buffer, _("%2.2f%%").c_str(), stw->noCreaturesProbInTurn[0]); + sprintf(buffer, _("%2.2f%%").c_str(), mStatsWrapper->noCreaturesProbInTurn[0]); font->DrawString(buffer, posX + leftTransition, posY); // Playgame Statistics @@ -1043,25 +908,25 @@ void GameStateDeckViewer::renderOnScreenMenu() posY += 10; font->DrawString(_("Games played"), 30 + leftTransition, posY); - sprintf(buffer, _("%i").c_str(), stw->gamesPlayed); + sprintf(buffer, _("%i").c_str(), mStatsWrapper->gamesPlayed); font->DrawString(buffer, posX + leftTransition, posY); posY += 10; font->DrawString(_("Victory ratio"), 30 + leftTransition, posY); - sprintf(buffer, _("%i%%").c_str(), stw->percentVictories); + sprintf(buffer, _("%i%%").c_str(), mStatsWrapper->percentVictories); font->DrawString(buffer, posX + leftTransition, posY); posY += 15; r->DrawLine(20 + leftTransition, posY - 1, posX + 40 + leftTransition, posY - 1, ARGB(128, 255, 255, 255)); font->DrawString(_("Total price (credits)"), 20 + leftTransition, posY); - sprintf(buffer, _("%i ").c_str(), stw->totalPrice); + sprintf(buffer, _("%i ").c_str(), mStatsWrapper->totalPrice); font->DrawString(buffer, posX + leftTransition, posY); r->DrawLine(20 + leftTransition, posY + 13, posX + 40 + leftTransition, posY + 13, ARGB(128, 255, 255, 255)); break; case 5: // Land statistics - sprintf(buffer, STATS_TITLE_FORMAT.c_str(), stw->currentPage, _("Mana production").c_str()); + sprintf(buffer, STATS_TITLE_FORMAT.c_str(), mStatsWrapper->currentPage, _("Mana production").c_str()); font->DrawString(buffer, 10 + leftTransition, 10); font->DrawString(_("Counts of manasources per type and color:"), 20 + leftTransition, 30); @@ -1079,19 +944,19 @@ void GameStateDeckViewer::renderOnScreenMenu() // Horizontal table lines r->DrawLine(27 + leftTransition, posY - 20, 60 + (Constants::NB_Colors - 2) * 15 + leftTransition, posY - 20, - ARGB(128, 255, 255, 255)); + ARGB(128, 255, 255, 255)); r->DrawLine(27 + leftTransition, posY - 1, 60 + (Constants::NB_Colors - 2) * 15 + leftTransition, posY - 1, - ARGB(128, 255, 255, 255)); + ARGB(128, 255, 255, 255)); r->DrawLine(27 + leftTransition, 2 * 10 + posY + 12, 60 + (Constants::NB_Colors - 2) * 15 + leftTransition, 2 * 10 - + posY + 12, ARGB(128, 255, 255, 255)); + + posY + 12, ARGB(128, 255, 255, 255)); r->DrawLine(27 + leftTransition, 3 * 10 + posY + 14, 60 + (Constants::NB_Colors - 2) * 15 + leftTransition, 3 * 10 - + posY + 14, ARGB(128, 255, 255, 255)); + + posY + 14, ARGB(128, 255, 255, 255)); // Vertical table lines r->DrawLine(26 + leftTransition, posY - 20, 26 + leftTransition, 3 * 10 + posY + 14, ARGB(128, 255, 255, 255)); r->DrawLine(43 + leftTransition, posY - 20, 43 + leftTransition, 3 * 10 + posY + 14, ARGB(128, 255, 255, 255)); r->DrawLine(60 + leftTransition + (Constants::NB_Colors - 2) * 15, posY - 20, 60 + leftTransition - + (Constants::NB_Colors - 2) * 15, 3 * 10 + posY + 14, ARGB(128, 255, 255, 255)); + + (Constants::NB_Colors - 2) * 15, 3 * 10 + posY + 14, ARGB(128, 255, 255, 255)); font->DrawString(_("BL"), 27 + leftTransition, posY); font->DrawString(_("NB"), 27 + leftTransition, posY + 10); @@ -1102,7 +967,7 @@ void GameStateDeckViewer::renderOnScreenMenu() for (int j = 0; j < Constants::NB_Colors - 1; j++) { - curCount = stw->countBasicLandsPerColor[j]; + curCount = mStatsWrapper->countBasicLandsPerColor[j]; if(curCount == 0) { sprintf(buffer, "."); } else { @@ -1110,7 +975,7 @@ void GameStateDeckViewer::renderOnScreenMenu() } font->DrawString(buffer, 49 + leftTransition + j * 15, posY); - curCount = stw->countLandsPerColor[j]; + curCount = mStatsWrapper->countLandsPerColor[j]; if(curCount == 0) { sprintf(buffer, "."); } else { @@ -1118,7 +983,7 @@ void GameStateDeckViewer::renderOnScreenMenu() } font->DrawString(buffer, 49 + leftTransition + j * 15, posY + 10); - curCount = stw->countNonLandProducersPerColor[j]; + curCount = mStatsWrapper->countNonLandProducersPerColor[j]; if(curCount == 0) { sprintf(buffer, "."); } else { @@ -1126,7 +991,7 @@ void GameStateDeckViewer::renderOnScreenMenu() } font->DrawString(buffer, 49 + leftTransition + j * 15, posY + 20); - curCount = stw->countLandsPerColor[j] + stw->countBasicLandsPerColor[j] + stw->countNonLandProducersPerColor[j]; + curCount = mStatsWrapper->countLandsPerColor[j] + mStatsWrapper->countBasicLandsPerColor[j] + mStatsWrapper->countNonLandProducersPerColor[j]; if(curCount == 0) { sprintf(buffer, "."); } else { @@ -1147,7 +1012,7 @@ void GameStateDeckViewer::renderOnScreenMenu() break; case 6: // Land statistics - in symbols - sprintf(buffer, STATS_TITLE_FORMAT.c_str(), stw->currentPage, _("Mana production - in mana symbols").c_str()); + sprintf(buffer, STATS_TITLE_FORMAT.c_str(), mStatsWrapper->currentPage, _("Mana production - in mana symbols").c_str()); font->DrawString(buffer, 10 + leftTransition, 10); font->DrawString(_("Total colored manasymbols in lands' production:"), 20 + leftTransition, 30); @@ -1155,25 +1020,25 @@ void GameStateDeckViewer::renderOnScreenMenu() totalProducedSymbols = 0; for (int i = 1; i < Constants::NB_Colors - 1; i++) { - totalProducedSymbols += stw->countLandsPerColor[i] + stw->countBasicLandsPerColor[i]; //!! Move to updatestats! + totalProducedSymbols += mStatsWrapper->countLandsPerColor[i] + mStatsWrapper->countBasicLandsPerColor[i]; //!! Move to updatestats! } posY = 50; for (int i = 1; i < Constants::NB_Colors - 1; i++) { - if (stw->countLandsPerColor[i] + stw->countBasicLandsPerColor[i] > 0) + if (mStatsWrapper->countLandsPerColor[i] + mStatsWrapper->countBasicLandsPerColor[i] > 0) { - sprintf(buffer, _("%i").c_str(), stw->countLandsPerColor[i] + stw->countBasicLandsPerColor[i]); + sprintf(buffer, _("%i").c_str(), mStatsWrapper->countLandsPerColor[i] + mStatsWrapper->countBasicLandsPerColor[i]); font->DrawString(buffer, 20 + leftTransition, posY); - sprintf(buffer, _("(%i%%)").c_str(), (int) (100 * (float) (stw->countLandsPerColor[i] - + stw->countBasicLandsPerColor[i]) / totalProducedSymbols)); + sprintf(buffer, _("(%i%%)").c_str(), (int) (100 * (float) (mStatsWrapper->countLandsPerColor[i] + + mStatsWrapper->countBasicLandsPerColor[i]) / totalProducedSymbols)); font->DrawString(buffer, 33 + leftTransition, posY); posX = 72; - for (int j = 0; j < stw->countLandsPerColor[i] + stw->countBasicLandsPerColor[i]; j++) + for (int j = 0; j < mStatsWrapper->countLandsPerColor[i] + mStatsWrapper->countBasicLandsPerColor[i]; j++) { r->RenderQuad(mIcons[i].get(), posX + leftTransition, posY + 6, 0, 0.5, 0.5); posX += ((j + 1) % 10 == 0) ? 17 : 13; - if ((((j + 1) % 30) == 0) && (j < stw->countLandsPerColor[i] + stw->countBasicLandsPerColor[i] - 1)) + if ((((j + 1) % 30) == 0) && (j < mStatsWrapper->countLandsPerColor[i] + mStatsWrapper->countBasicLandsPerColor[i] - 1)) { posX = 72; posY += 15; @@ -1192,34 +1057,34 @@ void GameStateDeckViewer::renderOnScreenMenu() int (*countPerCostAndColor)[Constants::STATS_MAX_MANA_COST + 1][Constants::MTG_NB_COLORS + 1]; float avgCost; - switch (stw->currentPage) + switch (mStatsWrapper->currentPage) { // Nested switch on the same variable. Oh yes. case 2: // Total counts // Title - sprintf(buffer, STATS_TITLE_FORMAT.c_str(), stw->currentPage, _("Mana cost detail").c_str()); + sprintf(buffer, STATS_TITLE_FORMAT.c_str(), mStatsWrapper->currentPage, _("Mana cost detail").c_str()); font->DrawString(buffer, 10 + leftTransition, 10); font->DrawString(_("Card counts per mana cost:"), 20 + leftTransition, 30); - avgCost = stw->avgManaCost; - countPerCost = &stw->countCardsPerCost; - countPerCostAndColor = &stw->countCardsPerCostAndColor; + avgCost = mStatsWrapper->avgManaCost; + countPerCost = &mStatsWrapper->countCardsPerCost; + countPerCostAndColor = &mStatsWrapper->countCardsPerCostAndColor; break; case 3: // Creature counts // Title - sprintf(buffer, STATS_TITLE_FORMAT.c_str(), stw->currentPage, _("Mana cost detail - Creatures").c_str()); + sprintf(buffer, STATS_TITLE_FORMAT.c_str(), mStatsWrapper->currentPage, _("Mana cost detail - Creatures").c_str()); font->DrawString(buffer, 10 + leftTransition, 10); font->DrawString(_("Creature counts per mana cost:"), 20 + leftTransition, 30); - avgCost = stw->avgCreatureCost; - countPerCost = &stw->countCreaturesPerCost; - countPerCostAndColor = &stw->countCreaturesPerCostAndColor; + avgCost = mStatsWrapper->avgCreatureCost; + countPerCost = &mStatsWrapper->countCreaturesPerCost; + countPerCostAndColor = &mStatsWrapper->countCreaturesPerCostAndColor; break; case 4: // Spell counts // Title - sprintf(buffer, STATS_TITLE_FORMAT.c_str(), stw->currentPage, _("Mana cost detail - Spells").c_str()); + sprintf(buffer, STATS_TITLE_FORMAT.c_str(), mStatsWrapper->currentPage, _("Mana cost detail - Spells").c_str()); font->DrawString(buffer, 10 + leftTransition, 10); font->DrawString(_("Non-creature spell counts per mana cost:"), 20 + leftTransition, 30); - avgCost = stw->avgSpellCost; - countPerCost = &stw->countSpellsPerCost; - countPerCostAndColor = &stw->countSpellsPerCostAndColor; + avgCost = mStatsWrapper->avgSpellCost; + countPerCost = &mStatsWrapper->countSpellsPerCost; + countPerCostAndColor = &mStatsWrapper->countSpellsPerCostAndColor; break; default: countPerCost = NULL; @@ -1241,22 +1106,22 @@ void GameStateDeckViewer::renderOnScreenMenu() // Horizontal table lines r->DrawLine(27 + leftTransition, posY - 20, 75 + (Constants::NB_Colors - 2) * 15 + leftTransition, posY - 20, - ARGB(128, 255, 255, 255)); + ARGB(128, 255, 255, 255)); r->DrawLine(27 + leftTransition, posY - 1, 75 + (Constants::NB_Colors - 2) * 15 + leftTransition, posY - 1, - ARGB(128, 255, 255, 255)); + ARGB(128, 255, 255, 255)); r->DrawLine(27 + leftTransition, Constants::STATS_MAX_MANA_COST * 10 + posY + 12, 75 + (Constants::NB_Colors - 2) - * 15 + leftTransition, Constants::STATS_MAX_MANA_COST * 10 + posY + 12, ARGB(128, 255, 255, 255)); + * 15 + leftTransition, Constants::STATS_MAX_MANA_COST * 10 + posY + 12, ARGB(128, 255, 255, 255)); // Vertical table lines r->DrawLine(26 + leftTransition, posY - 20, 26 + leftTransition, Constants::STATS_MAX_MANA_COST * 10 + posY + 12, - ARGB(128, 255, 255, 255)); + ARGB(128, 255, 255, 255)); r->DrawLine(41 + leftTransition, posY - 20, 41 + leftTransition, Constants::STATS_MAX_MANA_COST * 10 + posY + 12, - ARGB(128, 255, 255, 255)); + ARGB(128, 255, 255, 255)); r->DrawLine(58 + leftTransition, posY - 20, 58 + leftTransition, Constants::STATS_MAX_MANA_COST * 10 + posY + 12, - ARGB(128, 255, 255, 255)); + ARGB(128, 255, 255, 255)); r->DrawLine(75 + leftTransition + (Constants::NB_Colors - 2) * 15, posY - 20, 75 + leftTransition - + (Constants::NB_Colors - 2) * 15, Constants::STATS_MAX_MANA_COST * 10 + posY + 12, - ARGB(128, 255, 255, 255)); + + (Constants::NB_Colors - 2) * 15, Constants::STATS_MAX_MANA_COST * 10 + posY + 12, + ARGB(128, 255, 255, 255)); for (int i = 0; i <= Constants::STATS_MAX_MANA_COST; i++) { @@ -1270,7 +1135,7 @@ void GameStateDeckViewer::renderOnScreenMenu() font->DrawString(buffer, 64 + leftTransition + j * 15, posY); } r->FillRect(77.f + leftTransition + (Constants::NB_Colors - 2) * 15.0f, posY + 2.0f, (*countPerCost)[i] * 5.0f, - 8.0f, graphColor); + 8.0f, graphColor); posY += 10; } @@ -1288,13 +1153,13 @@ void GameStateDeckViewer::renderOnScreenMenu() case 8: // Title - sprintf(buffer, STATS_TITLE_FORMAT.c_str(), stw->currentPage, _("Probabilities").c_str()); + sprintf(buffer, STATS_TITLE_FORMAT.c_str(), mStatsWrapper->currentPage, _("Probabilities").c_str()); font->DrawString(buffer, 10 + leftTransition, 10); // No lands detail float graphScale, graphWidth; graphWidth = 100; - graphScale = (stw->noLandsProbInTurn[0] == 0) ? 0 : (graphWidth / stw->noLandsProbInTurn[0]); + graphScale = (mStatsWrapper->noLandsProbInTurn[0] == 0) ? 0 : (graphWidth / mStatsWrapper->noLandsProbInTurn[0]); font->DrawString(_("No lands in first n cards:"), 20 + leftTransition, 30); posY = 50; @@ -1302,9 +1167,9 @@ void GameStateDeckViewer::renderOnScreenMenu() { sprintf(buffer, _("%i:").c_str(), i + 7); font->DrawString(buffer, 30 + leftTransition, posY); - sprintf(buffer, _("%2.2f%%").c_str(), stw->noLandsProbInTurn[i]); + sprintf(buffer, _("%2.2f%%").c_str(), mStatsWrapper->noLandsProbInTurn[i]); font->DrawString(buffer, 45 + leftTransition, posY); - r->FillRect(84 + leftTransition, posY + 2, graphScale * stw->noLandsProbInTurn[i], 8, graphColor); + r->FillRect(84 + leftTransition, posY + 2, graphScale * mStatsWrapper->noLandsProbInTurn[i], 8, graphColor); posY += 10; } @@ -1312,15 +1177,15 @@ void GameStateDeckViewer::renderOnScreenMenu() posY += 10; font->DrawString(_("No creatures in first n cards:"), 20 + leftTransition, posY); posY += 20; - graphScale = (stw->noCreaturesProbInTurn[0] == 0) ? 0 : (graphWidth / stw->noCreaturesProbInTurn[0]); + graphScale = (mStatsWrapper->noCreaturesProbInTurn[0] == 0) ? 0 : (graphWidth / mStatsWrapper->noCreaturesProbInTurn[0]); for (int i = 0; i < Constants::STATS_FOR_TURNS; i++) { sprintf(buffer, _("%i:").c_str(), i + 7); font->DrawString(buffer, 30 + leftTransition, posY); - sprintf(buffer, _("%2.2f%%").c_str(), stw->noCreaturesProbInTurn[i]); + sprintf(buffer, _("%2.2f%%").c_str(), mStatsWrapper->noCreaturesProbInTurn[i]); font->DrawString(buffer, 45 + leftTransition, posY); - r->FillRect(84 + leftTransition, posY + 2, graphScale * stw->noCreaturesProbInTurn[i], 8, graphColor); + r->FillRect(84 + leftTransition, posY + 2, graphScale * mStatsWrapper->noCreaturesProbInTurn[i], 8, graphColor); posY += 10; } @@ -1328,7 +1193,7 @@ void GameStateDeckViewer::renderOnScreenMenu() case 7: // Total mana cost per color // Title - sprintf(buffer, STATS_TITLE_FORMAT.c_str(), stw->currentPage, _("Mana cost per color").c_str()); + sprintf(buffer, STATS_TITLE_FORMAT.c_str(), mStatsWrapper->currentPage, _("Mana cost per color").c_str()); font->DrawString(buffer, 10 + leftTransition, 10); font->DrawString(_("Total colored manasymbols in cards' casting costs:"), 20 + leftTransition, 30); @@ -1336,18 +1201,18 @@ void GameStateDeckViewer::renderOnScreenMenu() posY = 50; for (int i = 1; i < Constants::NB_Colors - 1; i++) { - if (stw->totalCostPerColor[i] > 0) + if (mStatsWrapper->totalCostPerColor[i] > 0) { - sprintf(buffer, _("%i").c_str(), stw->totalCostPerColor[i]); + sprintf(buffer, _("%i").c_str(), mStatsWrapper->totalCostPerColor[i]); font->DrawString(buffer, 20 + leftTransition, posY); - sprintf(buffer, _("(%i%%)").c_str(), (int) (100 * (float) stw->totalCostPerColor[i] / stw->totalColoredSymbols)); + sprintf(buffer, _("(%i%%)").c_str(), (int) (100 * (float) mStatsWrapper->totalCostPerColor[i] / mStatsWrapper->totalColoredSymbols)); font->DrawString(buffer, 33 + leftTransition, posY); posX = 72; - for (int j = 0; j < stw->totalCostPerColor[i]; j++) + for (int j = 0; j < mStatsWrapper->totalCostPerColor[i]; j++) { r->RenderQuad(mIcons[i].get(), posX + leftTransition, posY + 6, 0, 0.5, 0.5); posX += ((j + 1) % 10 == 0) ? 17 : 13; - if ((((j + 1) % 30) == 0) && (j < stw->totalCostPerColor[i] - 1)) + if ((((j + 1) % 30) == 0) && (j < mStatsWrapper->totalCostPerColor[i] - 1)) { posX = 72; posY += 15; @@ -1360,14 +1225,14 @@ void GameStateDeckViewer::renderOnScreenMenu() case 9: // Victory statistics // Title - sprintf(buffer, STATS_TITLE_FORMAT.c_str(), stw->currentPage, _("Victory statistics").c_str()); + sprintf(buffer, STATS_TITLE_FORMAT.c_str(), mStatsWrapper->currentPage, _("Victory statistics").c_str()); font->DrawString(buffer, 10 + leftTransition, 10); font->DrawString(_("Victories against AI:"), 20 + leftTransition, 30); - sprintf(buffer, _("Games played: %i").c_str(), stw->gamesPlayed); + sprintf(buffer, _("Games played: %i").c_str(), mStatsWrapper->gamesPlayed); font->DrawString(buffer, 20 + leftTransition, 45); - sprintf(buffer, _("Victory ratio: %i%%").c_str(), stw->percentVictories); + sprintf(buffer, _("Victory ratio: %i%%").c_str(), mStatsWrapper->percentVictories); font->DrawString(buffer, 20 + leftTransition, 55); int AIsPerColumn = 19; @@ -1375,13 +1240,13 @@ void GameStateDeckViewer::renderOnScreenMenu() posX = 20; // ToDo: Multiple pages when too many AI decks are present - for (int i = 0; i < (int) stw->aiDeckStats.size(); i++) + for (int i = 0; i < (int) mStatsWrapper->aiDeckStats.size(); i++) { - sprintf(buffer, _("%.14s").c_str(), stw->aiDeckNames.at(i).c_str()); + sprintf(buffer, _("%.14s").c_str(), mStatsWrapper->aiDeckNames.at(i).c_str()); font->DrawString(buffer, posX + (i < 2 * AIsPerColumn ? leftTransition : rightTransition), posY); - sprintf(buffer, _("%i/%i").c_str(), stw->aiDeckStats.at(i)->victories, stw->aiDeckStats.at(i)->nbgames); + sprintf(buffer, _("%i/%i").c_str(), mStatsWrapper->aiDeckStats.at(i)->victories, mStatsWrapper->aiDeckStats.at(i)->nbgames); font->DrawString(buffer, posX + (i < AIsPerColumn ? leftTransition : rightTransition) + 80, posY); - sprintf(buffer, _("%i%%").c_str(), stw->aiDeckStats.at(i)->percentVictories()); + sprintf(buffer, _("%i%%").c_str(), mStatsWrapper->aiDeckStats.at(i)->percentVictories()); font->DrawString(buffer, posX + (i < AIsPerColumn ? leftTransition : rightTransition) + 110, posY); posY += 10; if (((i + 1) % AIsPerColumn) == 0) @@ -1395,152 +1260,17 @@ void GameStateDeckViewer::renderOnScreenMenu() } } - -void GameStateDeckViewer::renderCard(int id, float rotation) -{ - WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); - MTGCard * card = cardIndex[id]; - - float max_scale = 0.96f; - float x_center_0 = 180; - float right_border = SCREEN_WIDTH + 180; - - float x_center = x_center_0 + cos((rotation + 8 - id) * M_PI / 12) * (right_border - x_center_0); - float scale = max_scale / 1.12f * cos((x_center - x_center_0) * 1.5f / (right_border - x_center_0)) + 0.2f * max_scale * cos( - cos((x_center - x_center_0) * 0.15f / (right_border - x_center_0))); - float x = x_center; // ; - - float y = (SCREEN_HEIGHT_F) / 2.0f + SCREEN_HEIGHT_F * mSlide * (scale + 0.2f); - - cardsCoordinates[id] = pair(x, y); - - int alpha = (int) (255 * (scale + 1.0 - max_scale)); - - if (!card) return; - - if (!WResourceManager::Instance()->IsThreaded()) - { - JQuadPtr backQuad = WResourceManager::Instance()->GetQuad(kGenericCardID); - JQuadPtr quad; - - int cacheError = CACHE_ERROR_NONE; - - if (!options[Options::DISABLECARDS].number) - { - quad = WResourceManager::Instance()->RetrieveCard(card, RETRIEVE_EXISTING); - cacheError = WResourceManager::Instance()->RetrieveError(); - if (!quad.get() && cacheError != CACHE_ERROR_404) - { - if (last_user_activity > (abs(2 - id) + 1) * NO_USER_ACTIVITY_SHOWCARD_DELAY) - quad = WResourceManager::Instance()->RetrieveCard(card); - else - { - quad = backQuad; - } - } - } - - if (quad.get()) - { - if (quad == backQuad) - { - quad->SetColor(ARGB(255,255,255,255)); - float _scale = scale * (285 / quad->mHeight); - JRenderer::GetInstance()->RenderQuad(quad.get(), x, y, 0.0f, _scale, _scale); - } - else - { - Pos pos = Pos(x, y, scale * 285 / 250, 0.0, 255); - CardGui::DrawCard(card, pos); - } - } - else - { - Pos pos = Pos(x, y, scale * 285 / 250, 0.0, 255); - CardGui::DrawCard(card, pos, DrawMode::kText); - } - } - else - { - int mode = !options[Options::DISABLECARDS].number ? DrawMode::kNormal : DrawMode::kText; - - Pos pos = Pos(x, y, scale * 285 / 250, 0.0, 255); - CardGui::DrawCard(card, pos, mode); - } - - int quadAlpha = alpha; - if (!displayed_deck->count(card)) quadAlpha /= 2; - quadAlpha = 255 - quadAlpha; - if (quadAlpha > 0) - { - JRenderer::GetInstance()->FillRect(x - scale * 100.0f, y - scale * 142.5f, scale * 200.0f, scale * 285.0f, - ARGB(quadAlpha,0,0,0)); - } - if (last_user_activity < 3) - { - int fontAlpha = alpha; - float qtY = y - 135 * scale; - float qtX = x + 40 * scale; - char buffer[4096]; - sprintf(buffer, "x%i", displayed_deck->count(card)); - WFont * font = mFont; - font->SetColor(ARGB(fontAlpha/2,0,0,0)); - JRenderer::GetInstance()->FillRect(qtX, qtY, font->GetStringWidth(buffer) + 6, 16, ARGB(fontAlpha/2,0,0,0)); - font->DrawString(buffer, qtX + 4, qtY + 4); - font->SetColor(ARGB(fontAlpha,255,255,255)); - font->DrawString(buffer, qtX + 2, qtY + 2); - font->SetColor(ARGB(255,255,255,255)); - } -} - -void GameStateDeckViewer::renderCard(int id) -{ - renderCard(id, 0); -} - void GameStateDeckViewer::Render() { setButtonState(false); - WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); + WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); JRenderer::GetInstance()->ClearScreen(ARGB(0,0,0,0)); - if (displayed_deck == myDeck && mStage != STAGE_MENU) - renderDeckBackground(); - int order[3] = { 1, 2, 3 }; - if (mRotation < 0.5 && mRotation > -0.5) - { - order[1] = 3; - order[2] = 2; - } - else if (mRotation < -0.5) - { - order[0] = 3; - order[2] = 1; - } + if (mView->deck() == myDeck && mStage != STAGE_MENU) + renderDeckBackground(); - // even though we want to draw the cards in a particular z order for layering, we want to prefetch them - // in a different order, ie the center card should appear first, then the adjacent ones - if (WResourceManager::Instance()->IsThreaded()) - { - WResourceManager::Instance()->RetrieveCard(cardIndex[0]); - WResourceManager::Instance()->RetrieveCard(cardIndex[3]); - WResourceManager::Instance()->RetrieveCard(cardIndex[4]); - WResourceManager::Instance()->RetrieveCard(cardIndex[2]); - WResourceManager::Instance()->RetrieveCard(cardIndex[5]); - WResourceManager::Instance()->RetrieveCard(cardIndex[1]); - WResourceManager::Instance()->RetrieveCard(cardIndex[6]); - } + mView->Render(); - renderCard(6, mRotation); - renderCard(5, mRotation); - renderCard(4, mRotation); - renderCard(0, mRotation); - - for (int i = 0; i < 3; i++) - { - renderCard(order[i], mRotation); - } - - if (displayed_deck->Size() > 0) + if (mView->deck()->Size() > 0) { setButtonState(true); renderSlideBar(); @@ -1567,12 +1297,12 @@ void GameStateDeckViewer::Render() if (mStage == STAGE_MENU) { setButtonState(false); - menu->Render(); + deckMenu->Render(); } if (subMenu) subMenu->Render(); - if (filterMenu && !filterMenu->isFinished()) + if (filterMenu && !filterMenu->isFinished()) { setButtonState(false); filterMenu->Render(); @@ -1586,21 +1316,21 @@ void GameStateDeckViewer::Render() int GameStateDeckViewer::loadDeck(int deckid) { - if (!stw) + if (!mStatsWrapper) { DeckManager *deckManager = DeckManager::GetInstance(); - stw = deckManager->getExtendedStatsForDeckId( deckid, MTGCollection(), false ); + mStatsWrapper = deckManager->getExtendedStatsForDeckId( deckid, MTGCollection(), false ); } - stw->currentPage = 0; - stw->pageCount = 9; - stw->needUpdate = true; + mStatsWrapper->currentPage = 0; + mStatsWrapper->pageCount = 9; + mStatsWrapper->needUpdate = true; if (!playerdata) playerdata = NEW PlayerData(MTGCollection()); SAFE_DELETE(myCollection); myCollection = NEW DeckDataWrapper(playerdata->collection); myCollection->Sort(WSrcCards::SORT_ALPHA); - displayed_deck = myCollection; + mView->SetDeck(myCollection); char deckname[256]; sprintf(deckname, "deck%i.txt", deckid); @@ -1644,7 +1374,7 @@ int GameStateDeckViewer::loadDeck(int deckid) myDeck->Sort(WSrcCards::SORT_ALPHA); SAFE_DELETE(filterMenu); rebuildFilters(); - loadIndexes(); + mView->reloadIndexes(); return 1; } @@ -1685,9 +1415,9 @@ void GameStateDeckViewer::ButtonPressed(int controllerId, int controlId) SAFE_DELETE(myCollection); myCollection = NEW DeckDataWrapper(playerdata->collection); myCollection->Sort(WSrcCards::SORT_ALPHA); - displayed_deck = myCollection; + mView->SetDeck(myCollection); rebuildFilters(); - loadIndexes(); + mView->reloadIndexes(); mStage = STAGE_WELCOME; break; } @@ -1760,18 +1490,19 @@ void GameStateDeckViewer::ButtonPressed(int controllerId, int controlId) { case MENU_ITEM_YES: { - MTGCard * card = cardIndex[2]; + MTGCard * card = mView->getActiveCard(); if (card) { int rnd = (rand() % 25); + int price = pricelist->getSellPrice(card); playerdata->credits += price; price = price - (rnd * price) / 100; pricelist->setPrice(card->getMTGId(), price); playerdata->collection->remove(card->getMTGId()); - displayed_deck->Remove(card, 1); - displayed_deck->validate(); - stw->needUpdate = true; - loadIndexes(); + mView->deck()->Remove(card, 1); + mView->deck()->validate(); + mStatsWrapper->needUpdate = true; + mView->reloadIndexes(); } } case MENU_ITEM_NO: @@ -1783,7 +1514,7 @@ void GameStateDeckViewer::ButtonPressed(int controllerId, int controlId) /* to keep actions consistent across the different platforms, we need to branch the way swipes are interpreted. iOS5 changes - the way a swipe moves a document on the page. swipe down is to simulate dragging the page down instead of moving down + the way a swipe moves a document on the page. swipe down is to simulate dragging the page down instead of moving down on a page. */ void GameStateDeckViewer::OnScroll(int inXVelocity, int inYVelocity) @@ -1798,25 +1529,20 @@ void GameStateDeckViewer::OnScroll(int inXVelocity, int inYVelocity) { if(abs(inXVelocity) > 300) { - //determine how many cards to move, the faster the velocity the more cards to move. - // the display is setup so that there is a max of 2 cards to the left and 7 cards to the right - // of the current card. + //FIXME: this 500 is a bit arbitrary int numCards = (magnitude / 500) % 8; - int offset = 0; - if ( (numCards == 0) && magnitude) numCards = 7; - if ( !flickRight) - { - if (numCards > 1) - offset = 0; - } - else - offset = 2 + numCards; - - mEngine->LeftClickedProcessed(); - mEngine->LeftClicked(static_cast(cardsCoordinates[offset].first), static_cast(cardsCoordinates[offset].second)); - mEngine->HoldKey_NoRepeat(JGE_BTN_OK); + mView->changePositionAnimated(flickRight ? numCards : - numCards); } } else - mEngine->HoldKey_NoRepeat(flickUp ? JGE_BTN_UP : JGE_BTN_DOWN); + { + if(abs(inYVelocity) > 300) + { + //FIXME: this 500 is a bit arbitrary + int numFilters = (magnitude / 500); + mView->changeFilterAnimated(flickUp ? numFilters : - numFilters); + } + } + + last_user_activity = 0; } diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index 35f57d66c..28763e02b 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -14,6 +14,7 @@ #include "Translate.h" #include "Rules.h" #include "ModRules.h" +#include "GameApp.h" #ifdef TESTSUITE #include "TestSuiteAI.h" @@ -795,7 +796,7 @@ void GameStateDuel::Update(float dt) if (game->didWin()) { - //the following section will be called only in a classic or demo gamemode and if a tournament or match with more then one game is activ + //the following section will be called only in a classic or demo gamemode and if a tournament or match with more than one game is activ if ( (mParent->gameType == GAME_TYPE_CLASSIC || mParent->gameType == GAME_TYPE_DEMO)&& mParent->players[1] == PLAYER_TYPE_CPU && (tournament->isTournament() || tournament->getGamesToPlay()>1 )) { setGamePhase(DUEL_STATE_SHOW_SCORE); diff --git a/projects/mtg/src/GameStateOptions.cpp b/projects/mtg/src/GameStateOptions.cpp index 981eee505..16decd052 100644 --- a/projects/mtg/src/GameStateOptions.cpp +++ b/projects/mtg/src/GameStateOptions.cpp @@ -215,34 +215,39 @@ void GameStateOptions::Render() const char * const CreditsText[] = { "Wagic, The Homebrew?! by Wololo", "", - "updates, new cards, and more on http://wololo.net/wagic", + "Updates, new cards, and more on http://wololo.net/wagic", "Many thanks to the people who help this project", "", "", - "Art: Ilya B, Julio, Jeck, J, Kaioshin, Lakeesha", + "Art:", + "Ilya B, Julio, Jeck, J, Kaioshin, Lakeesha", "Check themeinfo.txt for the full credits of each theme!", "", "Dev Team:", - "Abrasax, Almosthumane, Daddy32, DJardin, Dr.Solomat,", - "J, Jeck, kevlahnota, Leungclj, linshier, Mootpoint, Mnguyen,", - "Psyringe, Salmelo, Superhiro, Wololo, Yeshua, Zethfox", + "Abrasax, Almosthumane, Daddy32, DJardin, Dr.Solomat, J, Jeck,", + "kevlahnota, Leungclj, linshier, Mootpoint, Mnguyen, Psyringe,", + "Rolzad73, Salmelo, Superhiro, Wololo, Yeshua, Zethfox", "", "Music by Celestial Aeon Project, http://www.jamendo.com", "", - "Deck Builders: Abrasax, AzureKnight, colarchon", - "Excessum, Hehotfarv, Jeremy, Jog1118, JonyAS", - "Lachaux, Link17, Muddobbers, Nakano, Niegen", - "Kaioshin, Psyringe, r1c47, Superhiro, Szei", - "Thanatos02, Whismer, Wololo", + "Deck Builders:", + "Abrasax, AzureKnight, colarchon, Excessum, Hehotfarv,", + "Jeremy, Jog1118, JonyAS, Lachaux, Link17, Muddobbers,", + "Nakano, Niegen, Kaioshin, Psyringe, r1c47, Superhiro,", + "Szei, Thanatos02, Whismer, Wololo", "", "Thanks also go to Dr.Watson, Orine, Raphael, Sakya, Tyranid", "for their help.", "", "Thanks to everyone who contributes code/content on the forums!", "", - "Developed with the JGE++ Library (http://code.google.com/p/wagic)", + "", + "Source:", + "http://code.google.com/p/wagic (2009-2013)", + "https://github.com/WagicProject/wagic (2013- )", + "", + "Developed with the JGE++ Library", "SFX From www.soundsnap.com", - "", "", "This work is not related to or endorsed by Wizards of the Coast, Inc", diff --git a/projects/mtg/src/GameStateShop.cpp b/projects/mtg/src/GameStateShop.cpp index 2b780f5c7..84ca3f6e4 100644 --- a/projects/mtg/src/GameStateShop.cpp +++ b/projects/mtg/src/GameStateShop.cpp @@ -102,7 +102,6 @@ void GameStateShop::Start() bListCards = false; mTouched = false; mStage = STAGE_FADE_IN; - mElapsed = 0; needLoad = true; booster = NULL; srcCards = NEW WSrcUnlockedCards(0); @@ -259,8 +258,8 @@ void GameStateShop::cancelCard(int controlId) break; } price = price - (rnd * price) / 100; - if (price < pricelist->getPrice(c->getMTGId())) //filters have a tendancy to increase the price instead of lowering it! - pricelist->setPrice(c->getMTGId(), price); + if (price < pricelist->getPrice(c)) //filters have a tendancy to increase the price instead of lowering it! + pricelist->setPrice(c, price); //Prices do not immediately go down when you ignore something. return; } @@ -427,7 +426,7 @@ void GameStateShop::End() { save(); JRenderer::GetInstance()->EnableVSync(false); - mElapsed = 0; + SAFE_DELETE(shopMenu); SAFE_DELETE(bigDisplay); SAFE_DELETE(srcCards); @@ -469,9 +468,6 @@ void GameStateShop::Update(float dt) if (lightAlpha > 50) lightAlpha = 50; - if (mStage != STAGE_FADE_IN) - mElapsed += dt; - JButton btn; switch (mStage) { @@ -496,7 +492,7 @@ void GameStateShop::Update(float dt) } break; case STAGE_SHOP_TASKS: - if (menu) + if (menu && !menu->isClosed()) { menu->Update(dt); return; diff --git a/projects/mtg/src/GridDeckView.cpp b/projects/mtg/src/GridDeckView.cpp new file mode 100644 index 000000000..cfe750448 --- /dev/null +++ b/projects/mtg/src/GridDeckView.cpp @@ -0,0 +1,284 @@ +#include "GridDeckView.h" + +const float GridDeckView::scroll_animation_duration = 0.3f; +const float GridDeckView::slide_animation_duration = 0.6f; +const float GridDeckView::card_scale_small = 0.48f; +const float GridDeckView::card_scale_big = 0.7f; + +GridDeckView::GridDeckView() + : DeckView(16), mCols(8), mRows(2), mScrollOffset(0), mSlideOffset(0), + mScrollEasing(mScrollOffset), mSlideEasing(mSlideOffset), mCurrentSelection(-1), + mButtonMode(false) +{ + +} + +GridDeckView::~GridDeckView() +{ + +} + +void GridDeckView::Reset() +{ + mSlideEasing.finish(); + mScrollEasing.finish(); + + mCurrentSelection = 0; + mButtonMode = false; + + DeckView::Reset(); +} + +void GridDeckView::UpdateViewState(float dt) +{ + if(!mScrollEasing.finished()) + { + mScrollEasing.update(dt); + + if(mScrollOffset <= -1.0f) + { + changePosition(2); + moveSelection(-2, false); + mScrollEasing.translate(1.0f); + } + else if(mScrollOffset >= 1.0f) + { + changePosition(-2); + moveSelection(2, false); + mScrollEasing.translate(-1.0f); + } + + dirtyCardPos = true; + } + + if(!mSlideEasing.finished()) + { + mSlideEasing.update(dt); + + if(mSlideOffset < -1.0f) + { + mSlideEasing.translate(2.0f); + changeFilter(1); + } + else if(mSlideOffset > 1.0f) + { + mSlideEasing.translate(-2.0f); + changeFilter(-1); + } + + dirtyCardPos = true; + } +} + +void GridDeckView::UpdateCardPosition(int index) +{ + CardRep &rep = mCards[index]; + + int col = index / mRows; + int row = index % mRows; + float colWidth = SCREEN_WIDTH_F / (mCols - 3); + float rowHeight = SCREEN_HEIGHT_F / mRows; + + rep.x = (col + mScrollOffset) * colWidth - colWidth; + rep.y = row * rowHeight + mSlideOffset*SCREEN_HEIGHT + rowHeight/2; + + if(mCurrentSelection == index) + { + rep.scale = card_scale_big; + if(row == 0) + { + rep.y += rowHeight * (card_scale_big - card_scale_small); + } + else + { + rep.y -= rowHeight * (card_scale_big - card_scale_small); + } + } + else + { + rep.scale = card_scale_small; + } +} + +void GridDeckView::Render() +{ + int firstVisibleCard = 2; + int lastVisibleCard = mCards.size() - 2; + + if(!mScrollEasing.finished()) + { + if(mScrollEasing.delta_value > 0){ + firstVisibleCard = 0; + } + else + { + lastVisibleCard = mCards.size(); + } + } + + for(int i = firstVisibleCard; i < lastVisibleCard; ++i) + { + + if(mCurrentSelection != i) + { + if (WResourceManager::Instance()->IsThreaded()) + { + WResourceManager::Instance()->RetrieveCard(mCards[i].card, RETRIEVE_THUMB); + } + renderCard(i, 255, true); + } + else + { + if (WResourceManager::Instance()->IsThreaded()) + { + WResourceManager::Instance()->RetrieveCard(mCards[i].card); + } + } + } + + if(2 <= mCurrentSelection && mCurrentSelection < 12) + { + renderCard(mCurrentSelection, 255, false); + } +} + +bool GridDeckView::ButtonPressed(Buttons button) +{ + switch(button) + { + case JGE_BTN_LEFT: + if(mButtonMode && mScrollEasing.finished()) moveSelection(-2, true); + else if(!mButtonMode) changePositionAnimated(-1); + last_user_activity = 0; + break; + case JGE_BTN_RIGHT: + if(mButtonMode && mScrollEasing.finished()) moveSelection(2, true); + else if(!mButtonMode) changePositionAnimated(1); + last_user_activity = 0; + break; + case JGE_BTN_UP: + if(mButtonMode && mScrollEasing.finished()) moveSelection(-1, true); + else if(!mButtonMode) changeFilterAnimated(1); + last_user_activity = 0; + break; + case JGE_BTN_DOWN: + if(mButtonMode && mScrollEasing.finished()) moveSelection(1, true); + else if(!mButtonMode) changeFilterAnimated(-1); + last_user_activity = 0; + break; + case JGE_BTN_CTRL: + if(mButtonMode) + { + mButtonMode = false; + dirtyCardPos = true; + mCurrentSelection = -1; + } + else return false; + break; + default: + return false; + } + return true; +} + +MTGCard * GridDeckView::Click(int x, int y) +{ + int n = getCardIndexNextTo(x, y); + last_user_activity = 0; + mButtonMode = false; + + if(mScrollEasing.finished() && mSlideEasing.finished()) + { //clicked and no animations running + if(n == mCurrentSelection) + { + return getActiveCard(); + } + else if(n < 4) + { + changePositionAnimated(-1); + } + else if(n >= 12) + { + changePositionAnimated(1); + } + else + { + mCurrentSelection = n; + dirtyCardPos = true; + } + } + + return NULL; +} + +MTGCard * GridDeckView::Click() +{ + if(mScrollEasing.finished() && mSlideEasing.finished()) + { + MTGCard *active = getActiveCard(); + if(active != NULL) + { + return active; + } + else + { + mButtonMode = true; + dirtyCardPos = true; + mCurrentSelection = 4; + } + } + + return NULL; +} + +void GridDeckView::changePositionAnimated(int offset) +{ + if(mScrollEasing.finished()) + mScrollEasing.start(-1.0f * offset, scroll_animation_duration * abs(offset)); + last_user_activity = 0; +} + +void GridDeckView::changeFilterAnimated(int offset) +{ + if(mSlideEasing.finished()) + mSlideEasing.start(2.0f * offset, float(slide_animation_duration * abs(offset))); + last_user_activity = 0; +} + +MTGCard* GridDeckView::getActiveCard() +{ + if(mCurrentSelection >= 4 && mCurrentSelection < int(mCards.size())-4) + { + return mCards[mCurrentSelection].card; + } + else + { + return NULL; + } +} + +void GridDeckView::moveSelection(int offset, bool alignIfOutOfBounds) +{ + mCurrentSelection += offset; + + if(alignIfOutOfBounds) + { + if(mCurrentSelection < 4) + { + changePositionAnimated(-1); + } + else if(mCurrentSelection >= 12) + { + changePositionAnimated(1); + } + } + else + { + if(mCurrentSelection < 4 || mCurrentSelection >= 12) + { + mCurrentSelection = -1; + } + } + + dirtyCardPos = true; +} diff --git a/projects/mtg/src/GuiMana.cpp b/projects/mtg/src/GuiMana.cpp index 63d72936d..c4ca3d257 100644 --- a/projects/mtg/src/GuiMana.cpp +++ b/projects/mtg/src/GuiMana.cpp @@ -3,6 +3,7 @@ #include "GuiMana.h" #include "OptionItem.h" #include "Player.h" +#include "GameApp.h" //using std::cout; using std::endl; diff --git a/projects/mtg/src/GuiPhaseBar.cpp b/projects/mtg/src/GuiPhaseBar.cpp index 0accc8a08..f782c6518 100644 --- a/projects/mtg/src/GuiPhaseBar.cpp +++ b/projects/mtg/src/GuiPhaseBar.cpp @@ -24,26 +24,28 @@ }; */ +const float GuiPhaseBar::zoom_big = (float)(1.5 * 1.4); +const float GuiPhaseBar::zoom_small = 1.5; +const float GuiPhaseBar::step = M_PI/6.0f; + namespace { + //width and height of the phase symbol textures const float kWidth = 28; const float kHeight = kWidth; - const unsigned kPhases = 12; + const unsigned kPhases = NB_MTG_PHASES - 2; //there are two phases we do not show +} - const float ICONSCALE = 1.5; - const float CENTER = SCREEN_HEIGHT_F / 2 + 10; - - void DrawGlyph(JQuad* inQuad, int inGlyph, float inY, float, unsigned int inP, float inScale) - { - float xPos = static_cast ((inP + inGlyph * (int) (kWidth + 1)) % (kPhases * (int) (kWidth + 1))); - inQuad->SetTextureRect(xPos, 0, kWidth, kHeight); - JRenderer::GetInstance()->RenderQuad(inQuad, 0, inY, 0.0, inScale, inScale); - } +void GuiPhaseBar::DrawGlyph(JQuad *inQuad, int phaseId, float x, float y, float scale) +{ + inQuad->SetTextureRect(phaseId * (kWidth + 1), 0, kWidth, kHeight); + JRenderer::GetInstance()->RenderQuad(inQuad, x, y - scale * kWidth/2, 0.0f, scale, scale); } GuiPhaseBar::GuiPhaseBar(DuelLayers* duelLayers) : - GuiLayer(duelLayers->getObserver()), PlayGuiObject(0, 0, 106, 0, false), - phase(NULL), angle(0.0f), zoomFactor(ICONSCALE), mpDuelLayers(duelLayers) + GuiLayer(duelLayers->getObserver()), PlayGuiObject(80, 0, 106, 0, false), + displayedPhaseId(0), angle(0.0f), zoomFactor(zoom_small), angleEasing(angle), + zoomFactorEasing(zoomFactor), mpDuelLayers(duelLayers) { if(duelLayers->getObserver()->getResourceManager()) { @@ -57,10 +59,7 @@ GuiPhaseBar::GuiPhaseBar(DuelLayers* duelLayers) : GameApp::systemError = "Error loading phasebar texture : " __FILE__; } - - zoom = ICONSCALE; mpDuelLayers->getCardSelector()->Add(this); - } GuiPhaseBar::~GuiPhaseBar() @@ -69,32 +68,27 @@ GuiPhaseBar::~GuiPhaseBar() void GuiPhaseBar::Update(float dt) { - if (angle > 3 * dt) - angle -= 3 * dt; - else - angle = 0; + angleEasing.update(dt); - if (dt > 0.05f) dt = 0.05f; - if(zoomFactor + 0.05f < zoom) + if(angle <= -step) { - zoomFactor += dt; - } - else if (zoomFactor - 0.05f > zoom) - { - zoomFactor -= dt; + displayedPhaseId = (displayedPhaseId + 1) % kPhases; + angleEasing.translate(step); } + + zoomFactorEasing.update(dt); } void GuiPhaseBar::Entering() { mHasFocus = true; - zoom = 1.4f*ICONSCALE; + zoomFactorEasing.start(zoom_big, 0.3f); } bool GuiPhaseBar::Leaving(JButton) { mHasFocus = false; - zoom = ICONSCALE; + zoomFactorEasing.start(zoom_small, 0.6f); return true; } @@ -102,41 +96,28 @@ void GuiPhaseBar::Render() { JQuadPtr quad = WResourceManager::Instance()->GetQuad("phasebar"); //uncomment to draw a hideous line across hires screens. - // JRenderer::GetInstance()->DrawLine(0, CENTER, SCREEN_WIDTH, CENTER, ARGB(255, 255, 255, 255)); + // JRenderer::GetInstance()->DrawLine(0, CENTER, SCREEN_WIDTH, CENTER, ARGB(255, 255, 255, 255)); - unsigned int p = (phase->id + kPhases - 4) * (int) (kWidth + 1); - float centerYPosition = CENTER + (kWidth / 2) * angle * zoomFactor / (M_PI / 6) - zoomFactor * kWidth / 4; - float yPos = centerYPosition; - float scale = 0; - for (int glyph = 3; glyph < 6; ++glyph) - { - scale = zoomFactor * sinf(angle + glyph * M_PI / 6) / 2; - DrawGlyph(quad.get(), glyph, yPos, angle, p, scale); - yPos += kWidth * scale; - } + const float radius = 25 * zoomFactor; - yPos = centerYPosition; - for (int glyph = 2; glyph > 0; --glyph) + for(int i = 0; i < 6; ++i) { - scale = zoomFactor * sinf(angle + glyph * M_PI / 6) / 2; - yPos -= kWidth * scale; - DrawGlyph(quad.get(), glyph, yPos, angle, p, scale); - } + //the position of the glyphe in the circle + const float circPos = (i - 2) * step + angle; + const float glyphY = this->y + this->mHeight / 2 + sin(circPos) * radius; - if (angle > 0) - { - scale = zoomFactor * sinf(angle) / 2; - yPos -= kWidth * scale; - float xPos = static_cast (p % (kPhases * (int) (kWidth + 1))); - quad->SetTextureRect(xPos, kHeight, kWidth, kHeight); - JRenderer::GetInstance()->RenderQuad(quad.get(), 0, yPos, 0.0, scale, scale); + //the scale is computed so that the glyphes touch each other + //hint: sin(circPos + PI/2) = cos(circPos) + const float glyphScale = float(zoomFactor * cosf(circPos) * 0.5f); + + DrawGlyph(quad.get(), (displayedPhaseId - 2 + i + kPhases) % kPhases, 0, glyphY, glyphScale); } //print phase name WFont * font = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); string currentP = _("your turn"); string interrupt = ""; - if (observer->currentPlayer == mpDuelLayers->getRenderedPlayerOpponent()) + if (observer->currentPlayer == mpDuelLayers->getRenderedPlayerOpponent()) { currentP = _("opponent's turn"); } @@ -147,7 +128,7 @@ void GuiPhaseBar::Render() } if (observer->currentlyActing() != observer->currentPlayer) { - if (observer->currentPlayer == mpDuelLayers->getRenderedPlayer()) + if (observer->currentPlayer == mpDuelLayers->getRenderedPlayer()) { interrupt = _(" - ") + _("opponent plays"); } @@ -159,7 +140,9 @@ void GuiPhaseBar::Render() char buf[200]; //running this string through translate returns gibberish even though we defined the variables in the lang.txt - string phaseNameToTranslate = observer->phaseRing->phaseName(phase->id); + //the conversion from phase bar phases to mtg phases is x%kPhases + 1 + //todo: just to this when the displayedPhaseId updates + string phaseNameToTranslate = observer->phaseRing->phaseName(displayedPhaseId%kPhases + 1); phaseNameToTranslate = _(phaseNameToTranslate); sprintf(buf, _("(%s%s) %s").c_str(), currentP.c_str(), interrupt.c_str(),phaseNameToTranslate.c_str()); font->DrawString(buf, SCREEN_WIDTH - 5, 2, JGETEXT_RIGHT); @@ -170,8 +153,20 @@ int GuiPhaseBar::receiveEventMinus(WEvent *e) WEventPhaseChange *event = dynamic_cast (e); if (event) { - angle = M_PI / 6; - phase = event->to; + //convert the mtg phase to the phases of the phase wheel + //the mapping is + //0 -> none + //1..12 -> 0..11 + //13 -> none + int targetPhase = event->to->id; + + if(targetPhase != 0 && targetPhase != 13) + { + targetPhase -= 1; + + int phasesToAnimate = (targetPhase - displayedPhaseId + kPhases) % kPhases; + angleEasing.start(float(phasesToAnimate * (- step)), 0.3f * float(sqrt(float(phasesToAnimate)))); + } } return 1; } diff --git a/projects/mtg/src/GuiPlay.cpp b/projects/mtg/src/GuiPlay.cpp index 183bd581f..0ab99501d 100644 --- a/projects/mtg/src/GuiPlay.cpp +++ b/projects/mtg/src/GuiPlay.cpp @@ -103,7 +103,7 @@ inline float GuiPlay::VertStack::nextX() } GuiPlay::BattleField::BattleField() : - attackers(0), blockers(0), height(0.0), red(0), colorFlow(0) + attackers(0), height(0.0), red(0), colorFlow(0) { } const float GuiPlay::BattleField::HEIGHT = 80.0f; diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 022efba29..ca1a4b5ab 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1039,6 +1039,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG observer->addObserver(NEW MTGMorphCostRule(observer, -1)); return NULL; } + found = s.find("playfromgraveyardrule"); + if(found != string::npos) + { + observer->addObserver(NEW MTGPlayFromGraveyardRule(observer, -1)); + return NULL; + } //this rule handles attacking ability during attacker phase found = s.find("attackrule"); if(found != string::npos) @@ -4270,8 +4276,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell) if (card->hasType(Subtypes::TYPE_INSTANT) || card->hasType(Subtypes::TYPE_SORCERY)) { MTGPlayerCards * zones = card->owner->game; - if(card->getCurrentZone()) - card->currentZone->owner->game;//grab it from where ever it is. MTGPlayerCards * Endzones = card->owner->game;//put them in thier owners respective zones as per rules. if (card->basicAbilities[(int)Constants::EXILEDEATH]) { diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index e70320ae4..b957afa0c 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -158,6 +158,7 @@ void MTGCardInstance::initMTGCI() auras = 0; damageToOpponent = false; damageToController = false; + damageToCreature = false; wasDealtDamage = false; isDualWielding = false; suspended = false; diff --git a/projects/mtg/src/MTGDefinitions.cpp b/projects/mtg/src/MTGDefinitions.cpp index eaecce696..3161c3749 100644 --- a/projects/mtg/src/MTGDefinitions.cpp +++ b/projects/mtg/src/MTGDefinitions.cpp @@ -131,7 +131,8 @@ const char* Constants::MTGBasicAbilities[] = { "poisondamager",//deals damage to players as poison counters. "soulbond", "lure", - "nolegend" + "nolegend", + "canplayfromgraveyard" }; map Constants::MTGBasicAbilitiesMap; diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index b3ba2cd86..0c6e9ec10 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -146,7 +146,7 @@ int MTGEventBonus::receiveEvent(WEvent * event) } //////bonus for having a LOT of specific type. //not else'd becuase it is possible for a card to contain - //more then one of the types, and for more then one to trigger. + //more than one of the types, and for more than one to trigger. if(e->card->hasType(Subtypes::TYPE_ARTIFACT)) toys[currentPlayer->getId()]++; if(e->card->isCreature()) @@ -273,6 +273,7 @@ MTGEventBonus * MTGEventBonus::clone() const { return NEW MTGEventBonus(*this); } + MTGPutInPlayRule::MTGPutInPlayRule(GameObserver* observer, int _id) : PermanentAbility(observer, _id) { @@ -716,7 +717,6 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter copy->alternateCostPaid[alternateCostType] = 1; spell->resolve(); SAFE_DELETE(spell); - game->mLayers->stackLayer()->addSpell(copy, NULL, NULL, alternateCostType, 1); } else { @@ -1140,8 +1140,49 @@ MTGMorphCostRule * MTGMorphCostRule::clone() const //------------------------------------------------------------------------- //------------------------------------------------------------------------- +MTGPlayFromGraveyardRule::MTGPlayFromGraveyardRule(GameObserver* observer, int _id) : +MTGAlternativeCostRule(observer, _id) +{ + aType = MTGAbility::PUT_INTO_PLAY; +} +int MTGPlayFromGraveyardRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) +{ + Player * player = game->currentlyActing(); + ManaCost * cost = card->getManaCost(); + if (!player->game->graveyard->hasCard(card)) + return 0; + if (!card->has(Constants::CANPLAYFROMGRAVEYARD)) + return 0; + + return MTGAlternativeCostRule::isReactingToClick(card, mana, cost); +} + +int MTGPlayFromGraveyardRule::reactToClick(MTGCardInstance * card) +{ + if (!isReactingToClick(card)) + return 0; + + ManaCost * cost = card->getManaCost(); + + card->paymenttype = MTGAbility::PUT_INTO_PLAY; + + return MTGAlternativeCostRule::reactToClick(card, cost, ManaCost::MANA_PAID); +} + +ostream& MTGPlayFromGraveyardRule::toString(ostream& out) const +{ + out << "MTGPlayFromGraveyardRule ::: ("; + return MTGAbility::toString(out) << ")"; +} + +MTGPlayFromGraveyardRule * MTGPlayFromGraveyardRule::clone() const +{ + return NEW MTGPlayFromGraveyardRule(*this); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// bool MTGAttackRule::select(Target* t) { diff --git a/projects/mtg/src/OptionItem.cpp b/projects/mtg/src/OptionItem.cpp index df9edceab..4fee0a0ea 100644 --- a/projects/mtg/src/OptionItem.cpp +++ b/projects/mtg/src/OptionItem.cpp @@ -7,6 +7,7 @@ #include "TranslateKeys.h" #include "StyleManager.h" #include +#include "SimpleMenu.h" //OptionItem OptionItem::OptionItem(int _id, string _displayValue) : diff --git a/projects/mtg/src/PriceList.cpp b/projects/mtg/src/PriceList.cpp index 4e25d9c73..3586af28c 100644 --- a/projects/mtg/src/PriceList.cpp +++ b/projects/mtg/src/PriceList.cpp @@ -47,12 +47,12 @@ int PriceList::save() return 1; } -int PriceList::getPrice(int cardId) +int PriceList::getPrice(MTGCard * card) { - map::iterator it = prices.find(cardId); + map::iterator it = prices.find(card->getId()); if (it != prices.end()) return (*it).second; - char rarity = collection->getCardById(cardId)->getRarity(); + char rarity = card->getRarity(); switch (rarity) { case Constants::RARITY_M: @@ -77,7 +77,11 @@ int PriceList::getPrice(int cardId) return Constants::PRICE_1C; break; } +} +int PriceList::getPrice(int cardId) +{ + return getPrice(collection->getCardById(cardId)); } int PriceList::setPrice(int cardId, int price) @@ -85,10 +89,23 @@ int PriceList::setPrice(int cardId, int price) prices[cardId] = price; return price; } + +int PriceList::setPrice(MTGCard * card, int price) +{ + prices[card->getId()] = price; + return price; +} + int PriceList::getSellPrice(int cardid) { - return getPrice(cardid); + return getPrice(collection->getCardById(cardid)); } + +int PriceList::getSellPrice(MTGCard *card) +{ + return getPrice(card); +} + float PriceList::difficultyScalar(float price, int cardid) { float badluck = (float) (abs(cardid + randomKey) % 201) / 100; //Float between 0 and 2. diff --git a/projects/mtg/src/Rules.cpp b/projects/mtg/src/Rules.cpp index 54f051b46..bfdcd0cfb 100644 --- a/projects/mtg/src/Rules.cpp +++ b/projects/mtg/src/Rules.cpp @@ -6,6 +6,7 @@ #include "Player.h" #include "AIMomirPlayer.h" +#include "GameApp.h" #include "MTGGameZones.h" #include "MTGAbility.h" #include "AllAbilities.h" diff --git a/projects/mtg/src/SimplePopup.cpp b/projects/mtg/src/SimplePopup.cpp index b994d9c61..e8cccf5e4 100644 --- a/projects/mtg/src/SimplePopup.cpp +++ b/projects/mtg/src/SimplePopup.cpp @@ -15,7 +15,7 @@ #include SimplePopup::SimplePopup(int id, JGuiListener* listener, const int fontId, const char * _title, DeckMetaData* deckMetaData, MTGAllCards * collection, float cancelX, float cancelY) : - JGuiController(JGE::GetInstance(), id, listener), mFontId(fontId), mCollection(collection) + JGuiController(JGE::GetInstance(), id, listener), mCollection(collection) { mX = 19; mY = 66; diff --git a/projects/mtg/src/StoryFlow.cpp b/projects/mtg/src/StoryFlow.cpp index e9bc6da6a..572dc4f76 100644 --- a/projects/mtg/src/StoryFlow.cpp +++ b/projects/mtg/src/StoryFlow.cpp @@ -13,6 +13,7 @@ #include "PlayerData.h" #include "MTGDeck.h" #include "WFont.h" +#include "GameApp.h" #include #define LINE_SPACE 2 diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 2e73f23e4..e69f29702 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -485,6 +485,18 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta cd->CDcontrollerDamaged = 1; } } + //creature dealt damage to anything + else if (attribute.find("damager") != string::npos) + { + if (minus) + { + cd->CDdamager = -1; + } + else + { + cd->CDdamager = 1; + } + } else if (attribute.find("multicolor") != string::npos) { //card is multicolored? diff --git a/projects/mtg/src/Tasks.cpp b/projects/mtg/src/Tasks.cpp index eca12e80e..1161582dd 100644 --- a/projects/mtg/src/Tasks.cpp +++ b/projects/mtg/src/Tasks.cpp @@ -258,9 +258,10 @@ Task* Task::createFromStr(const string params, bool rand) /*---------------- TaskList -----------------*/ -TaskList::TaskList(string _fileName) +TaskList::TaskList(string _fileName): + fileName(_fileName), vPos(-SCREEN_HEIGHT), vPosInEasing(vPos), vPosOutEasing(vPos) { - fileName = _fileName; + if (fileName == "") { fileName = options.profileFile(PLAYER_TASKS).c_str(); @@ -378,9 +379,10 @@ void TaskList::removeTask(Task *task) void TaskList::Start() { - vPos = -SCREEN_HEIGHT; //Offscreen - mElapsed = 0; mState = TASKS_IN; + vPos = -SCREEN_HEIGHT; //Offscreen + vPosInEasing.start(0.0f, 1.0f); + if (!mBgTex) { mBgTex = WResourceManager::Instance()->RetrieveTexture("taskboard.png", RETRIEVE_LOCK); @@ -410,7 +412,7 @@ void TaskList::Start() void TaskList::End() { mState = TASKS_OUT; - mElapsed = 0; + vPosOutEasing.start(float(-SCREEN_HEIGHT), 0.9f); } void TaskList::passOneDay() @@ -451,21 +453,23 @@ int TaskList::getTaskCount() void TaskList::Update(float dt) { - mElapsed += dt; - - if (mState == TASKS_IN && vPos < 0) + if(!vPosInEasing.finished()) { - vPos = -SCREEN_HEIGHT + (SCREEN_HEIGHT * mElapsed / 0.75f); //Todo: more physical drop-in. - if (vPos >= 0) + vPosInEasing.update(dt); + + if(vPosInEasing.finished()) { - vPos = 0; mState = TaskList::TASKS_ACTIVE; } } - else if (mState == TASKS_OUT && vPos > -SCREEN_HEIGHT) + else if(!vPosOutEasing.finished()) { - vPos = -(SCREEN_HEIGHT * mElapsed / 0.75f); - if (vPos <= -SCREEN_HEIGHT) mState = TASKS_INACTIVE; + vPosOutEasing.update(dt); + + if(vPosOutEasing.finished()) + { + mState = TASKS_INACTIVE; + } } } diff --git a/projects/mtg/src/WGui.cpp b/projects/mtg/src/WGui.cpp index 234b2c5a2..4a1308f1b 100644 --- a/projects/mtg/src/WGui.cpp +++ b/projects/mtg/src/WGui.cpp @@ -6,6 +6,9 @@ #include "Subtypes.h" #include "TranslateKeys.h" #include +#include "SimpleMenu.h" +#include "Pos.h" +#include "CardGui.h" /** Provides an interface to retrieve some standardized colors. The idea here is that a child of WGuiBase diff --git a/projects/mtg/template.vcxproj b/projects/mtg/template.vcxproj index 42557bfff..74ceda7ba 100644 --- a/projects/mtg/template.vcxproj +++ b/projects/mtg/template.vcxproj @@ -319,6 +319,12 @@ + + NotUsing + NotUsing + NotUsing + NotUsing + @@ -330,6 +336,12 @@ + + NotUsing + NotUsing + NotUsing + NotUsing + @@ -363,6 +375,12 @@ + + NotUsing + NotUsing + NotUsing + NotUsing + @@ -461,6 +479,7 @@ + @@ -473,7 +492,9 @@ + + @@ -488,6 +509,7 @@ + diff --git a/projects/mtg/template.vcxproj.filters b/projects/mtg/template.vcxproj.filters index 8ea808e4d..0f1a9e0d0 100644 --- a/projects/mtg/template.vcxproj.filters +++ b/projects/mtg/template.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -334,6 +334,15 @@ src + + src + + + src + + + src + @@ -687,6 +696,18 @@ inc + + inc + + + inc + + + inc + + + inc + diff --git a/projects/mtg/wagic-SDL.pro b/projects/mtg/wagic-SDL.pro index a1580106d..39be85527 100644 --- a/projects/mtg/wagic-SDL.pro +++ b/projects/mtg/wagic-SDL.pro @@ -1,39 +1,19 @@ #------------------------------------------------- +#------------------------------------------------- + +include(wagic.pri) + +DEFINES += SDL_CONFIG # # Project created by QtCreator 2010-06-30T19:48:30 # -#------------------------------------------------- +QT -= core gui opengl network declarative -#QT += core gui opengl network -macx:QT += phonon -#CONFIG += warn_off precompile_header // causes some massives errors on mac. -VERSION = 0.14.1 -TARGET = wagic -TEMPLATE = app -unix|macx:QMAKE_CXXFLAGS += -Wno-unused-parameter -windows:DEFINES += WIN32 -windows:DEFINES += _CRT_SECURE_NO_WARNINGS -unix|macx:DEFINES += LINUX -CONFIG(debug, debug|release):DEFINES += _DEBUG -#DEFINES += QT_CONFIG -#DEFINES += NETWORK_SUPPORT -DEFINES += SDL_CONFIG -DEFINES += TIXML_USE_STL -macx:DEFINES += USE_PHONON -maemo5: { -DEFINES += USE_PHONON -QT += phonon dbus -} -windows:INCLUDEPATH += ../../JGE/Dependencies/include -windows:INCLUDEPATH += ../../JGE/Dependencies/SDL/include -windows:INCLUDEPATH += extra +#unix|windows:QMAKE_CXXFLAGS += -std=c++11 + +INCLUDEPATH += ../../JGE/Dependencies/SDL/include unix:INCLUDEPATH += /usr/include/GL unix:INCLUDEPATH += /usr/local/include/SDL -macx:INCLUDEPATH += /opt/include -INCLUDEPATH += ../../JGE/include -INCLUDEPATH += ../../JGE/src/zipFS -INCLUDEPATH += ../../Boost -INCLUDEPATH += include OBJECTS_DIR = objs MOC_DIR = objs DESTDIR = bin @@ -42,358 +22,246 @@ macx|unix:LIBS += -lz -lboost_thread-mt unix:LIBS += -ljpeg -lgif -lpng12 -L/usr/local/lib -lGL -lGLU -lSDL windows:LIBS += -L../../JGE/Dependencies/lib -L../../Boost/lib -llibjpeg-static-mt-debug -lgiflib -llibpng -lfmodvc -PRECOMPILED_HEADER = include/PrecompiledHeader.h - -# MGT -SOURCES += \ - src/AbilityParser.cpp\ - src/ActionElement.cpp\ - src/ActionLayer.cpp\ - src/ActionStack.cpp\ - src/AIHints.cpp\ - src/AIMomirPlayer.cpp\ - src/AIPlayer.cpp\ - src/AIPlayerBaka.cpp\ - src/AIStats.cpp\ - src/AllAbilities.cpp\ - src/CardDescriptor.cpp\ - src/CardDisplay.cpp\ - src/CardEffect.cpp\ - src/CardGui.cpp\ - src/CardPrimitive.cpp\ - src/CardSelector.cpp\ - src/CardSelectorSingleton.cpp\ - src/Closest.cpp\ - src/Counters.cpp\ - src/Credits.cpp\ - src/Damage.cpp\ - src/DamagerDamaged.cpp\ - src/DeckDataWrapper.cpp\ - src/DeckEditorMenu.cpp\ - src/DeckManager.cpp\ - src/DeckMenu.cpp\ - src/DeckMenuItem.cpp\ - src/DeckMetaData.cpp\ - src/DeckStats.cpp\ - src/DuelLayers.cpp\ - src/Effects.cpp\ - src/ExtraCost.cpp\ - src/GameApp.cpp\ - src/GameLauncher.cpp\ - src/GameObserver.cpp\ - src/GameOptions.cpp\ - src/GameStateAwards.cpp\ - src/GameState.cpp\ - src/GameStateDeckViewer.cpp\ - src/GameStateDuel.cpp\ - src/GameStateMenu.cpp\ - src/GameStateOptions.cpp\ - src/GameStateShop.cpp\ - src/GameStateStory.cpp\ - src/GameStateTransitions.cpp\ - src/GuiAvatars.cpp\ - src/GuiBackground.cpp\ - src/GuiCardsController.cpp\ - src/GuiCombat.cpp\ - src/GuiFrame.cpp\ - src/GuiHand.cpp\ - src/GuiLayers.cpp\ - src/GuiMana.cpp\ - src/GuiPhaseBar.cpp\ - src/GuiPlay.cpp\ - src/GuiStatic.cpp\ - src/IconButton.cpp\ - src/ManaCost.cpp\ - src/ManaCostHybrid.cpp\ - src/MenuItem.cpp\ - src/ModRules.cpp\ - src/MTGAbility.cpp\ - src/MTGCard.cpp\ - src/MTGCardInstance.cpp\ - src/MTGDeck.cpp\ - src/MTGDefinitions.cpp\ - src/MTGGamePhase.cpp\ - src/MTGGameZones.cpp\ - src/MTGPack.cpp\ - src/MTGRules.cpp\ - src/ObjectAnalytics.cpp\ - src/OptionItem.cpp\ - src/PhaseRing.cpp\ - src/Player.cpp\ - src/PlayerData.cpp\ - src/PlayGuiObject.cpp\ - src/PlayGuiObjectController.cpp\ - src/PlayRestrictions.cpp\ - src/Pos.cpp\ - src/PriceList.cpp\ - src/ReplacementEffects.cpp\ - src/Rules.cpp\ - src/SimpleMenu.cpp\ - src/SimpleMenuItem.cpp\ - src/SimplePad.cpp\ - src/SimplePopup.cpp\ - src/StoryFlow.cpp\ - src/Subtypes.cpp\ - src/StyleManager.cpp\ - src/TargetChooser.cpp\ - src/TargetsList.cpp\ - src/Tasks.cpp\ - src/TextScroller.cpp\ - src/ThisDescriptor.cpp\ - src/Token.cpp\ - src/Translate.cpp\ - src/TranslateKeys.cpp\ - src/Trash.cpp\ - src/utils.cpp\ - src/WCachedResource.cpp\ - src/WDataSrc.cpp\ - src/WEvent.cpp\ - src/WFilter.cpp\ - src/WFont.cpp\ - src/WGui.cpp\ - src/WResourceManager.cpp\ - src/NetworkPlayer.cpp - CONFIG(debug, debug|release):SOURCES += src/TestSuiteAI.cpp -HEADERS += \ - include/AllAbilities.h\ - include/DeckMenu.h\ - include/DeckMenuItem.h\ - include/ExtraCost.h\ - include/ManaCost.h\ - include/SimpleMenuItem.h\ - include/GameApp.h\ - include/ManaCostHybrid.h\ - include/SimplePad.h\ - include/ActionElement.h\ - include/GameObserver.h\ - include/MenuItem.h\ - include/StoryFlow.h\ - include/ActionLayer.h\ - include/GameOptions.h\ - include/MTGAbility.h\ - include/Subtypes.h\ - include/ActionStack.h\ - include/GameStateAwards.h\ - include/MTGCard.h\ - include/AIMomirPlayer.h\ - include/GameStateDeckViewer.h\ - include/MTGCardInstance.h\ - include/Targetable.h\ - include/AIPlayer.h\ - include/GameStateDuel.h\ - include/MTGDeck.h\ - include/TargetChooser.h\ - include/AIStats.h\ - include/GameState.h\ - include/MTGDefinitions.h\ - include/TargetsList.h\ - include/AllAbilities.h\ - include/GameStateMenu.h\ - include/MTGGamePhase.h\ - include/Tasks.h\ - include/CardDescriptor.h\ - include/GameStateOptions.h\ - include/MTGGameZones.h\ - include/TestSuiteAI.h\ - include/CardDisplay.h\ - include/GameStateShop.h\ - include/MTGPack.h\ - include/TextScroller.h\ - include/CardEffect.h\ - include/GameStateStory.h\ - include/MTGRules.h\ - include/ThisDescriptor.h\ - include/CardGui.h\ - include/GameStateTransitions.h\ - include/IconButton.h\ - include/OptionItem.h\ - include/Token.h\ - include/CardPrimitive.h\ - include/GuiAvatars.h\ - include/OSD.h\ - include/Translate.h\ - include/CardSelector.h\ - include/CardSelectorSingleton.h\ - include/GuiBackground.h\ - include/PhaseRing.h\ - include/TranslateKeys.h\ - include/config.h\ - include/GuiCardsController.h\ - include/PlayerData.h\ - include/Trash.h\ - include/Counters.h\ - include/GuiCombat.h\ - include/Player.h\ - include/utils.h\ - include/Credits.h\ - include/GuiFrame.h\ - include/PlayGuiObjectController.h\ - include/WCachedResource.h\ - include/Damage.h\ - include/GuiHand.h\ - include/PlayGuiObject.h\ - include/WDataSrc.h\ - include/DamagerDamaged.h\ - include/GuiLayers.h\ - include/Pos.h\ - include/WEvent.h\ - include/DeckDataWrapper.h\ - include/GuiMana.h\ - include/PriceList.h\ - include/WFilter.h\ - include/DeckMetaData.h\ - include/GuiPhaseBar.h\ - include/ReplacementEffects.h\ - include/WGui.h\ - include/DeckStats.h\ - include/GuiPlay.h\ - include/Rules.h\ - include/WResourceManager.h\ - include/DuelLayers.h\ - include/GuiStatic.h\ - include/Effects.h\ - include/StyleManager.h\ - include/WFont.h\ - include/DeckManager.h\ - include/SimplePopup.h\ - include/SimpleMenu.h\ - include/PrecompiledHeader.h\ - include/Navigator.h\ - include/DeckEditorMenu.h\ - include/PlayRestrictions.h\ - include/NetworkPlayer.h\ - include/ModRules.h\ - include/AIHints.h\ - # JGE, could probably be moved outside SOURCES += \ ../../JGE/src/SDLmain.cpp\ - ../../JGE/src/Encoding.cpp\ - ../../JGE/src/JAnimator.cpp\ - ../../JGE/src/JApp.cpp\ - ../../JGE/src/JDistortionMesh.cpp\ - ../../JGE/src/JFileSystem.cpp\ - ../../JGE/src/JGameObject.cpp\ - ../../JGE/src/JGE.cpp\ - ../../JGE/src/JGui.cpp\ - ../../JGE/src/JLogger.cpp\ - ../../JGE/src/JLBFont.cpp\ - ../../JGE/src/JMD2Model.cpp\ - ../../JGE/src/JOBJModel.cpp\ - ../../JGE/src/JParticle.cpp\ - ../../JGE/src/JParticleEffect.cpp\ - ../../JGE/src/JParticleEmitter.cpp\ - ../../JGE/src/JParticleSystem.cpp\ - ../../JGE/src/JResourceManager.cpp\ - ../../JGE/src/JSpline.cpp\ - ../../JGE/src/JSprite.cpp\ - ../../JGE/src/Vector2D.cpp\ - ../../JGE/src/tinyxml/tinystr.cpp\ - ../../JGE/src/tinyxml/tinyxml.cpp\ - ../../JGE/src/tinyxml/tinyxmlerror.cpp\ - ../../JGE/src/tinyxml/tinyxmlparser.cpp\ - ../../JGE/src/hge/hgecolor.cpp\ - ../../JGE/src/hge/hgedistort.cpp\ - ../../JGE/src/hge/hgefont.cpp\ - ../../JGE/src/hge/hgeparticle.cpp\ - ../../JGE/src/hge/hgerect.cpp\ - ../../JGE/src/hge/hgevector.cpp\ - ../../JGE/src/zipFS/zfsystem.cpp\ - ../../JGE/src/zipFS/ziphdr.cpp\ - ../../JGE/src/zipFS/zstream.cpp\ - ../../JGE/src/pc/JSfx.cpp\ - ../../JGE/src/pc/JGfx.cpp\ - ../../JGE/src/JNetwork.cpp\ - ../../JGE/src/pc/JSocket.cpp + ../../JGE/src/JMD2Model.cpp -HEADERS += \ - ../../JGE/include/decoder_prx.h\ - ../../JGE/include/DebugRoutines.h\ - ../../JGE/include/Encoding.h\ - ../../JGE/include/JAnimator.h\ - ../../JGE/include/JApp.h\ - ../../JGE/include/JAssert.h\ - ../../JGE/include/JCooleyesMP3.h\ - ../../JGE/include/JDistortionMesh.h\ - ../../JGE/include/JFileSystem.h\ - ../../JGE/include/JGameLauncher.h\ - ../../JGE/include/JGameObject.h\ - ../../JGE/include/JGE.h\ - ../../JGE/include/JGui.h\ - ../../JGE/include/JLBFont.h\ - ../../JGE/include/JLogger.h\ - ../../JGE/include/JMD2Model.h\ - ../../JGE/include/JMP3.h\ - ../../JGE/include/JNetwork.h\ - ../../JGE/include/JOBJModel.h\ - ../../JGE/include/JParticleEffect.h\ - ../../JGE/include/JParticleEmitter.h\ - ../../JGE/include/JParticle.h\ - ../../JGE/include/JParticleSystem.h\ - ../../JGE/include/JRenderer.h\ - ../../JGE/include/JResourceManager.h\ - ../../JGE/include/JSocket.h\ - ../../JGE/include/JSoundSystem.h\ - ../../JGE/include/JSpline.h\ - ../../JGE/include/JSprite.h\ - ../../JGE/include/JTypes.h\ - ../../JGE/include/Vector2D.h\ - ../../JGE/include/Vector3D.h\ - ../../JGE/include/vram.h\ - ../../JGE/include/Threading.h\ - ../../JGE/src/tinyxml/tinystr.h\ - ../../JGE/src/tinyxml/tinyxml.h\ - ../../JGE/include/vram.h\ - ../../JGE/include/hge/hgecolor.h\ - ../../JGE/include/hge/hgedistort.h\ - ../../JGE/include/hge/hgefont.h\ - ../../JGE/include/hge/hgerect.h\ - ../../JGE/include/hge/hgevector.h\ - ../../JGE/include/hge/hgeparticle.h\ - ../../JGE/include/unzip/ioapi.h\ - ../../JGE/include/unzip/mztools.h\ - ../../JGE/include/unzip/unzip.h\ - ../../JGE/include/JNetwork.h\ - ../../JGE/include/JSocket.h +windows{ - INSTALLS += target \ - res \ + SOURCES += \ + ../../JGE/Dependencies/SDL/src/core/windows/SDL_windows.c\ + ../../JGE/Dependencies/SDL/src/events/SDL_clipboardevents.c\ + ../../JGE/Dependencies/SDL/src/events/SDL_gesture.c\ + ../../JGE/Dependencies/SDL/src/events/SDL_touch.c\ + ../../JGE/Dependencies/SDL/src/libm/e_atan2.c\ + ../../JGE/Dependencies/SDL/src/libm/e_log.c\ + ../../JGE/Dependencies/SDL/src/libm/e_pow.c\ + ../../JGE/Dependencies/SDL/src/libm/e_rem_pio2.c\ + ../../JGE/Dependencies/SDL/src/libm/e_sqrt.c\ + ../../JGE/Dependencies/SDL/src/libm/k_cos.c\ + ../../JGE/Dependencies/SDL/src/libm/k_rem_pio2.c\ + ../../JGE/Dependencies/SDL/src/libm/k_sin.c\ + ../../JGE/Dependencies/SDL/src/libm/s_atan.c\ + ../../JGE/Dependencies/SDL/src/libm/s_copysign.c\ + ../../JGE/Dependencies/SDL/src/libm/s_cos.c\ + ../../JGE/Dependencies/SDL/src/libm/s_fabs.c\ + ../../JGE/Dependencies/SDL/src/libm/s_floor.c\ + ../../JGE/Dependencies/SDL/src/libm/s_scalbn.c\ + ../../JGE/Dependencies/SDL/src/libm/s_sin.c\ + ../../JGE/Dependencies/SDL/src/render/direct3d/SDL_render_d3d.c\ + ../../JGE/Dependencies/SDL/src/render/opengl/SDL_render_gl.c\ + ../../JGE/Dependencies/SDL/src/render/opengl/SDL_shaders_gl.c\ + ../../JGE/Dependencies/SDL/src/render/SDL_render.c\ + ../../JGE/Dependencies/SDL/src/render/SDL_yuv_mmx.c\ + ../../JGE/Dependencies/SDL/src/render/SDL_yuv_sw.c\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_blendfillrect.c\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_blendline.c\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_blendpoint.c\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_drawline.c\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_drawpoint.c\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_render_sw.c\ + ../../JGE/Dependencies/SDL/src/SDL.c\ + ../../JGE/Dependencies/SDL/src/SDL_assert.c\ + ../../JGE/Dependencies/SDL/src/atomic/SDL_atomic.c\ + ../../JGE/Dependencies/SDL/src/atomic/SDL_spinlock.c\ + ../../JGE/Dependencies/SDL/src/audio/SDL_audio.c\ + ../../JGE/Dependencies/SDL/src/audio/SDL_audiocvt.c\ + ../../JGE/Dependencies/SDL/src/audio/SDL_audiodev.c\ + ../../JGE/Dependencies/SDL/src/audio/SDL_audiotypecvt.c\ + ../../JGE/Dependencies/SDL/src/SDL_hints.c\ + ../../JGE/Dependencies/SDL/src/SDL_log.c\ + ../../JGE/Dependencies/SDL/src/video/dummy/SDL_nullframebuffer.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit_0.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit_1.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit_A.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit_auto.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit_copy.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit_N.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit_slow.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_bmp.c\ + ../../JGE/Dependencies/SDL/src/SDL_compat.c\ + ../../JGE/Dependencies/SDL/src/cpuinfo/SDL_cpuinfo.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_clipboard.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_shape.c\ + ../../JGE/Dependencies/SDL/src/audio/windib/SDL_dibaudio.c\ + ../../JGE/Dependencies/SDL/src/audio/disk/SDL_diskaudio.c\ + ../../JGE/Dependencies/SDL/src/audio/dummy/SDL_dummyaudio.c\ + ../../JGE/Dependencies/SDL/src/audio/windx5/SDL_dx5audio.c\ + ../../JGE/Dependencies/SDL/src/joystick/windows/SDL_dxjoystick.c\ + ../../JGE/Dependencies/SDL/src/SDL_error.c\ + ../../JGE/Dependencies/SDL/src/events/SDL_events.c\ + ../../JGE/Dependencies/SDL/src/SDL_fatal.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_fillrect.c\ + ../../JGE/Dependencies/SDL/src/stdlib/SDL_getenv.c\ + ../../JGE/Dependencies/SDL/src/haptic/SDL_haptic.c\ + ../../JGE/Dependencies/SDL/src/stdlib/SDL_iconv.c\ + ../../JGE/Dependencies/SDL/src/joystick/SDL_joystick.c\ + ../../JGE/Dependencies/SDL/src/events/SDL_keyboard.c\ + ../../JGE/Dependencies/SDL/src/stdlib/SDL_malloc.c\ + ../../JGE/Dependencies/SDL/src/audio/SDL_mixer.c\ + ../../JGE/Dependencies/SDL/src/joystick/windows/SDL_mmjoystick.c\ + ../../JGE/Dependencies/SDL/src/events/SDL_mouse.c\ + ../../JGE/Dependencies/SDL/src/video/dummy/SDL_nullevents.c\ + ../../JGE/Dependencies/SDL/src/video/dummy/SDL_nullvideo.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_pixels.c\ + ../../JGE/Dependencies/SDL/src/power/SDL_power.c\ + ../../JGE/Dependencies/SDL/src/stdlib/SDL_qsort.c\ + ../../JGE/Dependencies/SDL/src/events/SDL_quit.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_rect.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_RLEaccel.c\ + ../../JGE/Dependencies/SDL/src/file/SDL_rwops.c\ + ../../JGE/Dependencies/SDL/src/stdlib/SDL_stdlib.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_stretch.c\ + ../../JGE/Dependencies/SDL/src/stdlib/SDL_string.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_surface.c\ + ../../JGE/Dependencies/SDL/src/haptic/windows/SDL_syshaptic.c\ + ../../JGE/Dependencies/SDL/src/loadso/windows/SDL_sysloadso.c\ + ../../JGE/Dependencies/SDL/src/thread/windows/SDL_sysmutex.c\ + ../../JGE/Dependencies/SDL/src/power/windows/SDL_syspower.c\ + ../../JGE/Dependencies/SDL/src/thread/windows/SDL_syssem.c\ + ../../JGE/Dependencies/SDL/src/thread/windows/SDL_systhread.c\ + ../../JGE/Dependencies/SDL/src/timer/windows/SDL_systimer.c\ + ../../JGE/Dependencies/SDL/src/thread/SDL_thread.c\ + ../../JGE/Dependencies/SDL/src/timer/SDL_timer.c\ + ../../JGE/Dependencies/SDL/src/video/SDL_video.c\ + ../../JGE/Dependencies/SDL/src/audio/SDL_wave.c\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsclipboard.c\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsevents.c\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsframebuffer.c\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowskeyboard.c\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsmodes.c\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsmouse.c\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsopengl.c\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsshape.c\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsvideo.c\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowswindow.c\ + ../../JGE/Dependencies/SDL/src/events/SDL_windowevents.c - res.path = /usr/local/bin/Res - res.files += bin/Res/* - target.path = /usr/local/bin -maemo5: { - # Variables - BINDIR = /opt/wagic - RESDIR = /home/user/wagic/Res - ICONDIR = /usr/share - DEFINES += RESDIR=\\\"$$RESDIR\\\" + HEADERS += \ + ../../JGE/Dependencies/SDL/include/SDL.h\ + ../../JGE/Dependencies/SDL/include/SDL_assert.h\ + ../../JGE/Dependencies/SDL/include/SDL_atomic.h\ + ../../JGE/Dependencies/SDL/include/SDL_audio.h\ + ../../JGE/Dependencies/SDL/include/SDL_blendmode.h\ + ../../JGE/Dependencies/SDL/include/SDL_clipboard.h\ + ../../JGE/Dependencies/SDL/include/SDL_compat.h\ + ../../JGE/Dependencies/SDL/include/SDL_config.h\ + ../../JGE/Dependencies/SDL/include/SDL_config_windows.h\ + ../../JGE/Dependencies/SDL/include/SDL_copying.h\ + ../../JGE/Dependencies/SDL/include/SDL_cpuinfo.h\ + ../../JGE/Dependencies/SDL/include/SDL_endian.h\ + ../../JGE/Dependencies/SDL/include/SDL_error.h\ + ../../JGE/Dependencies/SDL/include/SDL_events.h\ + ../../JGE/Dependencies/SDL/include/SDL_gesture.h\ + ../../JGE/Dependencies/SDL/include/SDL_haptic.h\ + ../../JGE/Dependencies/SDL/include/SDL_hints.h\ + ../../JGE/Dependencies/SDL/include/SDL_input.h\ + ../../JGE/Dependencies/SDL/include/SDL_joystick.h\ + ../../JGE/Dependencies/SDL/include/SDL_keyboard.h\ + ../../JGE/Dependencies/SDL/include/SDL_keycode.h\ + ../../JGE/Dependencies/SDL/include/SDL_loadso.h\ + ../../JGE/Dependencies/SDL/include/SDL_log.h\ + ../../JGE/Dependencies/SDL/include/SDL_main.h\ + ../../JGE/Dependencies/SDL/include/SDL_mouse.h\ + ../../JGE/Dependencies/SDL/include/SDL_mutex.h\ + ../../JGE/Dependencies/SDL/include/SDL_name.h\ + ../../JGE/Dependencies/SDL/include/SDL_opengl.h\ + ../../JGE/Dependencies/SDL/include/SDL_opengles.h\ + ../../JGE/Dependencies/SDL/include/SDL_pixels.h\ + ../../JGE/Dependencies/SDL/include/SDL_platform.h\ + ../../JGE/Dependencies/SDL/include/SDL_power.h\ + ../../JGE/Dependencies/SDL/include/SDL_quit.h\ + ../../JGE/Dependencies/SDL/include/SDL_rect.h\ + ../../JGE/Dependencies/SDL/include/SDL_render.h\ + ../../JGE/Dependencies/SDL/include/SDL_revision.h\ + ../../JGE/Dependencies/SDL/include/SDL_rwops.h\ + ../../JGE/Dependencies/SDL/include/SDL_scancode.h\ + ../../JGE/Dependencies/SDL/include/SDL_shape.h\ + ../../JGE/Dependencies/SDL/include/SDL_stdinc.h\ + ../../JGE/Dependencies/SDL/include/SDL_surface.h\ + ../../JGE/Dependencies/SDL/include/SDL_syswm.h\ + ../../JGE/Dependencies/SDL/include/SDL_thread.h\ + ../../JGE/Dependencies/SDL/include/SDL_timer.h\ + ../../JGE/Dependencies/SDL/include/SDL_touch.h\ + ../../JGE/Dependencies/SDL/include/SDL_types.h\ + ../../JGE/Dependencies/SDL/include/SDL_version.h\ + ../../JGE/Dependencies/SDL/include/SDL_video.h\ + ../../JGE/Dependencies/SDL/src/core/windows/SDL_windows.h\ + ../../JGE/Dependencies/SDL/src/events/blank_cursor.h\ + ../../JGE/Dependencies/SDL/src/events/default_cursor.h\ + ../../JGE/Dependencies/SDL/src/audio/windx5\directx.h\ + ../../JGE/Dependencies/SDL/src/events/SDL_clipboardevents_c.h\ + ../../JGE/Dependencies/SDL/src/events/SDL_gesture_c.h\ + ../../JGE/Dependencies/SDL/src/events/SDL_touch_c.h\ + ../../JGE/Dependencies/SDL/src/libm/math.h\ + ../../JGE/Dependencies/SDL/src/libm/math_private.h\ + ../../JGE/Dependencies/SDL/src/render/mmx.h\ + ../../JGE/Dependencies/SDL/src/render/opengl\SDL_shaders_gl.h\ + ../../JGE/Dependencies/SDL/src/render/SDL_sysrender.h\ + ../../JGE/Dependencies/SDL/src/render/SDL_yuv_sw_c.h\ + ../../JGE/Dependencies/SDL/src/audio/SDL_audio_c.h\ + ../../JGE/Dependencies/SDL/src/audio/SDL_audiodev_c.h\ + ../../JGE/Dependencies/SDL/src/audio/SDL_audiomem.h\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_blendfillrect.h\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_blendline.h\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_blendpoint.h\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_draw.h\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_drawline.h\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_drawpoint.h\ + ../../JGE/Dependencies/SDL/src/render/software/SDL_render_sw_c.h\ + ../../JGE/Dependencies/SDL/src/video/dummy/SDL_nullframebuffer_c.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit_auto.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit_copy.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_blit_slow.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_shape_internals.h\ + ../../JGE/Dependencies/SDL/src/audio/windib/SDL_dibaudio.h\ + ../../JGE/Dependencies/SDL/src/audio/disk/SDL_diskaudio.h\ + ../../JGE/Dependencies/SDL/src/audio/dummy/SDL_dummyaudio.h\ + ../../JGE/Dependencies/SDL/src/audio/windx5/SDL_dx5audio.h\ + ../../JGE/Dependencies/SDL/src/SDL_error_c.h\ + ../../JGE/Dependencies/SDL/src/events/SDL_events_c.h\ + ../../JGE/Dependencies/SDL/src/SDL_fatal.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_glesfuncs.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_glfuncs.h\ + ../../JGE/Dependencies/SDL/src/joystick/SDL_joystick_c.h\ + ../../JGE/Dependencies/SDL/src/events/SDL_keyboard_c.h\ + ../../JGE/Dependencies/SDL/src/events/SDL_mouse_c.h\ + ../../JGE/Dependencies/SDL/src/video/dummy/SDL_nullevents_c.h\ + ../../JGE/Dependencies/SDL/src/video/dummy/SDL_nullvideo.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_pixels_c.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_rect_c.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_RLEaccel_c.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_stretch_c.h\ + ../../JGE/Dependencies/SDL/src/audio/SDL_sysaudio.h\ + ../../JGE/Dependencies/SDL/src/events/SDL_sysevents.h\ + ../../JGE/Dependencies/SDL/src/haptic/SDL_syshaptic.h\ + ../../JGE/Dependencies/SDL/src/joystick/SDL_sysjoystick.h\ + ../../JGE/Dependencies/SDL/src/thread/SDL_systhread.h\ + ../../JGE/Dependencies/SDL/src/thread/windows\SDL_systhread_c.h\ + ../../JGE/Dependencies/SDL/src/timer/SDL_systimer.h\ + ../../JGE/Dependencies/SDL/src/video/SDL_sysvideo.h\ + ../../JGE/Dependencies/SDL/src/thread/SDL_thread_c.h\ + ../../JGE/Dependencies/SDL/src/timer/SDL_timer_c.h\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_vkeys.h\ + ../../JGE/Dependencies/SDL/src/audio/SDL_wave.h\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsclipboard.h\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsevents.h\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsframebuffer.h\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowskeyboard.h\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsmodes.h\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsmouse.h\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsopengl.h\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsshape.h\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowsvideo.h\ + ../../JGE/Dependencies/SDL/src/video/windows/SDL_windowswindow.h\ + ../../JGE/Dependencies/SDL/src/events/SDL_windowevents_c.h\ + ../../JGE/Dependencies/SDL/src/video/windows/wmmsg.h\ + ../../JGE/Dependencies/SDL/VisualC/SDL/resource.h - INSTALLS += target \ - desktop \ - icon \ - res \ - restxt \ - launcher \ - - target.path = $$BINDIR - - desktop.path = $$ICONDIR/applications/hildon - desktop.files += wagic.desktop - - icon.path = $$ICONDIR/icons/hicolor/64x64/apps - icon.files += wagic-64x64.png - - res.path = $$RESDIR - res.files += bin/Res/* - # res.extra = tar -C ../../../../src/projects/mtg/bin -czf Res.tgz Res - - restxt.path = $$BINDIR - restxt.files += debian/Res.txt - - launcher.path = $$BINDIR - launcher.files += debian/launcher } diff --git a/projects/mtg/wagic-qt.pro b/projects/mtg/wagic-qt.pro index 3084f5f32..487557c3f 100644 --- a/projects/mtg/wagic-qt.pro +++ b/projects/mtg/wagic-qt.pro @@ -1,5 +1,9 @@ +include(wagic.pri) + # Add more folders to ship with the application, here addExclusiveBuilds(graphics, Graphics, console, Console) + +INCLUDEPATH += ../../JGE/include/qt CONFIG(console, graphics|console){ QT += core network QT -= gui @@ -14,407 +18,46 @@ else:CONFIG(graphics, graphics|console){ folder_01.target = /usr/share DEPLOYMENTFOLDERS = folder_01 QT += core gui opengl network + QT -= declarative quick qml #maemo5:DEFINES += QT_WIDGET DEFINES += QT_WIDGET unix:!symbian:INCLUDEPATH += /usr/include/GL # Please do not modify the following two lines. Required for deployment. - !maemo5:include(qml/qmlapplicationviewer/qmlapplicationviewer.pri) - !maemo5:qtcAddDeployment() +# !maemo5:include(qml/qmlapplicationviewer/qmlapplicationviewer.pri) +# !maemo5:qtcAddDeployment() } #!android:!symbian:QT += phonon maemo5:QT += dbus -TARGET = wagic -TEMPLATE = app - -#!macx:CONFIG += precompile_header -unix|macx:QMAKE_CXXFLAGS += -Wno-unused-parameter -unix:!macx:QMAKE_CXXFLAGS += -Wno-unused-but-set-parameter -unix:!macx:QMAKE_CXXFLAGS += -Wno-unused-but-set-variable -unix|macx:QMAKE_CXXFLAGS += -Wno-unused-value -unix:!macx:QMAKE_CXXFLAGS += -Wno-unused-local-typedefs -unix:!macx:!maemo5:!symbian:QMAKE_CXXFLAGS += -Werror - -windows:DEFINES += _CRT_SECURE_NO_WARNINGS -unix|macx:DEFINES += LINUX -CONFIG(debug, debug|release) { - DEFINES += _DEBUG -} - DEFINES += QT_CONFIG #!android:!symbian:DEFINES += USE_PHONON android:INCLUDEPATH += $$ANDROID_NDK_ROOT/platforms/android-9/arch-arm/usr/include #DEFINES += QT_NO_DEBUG_OUTPUT -DEFINES += NETWORK_SUPPORT - -DEFINES += TIXML_USE_STL - -windows:INCLUDEPATH += ../../JGE/Dependencies/include -windows{ - *-g++* { - DEFINES += LINUX - } - *-msvc* { - INCLUDEPATH += extra - DEFINES += WIN32 - } -} -macx:INCLUDEPATH += /opt/include -INCLUDEPATH += ../../JGE/include/qt -INCLUDEPATH += ../../JGE/include -INCLUDEPATH += ../../JGE/src/zipFS -INCLUDEPATH += ../../Boost -INCLUDEPATH += include -#!symbian:DESTDIR = bin - -unix:!symbian:LIBS += -lz -win32:LIBS += ../../JGE/Dependencies/lib/fmodvc.lib -win32:LIBS += ../../JGE/Dependencies/lib/zlibd.lib -PRECOMPILED_HEADER = include/PrecompiledHeader.h - -#DEFINES += TRACK_OBJECT_USAGE -#DEFINES += AI_CHANGE_TESTING -#DEFINES += ACTION_LOGGING_TESTING - -SOURCES += \ - src/AbilityParser.cpp\ - src/ActionElement.cpp\ - src/ActionLayer.cpp\ - src/ActionStack.cpp\ - src/AIHints.cpp\ - src/AIMomirPlayer.cpp\ - src/AIPlayer.cpp\ - src/AIPlayerBaka.cpp\ - src/AIStats.cpp\ - src/AllAbilities.cpp\ - src/CardDescriptor.cpp\ - src/CardDisplay.cpp\ - src/CardGui.cpp\ - src/CardPrimitive.cpp\ - src/CardSelector.cpp\ - src/Closest.cpp\ - src/Counters.cpp\ - src/Credits.cpp\ - src/Damage.cpp\ - src/DamagerDamaged.cpp\ - src/DeckDataWrapper.cpp\ - src/DeckEditorMenu.cpp\ - src/DeckManager.cpp\ - src/DeckMenu.cpp\ - src/DeckMenuItem.cpp\ - src/DeckMetaData.cpp\ - src/DeckStats.cpp\ - src/DuelLayers.cpp\ - src/Effects.cpp\ - src/ExtraCost.cpp\ - src/GameApp.cpp\ - src/GameLauncher.cpp\ - src/GameObserver.cpp\ - src/GameOptions.cpp\ - src/GameStateAwards.cpp\ - src/GameState.cpp\ - src/GameStateDeckViewer.cpp\ - src/GameStateDuel.cpp\ - src/GameStateMenu.cpp\ - src/GameStateOptions.cpp\ - src/GameStateShop.cpp\ - src/GameStateStory.cpp\ - src/GameStateTransitions.cpp\ - src/GuiAvatars.cpp\ - src/GuiBackground.cpp\ - src/GuiCardsController.cpp\ - src/GuiCombat.cpp\ - src/GuiFrame.cpp\ - src/GuiHand.cpp\ - src/GuiLayers.cpp\ - src/GuiMana.cpp\ - src/GuiPhaseBar.cpp\ - src/GuiPlay.cpp\ - src/GuiStatic.cpp\ - src/IconButton.cpp\ - src/InteractiveButton.cpp\ - src/ManaCost.cpp\ - src/ManaCostHybrid.cpp\ - src/MenuItem.cpp\ - src/ModRules.cpp\ - src/MTGAbility.cpp\ - src/MTGCard.cpp\ - src/MTGCardInstance.cpp\ - src/MTGDeck.cpp\ - src/MTGDefinitions.cpp\ - src/MTGGamePhase.cpp\ - src/MTGGameZones.cpp\ - src/MTGPack.cpp\ - src/MTGRules.cpp\ - src/ObjectAnalytics.cpp\ - src/OptionItem.cpp\ - src/PhaseRing.cpp\ - src/Player.cpp\ - src/PlayerData.cpp\ - src/PlayGuiObject.cpp\ - src/PlayGuiObjectController.cpp\ - src/PlayRestrictions.cpp\ - src/Pos.cpp\ - src/PriceList.cpp\ - src/ReplacementEffects.cpp\ - src/Rules.cpp\ - src/SimpleButton.cpp\ - src/SimpleMenu.cpp\ - src/SimpleMenuItem.cpp\ - src/SimplePad.cpp\ - src/SimplePopup.cpp\ - src/StoryFlow.cpp\ - src/Subtypes.cpp\ - src/StyleManager.cpp\ - src/TargetChooser.cpp\ - src/TargetsList.cpp\ - src/Tasks.cpp\ - src/TextScroller.cpp\ - src/ThisDescriptor.cpp\ - src/Token.cpp\ - src/Translate.cpp\ - src/TranslateKeys.cpp\ - src/Trash.cpp\ - src/utils.cpp\ - src/WCachedResource.cpp\ - src/WDataSrc.cpp\ - src/WEvent.cpp\ - src/WFilter.cpp\ - src/WFont.cpp\ - src/WGui.cpp\ - src/WResourceManager.cpp \ - src/AIPlayerBakaB.cpp \ - src/TestSuiteAI.cpp - -HEADERS += \ - include/CacheEngine.h\ - include/AllAbilities.h\ - include/AbilityParser.h\ - include/PrecompiledHeader.h\ - include/WResource_Fwd.h\ - include/PlayRestrictions.h\ - include/ModRules.h\ - include/AIHints.h\ - include/AIPlayerBaka.h\ - include/AIPlayerBakaB.h\ - include/DeckEditorMenu.h\ - include/WResourceManagerImpl.h\ - include/DeckMenu.h\ - include/DeckMenuItem.h\ - include/ExtraCost.h\ - include/ManaCost.h\ - include/SimpleMenuItem.h\ - include/GameApp.h\ - include/ManaCostHybrid.h\ - include/SimplePad.h\ - include/ActionElement.h\ - include/GameObserver.h\ - include/MenuItem.h\ - include/StoryFlow.h\ - include/ActionLayer.h\ - include/GameOptions.h\ - include/MTGAbility.h\ - include/Subtypes.h\ - include/ActionStack.h\ - include/GameStateAwards.h\ - include/MTGCard.h\ - include/AIMomirPlayer.h\ - include/GameStateDeckViewer.h\ - include/MTGCardInstance.h\ - include/Targetable.h\ - include/AIPlayer.h\ - include/GameStateDuel.h\ - include/MTGDeck.h\ - include/TargetChooser.h\ - include/AIStats.h\ - include/GameState.h\ - include/MTGDefinitions.h\ - include/TargetsList.h\ - include/AllAbilities.h\ - include/GameStateMenu.h\ - include/MTGGamePhase.h\ - include/Tasks.h\ - include/CardDescriptor.h\ - include/GameStateOptions.h\ - include/MTGGameZones.h\ - include/TestSuiteAI.h\ - include/CardDisplay.h\ - include/GameStateShop.h\ - include/MTGPack.h\ - include/TextScroller.h\ - include/GameStateStory.h\ - include/MTGRules.h\ - include/ThisDescriptor.h\ - include/CardGui.h\ - include/GameStateTransitions.h\ - include/IconButton.h\ - include/OptionItem.h\ - include/Token.h\ - include/CardPrimitive.h\ - include/GuiAvatars.h\ - include/Translate.h\ - include/CardSelector.h\ - include/GuiBackground.h\ - include/PhaseRing.h\ - include/TranslateKeys.h\ - include/config.h\ - include/GuiCardsController.h\ - include/PlayerData.h\ - include/Trash.h\ - include/Counters.h\ - include/GuiCombat.h\ - include/Player.h\ - include/utils.h\ - include/Credits.h\ - include/GuiFrame.h\ - include/PlayGuiObjectController.h\ - include/WCachedResource.h\ - include/Damage.h\ - include/GuiHand.h\ - include/PlayGuiObject.h\ - include/WDataSrc.h\ - include/DamagerDamaged.h\ - include/GuiLayers.h\ - include/Pos.h\ - include/WEvent.h\ - include/DeckDataWrapper.h\ - include/GuiMana.h\ - include/PriceList.h\ - include/WFilter.h\ - include/DeckMetaData.h\ - include/GuiPhaseBar.h\ - include/ReplacementEffects.h\ - include/WGui.h\ - include/DeckStats.h\ - include/GuiPlay.h\ - include/Rules.h\ - include/WResourceManager.h\ - include/DuelLayers.h\ - include/GuiStatic.h\ - include/Effects.h\ - include/StyleManager.h\ - include/WFont.h\ - include/DeckManager.h\ - include/SimplePopup.h\ - include/SimpleMenu.h\ - include/SimpleButton.h\ - include/InteractiveButton.h\ - include/ObjectAnalytics.h - -# JGE, could probably be moved outside -SOURCES += \ - ../../JGE/src/Encoding.cpp\ - ../../JGE/src/JAnimator.cpp\ - ../../JGE/src/JApp.cpp\ - ../../JGE/src/JDistortionMesh.cpp\ - ../../JGE/src/JFileSystem.cpp\ - ../../JGE/src/JGameObject.cpp\ - ../../JGE/src/JGE.cpp\ - ../../JGE/src/JGui.cpp\ - ../../JGE/src/JLogger.cpp\ - ../../JGE/src/JLBFont.cpp\ - ../../JGE/src/JOBJModel.cpp\ - ../../JGE/src/JParticle.cpp\ - ../../JGE/src/JParticleEffect.cpp\ - ../../JGE/src/JParticleEmitter.cpp\ - ../../JGE/src/JParticleSystem.cpp\ - ../../JGE/src/JResourceManager.cpp\ - ../../JGE/src/JSpline.cpp\ - ../../JGE/src/JNetwork.cpp\ - ../../JGE/src/pc/JSocket.cpp\ - ../../JGE/src/pc/JSfx.cpp\ - ../../JGE/src/JSprite.cpp\ - ../../JGE/src/OutputCapturer.cpp\ - ../../JGE/src/Vector2D.cpp\ - ../../JGE/src/tinyxml/tinystr.cpp\ - ../../JGE/src/tinyxml/tinyxml.cpp\ - ../../JGE/src/tinyxml/tinyxmlerror.cpp\ - ../../JGE/src/tinyxml/tinyxmlparser.cpp\ - ../../JGE/src/hge/hgecolor.cpp\ - ../../JGE/src/hge/hgedistort.cpp\ - ../../JGE/src/hge/hgefont.cpp\ - ../../JGE/src/hge/hgeparticle.cpp\ - ../../JGE/src/hge/hgerect.cpp\ - ../../JGE/src/hge/hgevector.cpp\ - ../../JGE/src/zipFS/zfsystem.cpp\ - ../../JGE/src/zipFS/ziphdr.cpp\ - ../../JGE/src/zipFS/zstream.cpp CONFIG(graphics, graphics|console){ + HEADERS += \ + ../../JGE/include/qt/filedownloader.h\ + ../../JGE/include/qt/corewrapper.h + SOURCES += \ ../../JGE/src/qt/filedownloader.cpp\ ../../JGE/src/qt/corewrapper.cpp\ ../../JGE/src/Qtmain.cpp\ ../../JGE/src/JMD2Model.cpp\ ../../JGE/src/pc/JGfx.cpp - - HEADERS += \ - ../../JGE/include/qt/filedownloader.h\ - ../../JGE/include/qt/corewrapper.h } else:CONFIG(console, graphics|console){ + HEADERS += \ + ../../JGE/include/OutputCapturer.h + SOURCES += \ + ../../JGE/src/OutputCapturer.cpp\ ../../JGE/src/JGfx-fake.cpp\ - ../../JGE/src/Qtconsole.cpp + ../../JGE/src/Qtconsole.cpp\ } - -HEADERS += \ - ../../JGE/include/Threading.h\ - ../../JGE/include/decoder_prx.h\ - ../../JGE/include/DebugRoutines.h\ - ../../JGE/include/Encoding.h\ - ../../JGE/include/JAnimator.h\ - ../../JGE/include/JApp.h\ - ../../JGE/include/JAssert.h\ - ../../JGE/include/JCooleyesMP3.h\ - ../../JGE/include/JDistortionMesh.h\ - ../../JGE/include/JFileSystem.h\ - ../../JGE/include/JGameLauncher.h\ - ../../JGE/include/JGameObject.h\ - ../../JGE/include/JGE.h\ - ../../JGE/include/JGui.h\ - ../../JGE/include/JLBFont.h\ - ../../JGE/include/JLogger.h\ - ../../JGE/include/JMD2Model.h\ - ../../JGE/include/JMP3.h\ - ../../JGE/include/JNetwork.h\ - ../../JGE/include/JOBJModel.h\ - ../../JGE/include/JParticleEffect.h\ - ../../JGE/include/JParticleEmitter.h\ - ../../JGE/include/JParticle.h\ - ../../JGE/include/JParticleSystem.h\ - ../../JGE/include/JRenderer.h\ - ../../JGE/include/JResourceManager.h\ - ../../JGE/include/JSocket.h\ - ../../JGE/include/JSoundSystem.h\ - ../../JGE/include/JSpline.h\ - ../../JGE/include/JSprite.h\ - ../../JGE/include/JTypes.h\ - ../../JGE/include/OutputCapturer.h\ - ../../JGE/include/Vector2D.h\ - ../../JGE/include/Vector3D.h\ - ../../JGE/include/vram.h\ - ../../JGE/include/hge/hgecolor.h\ - ../../JGE/include/hge/hgedistort.h\ - ../../JGE/include/hge/hgefont.h\ - ../../JGE/include/hge/hgeparticle.h\ - ../../JGE/include/hge/hgerect.h\ - ../../JGE/include/hge/hgevector.h\ - ../../JGE/src/unzip/unzip.h\ - ../../JGE/src/unzip/ioapi.h\ - ../../JGE/src/zipFS/zstream_zlib.h\ - ../../JGE/src/zipFS/zfsystem.h\ - ../../JGE/src/zipFS/zstream.h\ - ../../JGE/src/zipFS/ziphdr.h\ - ../../JGE/src/zipFS/stdafx.h\ - ../../JGE/src/zipFS/fileio.h\ - ../../JGE/src/tinyxml/tinystr.h\ - ../../JGE/src/tinyxml/tinyxml.h\ - ../../JGE/include/vram.h - # maemo 5 packaging maemo5: { # Variables diff --git a/projects/mtg/wagic.pri b/projects/mtg/wagic.pri new file mode 100644 index 000000000..85ea223a2 --- /dev/null +++ b/projects/mtg/wagic.pri @@ -0,0 +1,482 @@ +# Add more folders to ship with the application, here +TARGET = wagic +TEMPLATE = app + +#!macx:CONFIG += precompile_header +unix|macx:QMAKE_CXXFLAGS += -Wno-unused-parameter +unix:!*macx*:QMAKE_CXXFLAGS += -Wno-unused-but-set-parameter +unix:!*macx*:QMAKE_CXXFLAGS += -Wno-unused-but-set-variable +unix|*macx*:QMAKE_CXXFLAGS += -Wno-unused-value +unix:!*macx*:QMAKE_CXXFLAGS += -Wno-unused-local-typedefs +unix:!*macx*:!maemo5:!symbian:QMAKE_CXXFLAGS += -Werror + +windows:DEFINES += _CRT_SECURE_NO_WARNINGS +unix|macx:DEFINES += LINUX +CONFIG(debug, debug|release) { + DEFINES += _DEBUG +} + +DEFINES += NETWORK_SUPPORT +DEFINES += TIXML_USE_STL + +windows:INCLUDEPATH += ../../JGE/Dependencies/include +windows{ + *-g++* { + DEFINES += LINUX + INCLUDEPATH += /usr/i686-w64-mingw32/sys-root/mingw/include/Qt +# INCLUDEPATH += /usr/i686-w64-mingw32/sys-root/mingw/include/c++ + LIBS += -L/usr/i686-w64-mingw32/sys-root/mingw/lib + LIBS += -lwsock32 + DEFINES += FORCE_GL2 + } + *-msvc* { + INCLUDEPATH += extra + DEFINES += WIN32 + } +} +macx:INCLUDEPATH += /opt/include +INCLUDEPATH += ../../JGE/include +INCLUDEPATH += ../../JGE/src/zipFS +INCLUDEPATH += ../../Boost +INCLUDEPATH += include + +unix:!symbian:LIBS += -lz +windows:LIBS += ../../JGE/Dependencies/lib/fmodvc.lib +windows:LIBS += ../../JGE/Dependencies/lib/zlibd.lib +PRECOMPILED_HEADER = include/PrecompiledHeader.h + +#DEFINES += TRACK_OBJECT_USAGE +#DEFINES += AI_CHANGE_TESTING +#DEFINES += ACTION_LOGGING_TESTING + +SOURCES += \ + src/AbilityParser.cpp\ + src/ActionElement.cpp\ + src/ActionLayer.cpp\ + src/ActionStack.cpp\ + src/AIHints.cpp\ + src/AIMomirPlayer.cpp\ + src/AIPlayer.cpp\ + src/AIPlayerBaka.cpp\ + src/AIStats.cpp\ + src/AllAbilities.cpp\ + src/CardDescriptor.cpp\ + src/CardDisplay.cpp\ + src/CardGui.cpp\ + src/CardPrimitive.cpp\ + src/CardSelector.cpp\ + src/CarouselDeckView.cpp\ + src/Closest.cpp\ + src/Counters.cpp\ + src/Credits.cpp\ + src/Damage.cpp\ + src/DamagerDamaged.cpp\ + src/DeckDataWrapper.cpp\ + src/DeckEditorMenu.cpp\ + src/DeckManager.cpp\ + src/DeckMenu.cpp\ + src/DeckMenuItem.cpp\ + src/DeckMetaData.cpp\ + src/DeckStats.cpp\ + src/DeckView.cpp\ + src/DuelLayers.cpp\ + src/Effects.cpp\ + src/ExtraCost.cpp\ + src/GameApp.cpp\ + src/GameLauncher.cpp\ + src/GameObserver.cpp\ + src/GameOptions.cpp\ + src/GameStateAwards.cpp\ + src/GameState.cpp\ + src/GameStateDeckViewer.cpp\ + src/GameStateDuel.cpp\ + src/GameStateMenu.cpp\ + src/GameStateOptions.cpp\ + src/GameStateShop.cpp\ + src/GameStateStory.cpp\ + src/GameStateTransitions.cpp\ + src/GridDeckView.cpp\ + src/GuiAvatars.cpp\ + src/GuiBackground.cpp\ + src/GuiCardsController.cpp\ + src/GuiCombat.cpp\ + src/GuiFrame.cpp\ + src/GuiHand.cpp\ + src/GuiLayers.cpp\ + src/GuiMana.cpp\ + src/GuiPhaseBar.cpp\ + src/GuiPlay.cpp\ + src/GuiStatic.cpp\ + src/IconButton.cpp\ + src/InteractiveButton.cpp\ + src/ManaCost.cpp\ + src/ManaCostHybrid.cpp\ + src/MenuItem.cpp\ + src/ModRules.cpp\ + src/MTGAbility.cpp\ + src/MTGCard.cpp\ + src/MTGCardInstance.cpp\ + src/MTGDeck.cpp\ + src/MTGDefinitions.cpp\ + src/MTGGamePhase.cpp\ + src/MTGGameZones.cpp\ + src/MTGPack.cpp\ + src/MTGRules.cpp\ + src/ObjectAnalytics.cpp\ + src/OptionItem.cpp\ + src/PhaseRing.cpp\ + src/Player.cpp\ + src/PlayerData.cpp\ + src/PlayGuiObject.cpp\ + src/PlayGuiObjectController.cpp\ + src/PlayRestrictions.cpp\ + src/Pos.cpp\ + src/PriceList.cpp\ + src/ReplacementEffects.cpp\ + src/Rules.cpp\ + src/SimpleButton.cpp\ + src/SimpleMenu.cpp\ + src/SimpleMenuItem.cpp\ + src/SimplePad.cpp\ + src/SimplePopup.cpp\ + src/StoryFlow.cpp\ + src/Subtypes.cpp\ + src/StyleManager.cpp\ + src/TargetChooser.cpp\ + src/TargetsList.cpp\ + src/Tasks.cpp\ + src/TextScroller.cpp\ + src/ThisDescriptor.cpp\ + src/Token.cpp\ + src/Translate.cpp\ + src/TranslateKeys.cpp\ + src/Trash.cpp\ + src/utils.cpp\ + src/WCachedResource.cpp\ + src/WDataSrc.cpp\ + src/WEvent.cpp\ + src/WFilter.cpp\ + src/WFont.cpp\ + src/WGui.cpp\ + src/WResourceManager.cpp \ + src/AIPlayerBakaB.cpp \ + src/TestSuiteAI.cpp + +HEADERS += \ + include/CarouselDeckView.h\ + include/DeckView.h\ + include/Easing.h\ + include/GridDeckView.h\ + include/CacheEngine.h\ + include/AllAbilities.h\ + include/AbilityParser.h\ + include/PrecompiledHeader.h\ + include/WResource_Fwd.h\ + include/PlayRestrictions.h\ + include/ModRules.h\ + include/AIHints.h\ + include/AIPlayerBaka.h\ + include/AIPlayerBakaB.h\ + include/DeckEditorMenu.h\ + include/WResourceManagerImpl.h\ + include/DeckMenu.h\ + include/DeckMenuItem.h\ + include/ExtraCost.h\ + include/ManaCost.h\ + include/SimpleMenuItem.h\ + include/GameApp.h\ + include/ManaCostHybrid.h\ + include/SimplePad.h\ + include/ActionElement.h\ + include/GameObserver.h\ + include/MenuItem.h\ + include/StoryFlow.h\ + include/ActionLayer.h\ + include/GameOptions.h\ + include/MTGAbility.h\ + include/Subtypes.h\ + include/ActionStack.h\ + include/GameStateAwards.h\ + include/MTGCard.h\ + include/AIMomirPlayer.h\ + include/GameStateDeckViewer.h\ + include/MTGCardInstance.h\ + include/Targetable.h\ + include/AIPlayer.h\ + include/GameStateDuel.h\ + include/MTGDeck.h\ + include/TargetChooser.h\ + include/AIStats.h\ + include/GameState.h\ + include/MTGDefinitions.h\ + include/TargetsList.h\ + include/AllAbilities.h\ + include/GameStateMenu.h\ + include/MTGGamePhase.h\ + include/Tasks.h\ + include/CardDescriptor.h\ + include/GameStateOptions.h\ + include/MTGGameZones.h\ + include/TestSuiteAI.h\ + include/CardDisplay.h\ + include/GameStateShop.h\ + include/MTGPack.h\ + include/TextScroller.h\ + include/GameStateStory.h\ + include/MTGRules.h\ + include/ThisDescriptor.h\ + include/CardGui.h\ + include/GameStateTransitions.h\ + include/IconButton.h\ + include/OptionItem.h\ + include/Token.h\ + include/CardPrimitive.h\ + include/GuiAvatars.h\ + include/Translate.h\ + include/CardSelector.h\ + include/GuiBackground.h\ + include/PhaseRing.h\ + include/TranslateKeys.h\ + include/config.h\ + include/GuiCardsController.h\ + include/PlayerData.h\ + include/Trash.h\ + include/Counters.h\ + include/GuiCombat.h\ + include/Player.h\ + include/utils.h\ + include/Credits.h\ + include/GuiFrame.h\ + include/PlayGuiObjectController.h\ + include/WCachedResource.h\ + include/Damage.h\ + include/GuiHand.h\ + include/PlayGuiObject.h\ + include/WDataSrc.h\ + include/DamagerDamaged.h\ + include/GuiLayers.h\ + include/Pos.h\ + include/WEvent.h\ + include/DeckDataWrapper.h\ + include/GuiMana.h\ + include/PriceList.h\ + include/WFilter.h\ + include/DeckMetaData.h\ + include/GuiPhaseBar.h\ + include/ReplacementEffects.h\ + include/WGui.h\ + include/DeckStats.h\ + include/GuiPlay.h\ + include/Rules.h\ + include/WResourceManager.h\ + include/DuelLayers.h\ + include/GuiStatic.h\ + include/Effects.h\ + include/StyleManager.h\ + include/WFont.h\ + include/DeckManager.h\ + include/SimplePopup.h\ + include/SimpleMenu.h\ + include/SimpleButton.h\ + include/InteractiveButton.h\ + include/ObjectAnalytics.h + +# JGE, could probably be moved outside +SOURCES += \ + ../../JGE/src/Downloader.cpp\ + ../../JGE/src/Encoding.cpp\ + ../../JGE/src/JAnimator.cpp\ + ../../JGE/src/JApp.cpp\ + ../../JGE/src/JDistortionMesh.cpp\ + ../../JGE/src/JFileSystem.cpp\ + ../../JGE/src/JGameObject.cpp\ + ../../JGE/src/JGE.cpp\ + ../../JGE/src/JGui.cpp\ + ../../JGE/src/JLogger.cpp\ + ../../JGE/src/JLBFont.cpp\ + ../../JGE/src/JOBJModel.cpp\ + ../../JGE/src/JParticle.cpp\ + ../../JGE/src/JParticleEffect.cpp\ + ../../JGE/src/JParticleEmitter.cpp\ + ../../JGE/src/JParticleSystem.cpp\ + ../../JGE/src/JResourceManager.cpp\ + ../../JGE/src/JSpline.cpp\ + ../../JGE/src/JNetwork.cpp\ + ../../JGE/src/pc/JSocket.cpp\ + ../../JGE/src/pc/JSfx.cpp\ + ../../JGE/src/JSprite.cpp\ + ../../JGE/src/Vector2D.cpp\ + ../../JGE/src/tinyxml/tinystr.cpp\ + ../../JGE/src/tinyxml/tinyxml.cpp\ + ../../JGE/src/tinyxml/tinyxmlerror.cpp\ + ../../JGE/src/tinyxml/tinyxmlparser.cpp\ + ../../JGE/src/hge/hgecolor.cpp\ + ../../JGE/src/hge/hgedistort.cpp\ + ../../JGE/src/hge/hgefont.cpp\ + ../../JGE/src/hge/hgeparticle.cpp\ + ../../JGE/src/hge/hgerect.cpp\ + ../../JGE/src/hge/hgevector.cpp\ + ../../JGE/src/zipFS/zfsystem.cpp\ + ../../JGE/src/zipFS/ziphdr.cpp\ + ../../JGE/src/zipFS/zstream.cpp + +HEADERS += \ + ../../JGE/include/Downloader.h\ + ../../JGE/include/Threading.h\ + ../../JGE/include/decoder_prx.h\ + ../../JGE/include/DebugRoutines.h\ + ../../JGE/include/Encoding.h\ + ../../JGE/include/JAnimator.h\ + ../../JGE/include/JApp.h\ + ../../JGE/include/JAssert.h\ + ../../JGE/include/JCooleyesMP3.h\ + ../../JGE/include/JDistortionMesh.h\ + ../../JGE/include/JFileSystem.h\ + ../../JGE/include/JGameLauncher.h\ + ../../JGE/include/JGameObject.h\ + ../../JGE/include/JGE.h\ + ../../JGE/include/JGui.h\ + ../../JGE/include/JLBFont.h\ + ../../JGE/include/JLogger.h\ + ../../JGE/include/JMD2Model.h\ + ../../JGE/include/JMP3.h\ + ../../JGE/include/JNetwork.h\ + ../../JGE/include/JOBJModel.h\ + ../../JGE/include/JParticleEffect.h\ + ../../JGE/include/JParticleEmitter.h\ + ../../JGE/include/JParticle.h\ + ../../JGE/include/JParticleSystem.h\ + ../../JGE/include/JRenderer.h\ + ../../JGE/include/JResourceManager.h\ + ../../JGE/include/JSocket.h\ + ../../JGE/include/JSoundSystem.h\ + ../../JGE/include/JSpline.h\ + ../../JGE/include/JSprite.h\ + ../../JGE/include/JTypes.h\ + ../../JGE/include/Vector2D.h\ + ../../JGE/include/Vector3D.h\ + ../../JGE/include/vram.h\ + ../../JGE/include/hge/hgecolor.h\ + ../../JGE/include/hge/hgedistort.h\ + ../../JGE/include/hge/hgefont.h\ + ../../JGE/include/hge/hgeparticle.h\ + ../../JGE/include/hge/hgerect.h\ + ../../JGE/include/hge/hgevector.h\ + ../../JGE/src/unzip/unzip.h\ + ../../JGE/src/unzip/ioapi.h\ + ../../JGE/src/zipFS/zstream_zlib.h\ + ../../JGE/src/zipFS/zfsystem.h\ + ../../JGE/src/zipFS/zstream.h\ + ../../JGE/src/zipFS/ziphdr.h\ + ../../JGE/src/zipFS/stdafx.h\ + ../../JGE/src/zipFS/fileio.h\ + ../../JGE/src/tinyxml/tinystr.h\ + ../../JGE/src/tinyxml/tinyxml.h\ + ../../JGE/include/vram.h + +# maemo 5 packaging +maemo5: { + # Variables + BINDIR = /opt/wagic/bin + RESDIR = /home/user/wagic/Res + USERDIR = MyDocs/.Wagic + ICONDIR = /usr/share + + DEFINES += RESDIR=\\\"$$RESDIR\\\" + DEFINES += USERDIR=\\\"$$USERDIR\\\" + + INSTALLS += target \ + desktop \ + icon + + target.path = $$BINDIR + + desktop.path = $$ICONDIR/applications/hildon + desktop.files += wagic.desktop + + icon.path = $$ICONDIR/icons/hicolor/64x64/apps + icon.files += wagic-64x64.png + +# Meego/maemo 6 packaging (no launcher) +} else:contains(MEEGO_EDITION,harmattan): { + # Variables + BINDIR = /opt/wagic/bin + RESDIR = /opt/wagic/Res + USERDIR = MyDocs/.Wagic + ICONDIR = /usr/share + + DEFINES += RESDIR=\\\"$$RESDIR\\\" + DEFINES += USERDIR=\\\"$$USERDIR\\\" + + INSTALLS += target \ + desktop \ + icon \ + policy + + target.path = $$BINDIR + + desktop.path = /usr/share/applications + desktop.files += debian_harmattan/wagic.desktop + + icon.files = wagic-80x80.png + icon.path = /usr/share/icons/hicolor/64x64/apps + + policy.files = debian_harmattan/wagic.conf + policy.path = /usr/share/policy/etc/syspart.conf.d + +} else:symbian { + TARGET.UID3 = 0xE1D807D3 + + # Smart Installer package's UID + # This UID is from the protected range + # and therefore the package will fail to install if self-signed + # By default qmake uses the unprotected range value if unprotected UID is defined for the application + # and 0x2002CCCF value if protected UID is given to the application + #symbian:DEPLOYMENT.installer_header = 0x2002CCCF + + # Allow network access on Symbian... that's probably pointless + TARGET.CAPABILITY += NetworkServices + + RESDIR = some/res/dir + USERDIR = .Wagic + DEFINES += RESDIR=\"$$RESDIR\" + DEFINES += USERDIR=\"$$USERDIR\" + ICON = wagic.svg +} else:android { + DEFINES += Q_WS_ANDROID + RESDIR = Res + USERDIR = /sdcard/Wagic/Res + DEFINES += RESDIR=\\\"$$RESDIR\\\" + DEFINES += USERDIR=\\\"$$USERDIR\\\" +} else:unix { + # Variables + BINDIR = /usr/bin + ICONDIR = /usr/share + RESDIR = Res + USERDIR = .Wagic + + DEFINES += RESDIR=\\\"$$RESDIR\\\" + DEFINES += USERDIR=\\\"$$USERDIR\\\" + + target.path = $$BINDIR + + desktop.path = $$ICONDIR/applications + desktop.files += wagic.desktop + + icon.path = $$ICONDIR/icons/hicolor/64x64/apps + icon.files += wagic-64x64.png + + INSTALLS += target \ + desktop \ + icon + +} else:windows { + RESDIR = ./Res + USERDIR = .Wagic + DEFINES += RESDIR=\\\"$$RESDIR\\\" + DEFINES += USERDIR=\\\"$$USERDIR\\\" +} + + + + diff --git a/travis-script.sh b/travis-script.sh index 17f0fbdec..244d7c19a 100755 --- a/travis-script.sh +++ b/travis-script.sh @@ -1,5 +1,39 @@ #!/bin/sh -ex +# let's dump some info to debug a bit +echo PSPDEV = $PSPDEV +echo psp-config = `psp-config --psp-prefix` +echo ls = `ls` +echo pwd = `pwd` +# computing potential release name +echo TRAVIS_PULL_REQUEST = $TRAVIS_PULL_REQUEST +echo TRAVIS_BRANCH = $TRAVIS_BRANCH + +if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then +if [ "$TRAVIS_BRANCH" = "alphas" ]; then + export RELEASE_NAME="alpha-${TRAVIS_BUILD_NUMBER}" +else if [ "$TRAVIS_BRANCH" = "master" ]; then + export RELEASE_NAME="latest-master" +fi +fi +fi + +echo RELEASE_NAME = $RELEASE_NAME + + +# updating versions with the TRAVIS build numbers +cd projects/mtg/ +ant update > error.txt +cd ../.. + +# we create resource package +cd projects/mtg/bin/Res +python createResourceZip.py +# if we let the zip here, Wagic will use it in the testsuite +# and we'll get 51 failed test cases +mv core_*.zip ../../../../core.zip +cd ../../../.. + # we're building a PSP binary here cd JGE make -j 8 @@ -7,6 +41,18 @@ cd .. cd projects/mtg mkdir objs make -j 8 +mkdir WTH +mkdir WTH/Res +mv EBOOT.PBP WTH/ +mv ../../JGE/exceptionHandler/prx/exception.prx WTH/ +cp ../../core.zip WTH/Res +cd WTH/Res +unzip core.zip +rm core.zip +cd .. +chmod -R 775 Res +cd .. +zip psprelease.zip -r WTH/ cd ../.. # we're building an Android binary here @@ -26,5 +72,28 @@ cd .. qmake projects/mtg/wagic-qt.pro CONFIG+=console CONFIG+=debug DEFINES+=CAPTURE_STDERR make -j 8 -# and finish by running the testsuite -./wagic +# we're cross-compiling a Qt Windows version here, +# PATH is only set here to prevent colision +export PATH="$PATH:/opt/mingw32/bin" +mkdir build +cd build +mkdir win-cross +cd win-cross +/opt/mingw32/bin/qmake ../../projects/mtg/wagic-qt.pro CONFIG+=release CONFIG+=graphics +make -j 8 +cd release +cp ../../../projects/mtg/bin/fmod.dll . +cp /opt/mingw32/bin/QtCore4.dll . +cp /opt/mingw32/bin/QtGui4.dll . +cp /opt/mingw32/bin/QtNetwork4.dll . +cp /opt/mingw32/bin/QtOpenGL4.dll . +cp ../../../projects/mtg/bin/zlib1.dll . +cp /opt/mingw32/bin/libpng15-15.dll . +cd .. +zip win-cross.zip -r release/ +cd ../.. + +# Now we run the testsuite (Res needs to be in the working directory) +cd projects/mtg +../../wagic +cd ../.. diff --git a/upload-binaries.sh b/upload-binaries.sh new file mode 100755 index 000000000..a558ccbb9 --- /dev/null +++ b/upload-binaries.sh @@ -0,0 +1,99 @@ +if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then +if [ "$TRAVIS_BRANCH" == "alphas" ]; then + echo -e "Creating a release\n" + curl -X POST -H "Authorization: token ${GH_TOKEN}" \ + -d '{"tag_name": "alpha-'${TRAVIS_BUILD_NUMBER}'", "target_commitish": "master", "name": "Alpha release number '${TRAVIS_BUILD_NUMBER}'", "body": "Automatic alpha release generated by Travis CI", "draft": false, "prerelease": true}' "https://api.github.com/repos/WagicProject/wagic/releases" > json.txt + IDDI=`cat json.txt | jq '.id'` + + echo -e "Uploading Core resources\n" + curl -X POST -H "Authorization: token ${GH_TOKEN}" \ + -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/zip" \ + --data-binary @core.zip \ + "https://uploads.github.com/repos/WagicProject/wagic/releases/${IDDI}/assets?name=Wagic-core.zip" + + echo -e "Uploading android package\n" + curl -X POST -H "Authorization: token ${GH_TOKEN}" \ + -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/zip" \ + --data-binary @projects/mtg/Android/bin/Wagic-debug.apk \ + "https://uploads.github.com/repos/WagicProject/wagic/releases/${IDDI}/assets?name=Wagic-android.apk" + + echo -e "Uploading PSP package\n" + curl -X POST -H "Authorization: token ${GH_TOKEN}" \ + -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/zip" \ + --data-binary @projects/mtg/psprelease.zip \ + "https://uploads.github.com/repos/WagicProject/wagic/releases/${IDDI}/assets?name=Wagic-psp.zip" + + echo -e "Uploading Windows package\n" + curl -X POST -H "Authorization: token ${GH_TOKEN}" \ + -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/zip" \ + --data-binary @build/win-cross/win-cross.zip \ + "https://uploads.github.com/repos/WagicProject/wagic/releases/${IDDI}/assets?name=Wagic-windows.zip" + + echo -e "Done uploading\n" +fi +fi + +if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then +if [ "$TRAVIS_BRANCH" == "master" ]; then + + # get info about all releases + echo -e "Getting info about previous releases" + curl -X GET -H "Authorization: token ${GH_TOKEN}" \ + "https://api.github.com/repos/WagicProject/wagic/releases" > json.txt + + # extract info only about only "latest-release" tag + cat json.txt |jq 'map(select (.tag_name == "latest-master"))' > latest.txt + + # get id of release + ID_TO_DELETE=`cat latest.txt |jq '.[0].id'` + + # delete previous release + echo -e "Deleting release number ${ID_TO_DELETE}" + curl -X DELETE -H "Authorization: token ${GH_TOKEN}" \ + "https://api.github.com/repos/WagicProject/wagic/releases/${ID_TO_DELETE}" + + # delete previous tag + curl -X DELETE -H "Authorization: token ${GH_TOKEN}" \ + "https://api.github.com/repos/WagicProject/wagic/git/refs/tags/latest-master" + + + echo -e "Creating a release\n" + curl -X POST -H "Authorization: token ${GH_TOKEN}" \ + -d '{"tag_name": "latest-master", "target_commitish": "master", "name": "master-'${TRAVIS_BUILD_NUMBER}'", "body": "Automatic release based on latest commit to master branch generated by Travis CI", "draft": false, "prerelease": true}' "https://api.github.com/repos/WagicProject/wagic/releases" > json.txt + IDDI=`cat json.txt | jq '.id'` + + echo -e "Uploading Core resources\n" + curl -X POST -H "Authorization: token ${GH_TOKEN}" \ + -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/zip" \ + --data-binary @core.zip \ + "https://uploads.github.com/repos/WagicProject/wagic/releases/${IDDI}/assets?name=Wagic-core.zip" + + echo -e "Uploading android package\n" + curl -X POST -H "Authorization: token ${GH_TOKEN}" \ + -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/zip" \ + --data-binary @projects/mtg/Android/bin/Wagic-debug.apk \ + "https://uploads.github.com/repos/WagicProject/wagic/releases/${IDDI}/assets?name=Wagic-android.apk" + + echo -e "Uploading PSP package\n" + curl -X POST -H "Authorization: token ${GH_TOKEN}" \ + -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/zip" \ + --data-binary @projects/mtg/psprelease.zip \ + "https://uploads.github.com/repos/WagicProject/wagic/releases/${IDDI}/assets?name=Wagic-psp.zip" + + echo -e "Uploading Windows package\n" + curl -X POST -H "Authorization: token ${GH_TOKEN}" \ + -H "Accept: application/vnd.github.manifold-preview" \ + -H "Content-Type: application/zip" \ + --data-binary @build/win-cross/win-cross.zip \ + "https://uploads.github.com/repos/WagicProject/wagic/releases/${IDDI}/assets?name=Wagic-windows.zip" + + echo -e "Done uploading\n" +fi +fi