Compare commits

...

79 Commits

Author SHA1 Message Date
xawotihs 25c844c1f5 Activates SDL build in travis 2014-02-10 22:57:53 +01:00
xawotihs 34492d9096 Adds Threading implementation on SDL 2014-02-03 23:08:17 +01:00
xawotihs 30d92eb68c Should fix issue #497 with the broken freezing the game. 2014-01-18 22:50:16 +01:00
xawotihs 6e6a0fd5c2 OMG I so hate shells 2014-01-18 16:00:14 +01:00
xawotihs cd4a980182 More debug 2014-01-18 15:26:09 +01:00
xawotihs aad54fd98d Adds debug in build script 2014-01-18 14:57:23 +01:00
xawotihs 6b7a49506c Should fix the stringifying issue 2014-01-18 14:23:26 +01:00
xawotihs 7ecf67c176 And again 2014-01-18 13:37:43 +01:00
xawotihs 77aeb2d0ac Fixed release name 2014-01-18 13:29:50 +01:00
xawotihs 7a9f989104 Adds some URL error log 2014-01-18 12:46:27 +01:00
xawotihs ae06bebd24 Merge branch 'github_downloader' 2014-01-18 12:11:08 +01:00
xawotihs 042fb7b376 Tries to fix Android compilation 2014-01-18 11:18:27 +01:00
xawotihs c3583ade01 Updated resource name and URL for android project 2014-01-17 23:25:48 +01:00
xawotihs f97d9805dd Removed build number in released filename and added computation of resource URL based on release name. 2014-01-17 21:50:10 +01:00
xawotihs 1d33de59a9 Fixed compilation issue 2014-01-12 22:56:53 +01:00
xawotihs 0c4b09891b Removed hardcoded testing values and used 32 bits file size instead of 64 bits. 2014-01-12 22:40:45 +01:00
xawotihs 25955303e7 Adds a Downloader component to JGE able to download and cache files. 2014-01-12 22:16:35 +01:00
Rolzad73 27b75eecb0 Merge pull request #600 from WagicProject/android_build_update
update android build tools version
2014-01-09 12:33:11 -08:00
Rolzad73 e40921cf13 update android build tools version 2014-01-09 14:57:06 -05:00
Rolzad73 083cebcc7e updated credits text 2014-01-09 14:46:58 -05:00
Rolzad73 a722736335 Merge pull request #599 from WagicProject/android_travis_explicit
Attempt to make android tools fetching for TravisCI explicit and futureproof
2014-01-08 08:40:47 -08:00
Rolzad73 c483c20c81 attempt to make android tools fetching for TravisCI explicit and futureproof 2014-01-08 11:14:47 -05:00
Dmitry Panin dec1caa43c Revert "Fixed issue with multiple basic abilities in TargetChooser"
This reverts commit d9816c7ad0.
2014-01-04 18:40:59 -08:00
Dmitry Panin 9526e22118 Fixed grave pact 2014-01-04 18:14:15 -08:00
Dmitry Panin d9816c7ad0 Fixed issue with multiple basic abilities in TargetChooser
E.g. card create[trample;haste] wasn't handled properly
2014-01-04 18:13:22 -08:00
Dmitry Panin 8e327a27df Fixed formatting 2014-01-04 18:13:22 -08:00
xawotihs 43fe67d7d8 Adds executioners_swing tests in _tests.txt 2013-12-31 18:38:30 +01:00
Xawotihs a63991bb4e Merge pull request #598 from bjornsnoen/master
Damager keyword
2013-12-31 09:11:20 -08:00
xawotihs b09db0c60f Removed c++11 warning. 2013-12-22 21:26:06 +01:00
Bjørn Snoen 928ca3497a More code compliance. New tests. 2013-12-21 19:31:32 +01:00
Bjørn Snoen 60219411f6 Coding style compliance 2013-12-21 14:33:44 +01:00
Bjørn Snoen 642f5bb515 Fixed indentation mistakes 2013-12-21 11:18:18 +01:00
Bjørn Snoen 20e878a102 Made damager keyword work. Fixed Executioner's Swing in mtg.txt 2013-12-21 11:05:15 +01:00
xawotihs da31371d86 Include c++11 threading 2013-12-20 18:39:02 +01:00
xawotihs 0df408793a Tries to fix android sdk installation in Travis 2013-12-20 14:09:30 +01:00
xawotihs 9630bcd56b Removed file wrongly added. 2013-12-20 12:37:25 +01:00
xawotihs 3c38e21b25 Merge branch 'master' into Qt5.2_macx 2013-12-20 11:14:10 +01:00
xawotihs caec886e22 Fixed issues found by XCode. 2013-12-20 00:24:08 +01:00
Dmitry Panin 927f8955e9 Merge pull request #596 from bjornsnoen/master
Fix a rarity mistake and a grammatical error
2013-12-19 02:44:38 -08:00
Bjørn Snoen d4e0296d2b Fixed wrong rarity on millstone in M14 2013-12-18 09:37:20 +01:00
Bjørn Snoen 8eb664f93d Fixed grammatical then/than error. 2013-12-18 05:50:30 +01:00
xawotihs b180c3d1a7 Fixed Qt5 mingw32 build 2013-12-16 22:11:28 +01:00
Dmitry Panin db9f18a644 Added _cards.dat for M14 (taken from forum) 2013-12-15 22:39:08 +04:00
xawotihs 95805ea387 Fixed QT mingw cross compile with QT4.8 2013-12-15 00:26:04 +01:00
xawotihs 4765890d0a Fixed mouse input with retina display 2013-12-14 23:46:23 +01:00
Xawotihs 2e13f29945 Update README.md 2013-12-14 19:13:26 +01:00
xawotihs 22b1c3b5d8 Fixed zip permission while rezipping PSP package 2013-12-14 14:40:26 +01:00
xawotihs c7bae65697 Fixed core unzip 2013-12-14 13:18:11 +01:00
xawotihs 2381f0306c Fixed paths 2013-12-14 12:06:51 +01:00
xawotihs b12e15e4ff Tries to arrange a bit the PSP binary package to make it more usual for users. 2013-12-14 11:55:12 +01:00
xawotihs 9e21751e12 Fixed windows build upload 2013-12-13 22:54:40 +01:00
xawotihs db60c38eda Added windows build 2013-12-13 23:07:17 +01:00
xawotihs 1a4327a2e6 Fixed mingw32 build linking 2013-12-13 21:54:43 +01:00
xawotihs 88095c67b8 Fixed mingw32 compilation 2013-12-13 21:27:40 +01:00
xawotihs ec34380668 Fixed mingw gcc package name 2013-12-13 00:12:32 +01:00
xawotihs 89dcd6c71d Added some windows cross compiling of the Qt flavor. 2013-12-12 17:54:43 -05:00
Dmitry Panin fd3cf574cf Remove previous tag "latest-master" before uploading new one 2013-12-12 21:08:39 +04:00
Dmitry Panin f21452feec Fixed some Cards:
Rune-Tail, Kitsune Ascendant
Shifting Sky
Flourishing Defenses (thanks to Shadowfireomega)
2013-12-12 20:11:35 +04:00
Dmitry Panin 0f85471216 Enabled automatic releases for each commit in master 2013-12-12 02:20:14 +04:00
Tobias Loose 5d92553017 Fix bug where the phase wheel got out of sync
The phase wheel messures phases within another unit and not
mtg phases. It is important to map between those
2013-12-11 01:53:05 +01:00
xawotihs f0e6d820c7 Fixed GuiPhaseBar logics. 2013-12-10 22:23:28 +01:00
xawotihs 545fc21260 Merge branch 'more_easing' of https://github.com/ZobyTwo/wagic into ZobyTwo-more_easing 2013-12-10 20:35:47 +01:00
Xawotihs 8b68568106 Merge pull request #585 from bjornsnoen/master
Added Avatar Tokens created by Ajani Goldmane.
2013-12-10 11:12:33 -08:00
xawotihs 739a5d9e2b Removed env traces and change the secure token as it was exposed. 2013-12-09 22:39:25 +01:00
Tobias Loose 4c627f74b6 Add easing to GuiPhaseBar, simplify math a bit. 2013-12-09 22:20:43 +01:00
Tobias Loose 1e610ff653 Add InQuadEasing and OutQuadEasing and make tasklists...
easing more natural
2013-12-09 22:20:43 +01:00
Tobias Loose 5d6557a49f Add easing to task list and fix a bug where
opening the task list a second time was not possible
2013-12-09 22:20:43 +01:00
xawotihs 7528329a58 Add more debug in travis script 2013-12-09 21:54:55 +01:00
xawotihs c62597dce5 Add some debugging to Travis script 2013-12-09 21:43:26 +01:00
Xawotihs d8dfcdba67 Merge pull request #583 from ZobyTwo/deck_viewer_1
Cleanup, usability fixes and source code documentation for DeckView.h and GridDeckView.h
2013-12-09 11:51:40 -08:00
Bjørn Snoen 7b5f00260b Added Avatar Tokens created by Ajani Goldmane. 2013-12-09 16:55:31 +01:00
Tobias Loose f9dc551942 Fix logic error in grid view 2013-12-08 23:05:06 +01:00
Tobias Loose 718ceca919 Do not allow that the selection moves outside in grid view. 2013-12-08 22:43:03 +01:00
xawotihs 89fb76a8e7 Updated scripts to remove any modified artifacts from Res directory.
Not doing it causes side effects on the testsuite.
2013-12-08 12:16:25 +01:00
Tobias Loose 1cc65ab611 Enable rotating over multiple filters, add src code doc 2013-12-08 12:03:13 +01:00
xawotihs 3b22354ad9 Fixed testsuite 2013-12-08 11:36:18 +01:00
Tobias Loose 2b9977a334 Rename methods for consistency and add source code doc
to DeckView.h
2013-12-08 10:48:15 +01:00
Tobias Loose 12c5f31562 Add a buttonMode to grid view to enable it on pointerless devices. 2013-12-08 09:11:44 +01:00
xawotihs 8cfd887375 Fixed upload script 2013-12-08 01:10:29 +01:00
66 changed files with 3151 additions and 361 deletions
+10 -4
View File
@@ -1,24 +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"
install:
- 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; fi
- 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 -a
- echo yes | $ANDROID update sdk -a --filter 1,2,4,18 --no-ui --force > log.txt
- $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: YocijVYZa1oDPviFubPIpmBmXyw0gQ7D0YA6tC01wExXvY+8tGUh1HQ5uXn8LotRZ+Ob5HLHDaCzkKWF8+57ILSMeHrnf6tcRyyeO7wjNY9P7WvSZyCjvqnWzsUN9tiMmsEzhTz2MaUgsY6ocB/4nbWZwfQvL7z+s7z41R4J1I4=
secure: "fJgWlCFbde96OSQNGKUmowGX+ERPeqP+n1EOMf1+FJzOU4DdkTLRAlV5+5qnEX9jB/3mWN6iPpmG1qEz/SdDG3KHxJYs4ZU/Lu485O24zZ/+GdYBNsrvhPD9ckPGEMLDa1foEVTDnW0Dlkz3BCFcszjhtXGUJv7v6Pj6LRk1Mg8="
script: "./travis-script.sh"
after_success: ./upload-binaries.sh
+128
View File
@@ -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 <string>
#include <ostream>
#include <istream>
#include <fstream>
#include <map>
#include "Threading.h"
#ifdef QT_CONFIG
#include <QObject>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#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&currentSize) {
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<string, DownloadRequest*> 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
-1
View File
@@ -297,7 +297,6 @@ public:
private:
float mTimer;
float mFrameTime;
JAnimator* mAnimator;
vector<JAnimatorObject *> mObjects;
};
-1
View File
@@ -37,7 +37,6 @@ private:
float mTexY;
float mTexWidth;
float mTexHeight;
JTexture* mTexture;
JQuad* mQuad;
+2 -1
View File
@@ -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
#endif
+309 -15
View File
@@ -1,7 +1,7 @@
#ifndef THREADING_H
#define THREADING_H
#if !defined(PSP) && !defined(QT_CONFIG)
#if !defined(PSP) && !defined(QT_CONFIG) && !(__cplusplus > 199711L) && !defined(SDL_CONFIG)
#include <boost/date_time.hpp>
#ifdef WIN32
@@ -14,7 +14,7 @@
#endif
#include <boost/thread/mutex.hpp>
#elif !defined(QT_CONFIG)
#elif defined(PSP)
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
@@ -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 <class Mutex>
@@ -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<FOO*>(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<FOO*>(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 <QMutex>
#include <QThread>
@@ -537,6 +537,300 @@ namespace boost
}
}
#elif (__cplusplus > 199711L)
#include <thread>
#include <mutex>
namespace boost
{
typedef std::thread thread;
template <class Mutex>
struct unique_lock
{
unique_lock(Mutex& inMutex) : mMutex(&inMutex)
{
mMutex->lock();
}
~unique_lock()
{
mMutex->unlock();
}
Mutex* mMutex;
};
class mutex
{
public:
typedef unique_lock<mutex> 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));
}
}
}
#elif defined(SDL_CONFIG)
#include "SDL_thread.h"
#include "SDL_timer.h"
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include "../include/JLogger.h"
namespace boost
{
template <class Mutex>
struct unique_lock
{
unique_lock(Mutex& inMutex) : mMutex(&inMutex)
{
mMutex->lock();
}
~unique_lock()
{
mMutex->unlock();
}
Mutex* mMutex;
};
class mutex
{
public:
typedef unique_lock<mutex> scoped_lock;
mutex()
: mpSDLMutex(0)
{
mpSDLMutex = SDL_CreateMutex();
}
~mutex()
{
SDL_DestroyMutex(mpSDLMutex);
}
void lock()
{
SDL_mutexP(mpSDLMutex);
}
void unlock()
{
SDL_mutexV(mpSDLMutex);
}
SDL_mutex* mpSDLMutex;
private:
mutex(mutex const&);
mutex& operator=(mutex const&);
};
class recursive_mutex
{
public:
typedef unique_lock<recursive_mutex> scoped_lock;
recursive_mutex()
: mpSDLMutex(0)
{
mpSDLMutex = SDL_CreateMutex();
}
~recursive_mutex()
{
SDL_DestroyMutex(mpSDLMutex);
}
void lock()
{
SDL_mutexP(mpSDLMutex);
}
void unlock()
{
SDL_mutexV(mpSDLMutex);
}
SDL_mutex* mpSDLMutex;
private:
recursive_mutex(recursive_mutex const&);
recursive_mutex& operator=(recursive_mutex const&);
};
/**
** Emulating boost::thread configuration glue, with some shortcuts
** This detail namespace is a distillation of boost's thread.hpp, thread_data.hpp.
*/
namespace detail
{
struct thread_data_base
{
thread_data_base()
{
}
virtual ~thread_data_base()
{
}
virtual void run() = 0;
};
typedef boost::shared_ptr<detail::thread_data_base> thread_data_ptr;
template<typename F>
class thread_data : public detail::thread_data_base
{
public:
thread_data(F f_) : f(f_)
{
}
void run()
{
f();
}
private:
F f;
void operator=(thread_data&);
thread_data(thread_data&);
};
} //namespace detail
/**
** A simplistic implementation of boost::thread, using QThread.
**
*/
class thread
{
/*
** 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
{
CallbackData(detail::thread_data_ptr inThreadInfo)
: mThreadInfo(inThreadInfo)
{
}
detail::thread_data_ptr mThreadInfo;
};
public:
thread()
{
}
template <class F,class A1>
thread(F f, A1 a1) : mThreadInfo(make_thread_info(boost::bind(boost::type<void>(), f, a1)))
{
mpSDLThread = SDL_CreateThread(ThreadProc, &mThreadInfo);
}
~thread()
{
}
void join()
{
int status;
SDL_WaitThread(mpSDLThread, &status);
}
private:
static int ThreadProc(void *inParam)
{
detail::thread_data_ptr* threadInfo = reinterpret_cast<detail::thread_data_ptr* >(inParam);
CallbackData callbackData(*threadInfo);
LOG("Entering thread::ThreadProc");
callbackData.mThreadInfo->run();
return 0;
}
template<typename F>
static inline detail::thread_data_ptr make_thread_info(F f)
{
return detail::thread_data_ptr(new detail::thread_data<F>(f));
}
detail::thread_data_ptr mThreadInfo;
SDL_Thread* mpSDLThread;
};
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)
{
SDL_Delay(time);
}
}
}
#endif
#endif // THREADING_H
+15
View File
@@ -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;
+298
View File
@@ -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<string, DownloadRequest*>::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<string, DownloadRequest*>::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<std::map<string,DownloadRequest*>::iterator,bool> ret;
ret = mRequestMap.insert ( std::pair<string,DownloadRequest*>(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 <<endl;
}
return out;
}
istream& operator>>(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<string, DownloadRequest*>::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;
}
+11 -1
View File
@@ -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)
+18 -11
View File
@@ -9,11 +9,11 @@
#include <QtDeclarative>
#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<WagicCore>("CustomComponents", 1, 0, "WagicCore");
+14 -1
View File
@@ -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
+28 -28
View File
@@ -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()<m_viewPort.top()) {
} else if(lastPosy()<m_viewPort.top()) {
m_engine->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);
+2
View File
@@ -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);
+1 -1
View File
@@ -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")
@@ -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();
@@ -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();
+5
View File
@@ -1513,3 +1513,8 @@ primitive=Zephyr Net
id=142357
rarity=C
[/card]
[card]
primitive=Avatar Token
id=-140233
rarity=T
[/card]
+5
View File
@@ -1248,3 +1248,8 @@ primitive=Zombie Goliath
id=190545
rarity=C
[/card]
[card]
primitive=Avatar Token
id=-191239
rarity=T
[/card]
+6 -1
View File
@@ -1257,4 +1257,9 @@ rarity=U
primitive=Yavimaya Wurm
id=205221
rarity=C
[/card]
[/card]
[card]
primitive=Avatar Token
id=-205957
rarity=T
[/card]
File diff suppressed because it is too large Load Diff
+6 -10
View File
@@ -28204,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
@@ -31457,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
@@ -37166,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
@@ -73586,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
@@ -78444,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
@@ -104302,4 +104298,4 @@ type=Land Creature
subtype=Forest Dryad
power=1
toughness=1
[/card]
[/card]
+3
View File
@@ -308,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
@@ -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]
@@ -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]
@@ -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]
+4 -2
View File
@@ -3,7 +3,7 @@
<property file="build.properties" />
<property file="build.number.properties" />
<property environment="env"/>
<path id="groovy.class.path" >
<fileset dir="${groovy.dir}" />
</path>
@@ -90,7 +90,9 @@ Author: Michael Nguyen
#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
+1
View File
@@ -64,6 +64,7 @@ class CardDescriptor: public MTGCardInstance
string compareName;
int CDopponentDamaged;
int CDcontrollerDamaged;
int CDdamager;
};
#endif
+7 -4
View File
@@ -11,6 +11,7 @@ private:
static const float x_center;
static const float right_border;
static const float slide_animation_duration;
static const float scroll_animation_duration;
public:
CarouselDeckView();
@@ -18,19 +19,21 @@ public:
void Reset();
void UpdateViewState(float dt);
void UpdateCardPosition(CardRep &rep, int index);
void UpdateCardPosition(int index);
void renderCard(int index)
{
int alpha = (int) (255 * (getCardRep(index).scale + 1.0 - max_scale));
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 changePosition(int offset);
void changeFilter(int offset);
void changePositionAnimated(int offset);
void changeFilterAnimated(int offset);
MTGCard *getActiveCard();
private:
+190 -12
View File
@@ -9,55 +9,233 @@
#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;
public:
/*! \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();
//advances the view and card representations
/*! \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);
virtual void SetDeck(DeckDataWrapper *toShow);
/*! \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();
void SwitchFilter(int delta);
void SwitchPosition(int delta);
/*! \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;
bool ButtonPressed(Buttons button);
/*! \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;
virtual void changePosition(int offset) = 0;
virtual void changeFilter(int offset) = 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<CardRep> mCards;
CardRep& getCardRep(unsigned int index);
/*! \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;
virtual void UpdateCardPosition(CardRep& rep, int index) = 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_
+45 -1
View File
@@ -95,7 +95,7 @@ public:
*/
void update(float dt)
{
if(duration > 0)
if(time_acc < duration)
{
time_acc += dt;
@@ -167,6 +167,50 @@ public:
}
};
/*! \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
-1
View File
@@ -17,7 +17,6 @@ private:
WSrcCards * setSrc;
SimpleMenu * menu;
bool showMenu;
bool showAlt;
bool saveMe;
int mState;
int mDetailItem;
-1
View File
@@ -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;
+122 -6
View File
@@ -4,6 +4,15 @@
#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:
@@ -12,27 +21,134 @@ private:
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);
void UpdateCardPosition(CardRep &rep, int index);
/*! \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);
void changePosition(int offset);
void changeFilter(int offset);
/*! \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:
int mCols;
int mRows;
float mScrollOffset, mSlideOffset;
/*! \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
+13 -3
View File
@@ -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();
-1
View File
@@ -47,7 +47,6 @@ protected:
{
static const float HEIGHT;
unsigned attackers;
unsigned blockers;
unsigned currentAttacker;
float height;
+1
View File
@@ -65,6 +65,7 @@ public:
bool wasDealtDamage;
bool damageToOpponent;
bool damageToController;
bool damageToCreature;
bool mPropertiesChangedSinceLastUpdate;
int reduxamount;
int flanked;
-1
View File
@@ -20,7 +20,6 @@ class SimplePopup: public JGuiController
private:
float mWidth, mX, mY;
int mMaxLines;
int mFontId;
DeckMetaData * mDeckInformation;
string mTitle;
WFont *mTextFont;
+11 -2
View File
@@ -2,8 +2,15 @@
#define TASK_H
#include <vector>
#include <string>
#include "Easing.h"
using namespace std;
class GameObserver;
class JQuad;
class JTexture;
// Task type constant
@@ -72,8 +79,11 @@ class TaskList
{
protected:
string fileName;
float vPos;
float mElapsed;
OutQuadEasing vPosInEasing;
InQuadEasing vPosOutEasing;
int mState;
JQuad * mBg[9];
JTexture * mBgTex;
@@ -97,7 +107,6 @@ public:
{
return mState;
}
;
void addTask(string params, bool rand = false);
void addTask(Task *task);
void addRandomTask(int diff = 100);
+4 -4
View File
@@ -1,12 +1,12 @@
#ifndef WRESOURCE_FWD_H
#define WRESOURCE_FWD_H
#ifndef WP8
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr<JQuad> JQuadPtr;
#else
#if (__cplusplus > 199711L)
#include <memory>
typedef std::shared_ptr<JQuad> JQuadPtr;
#else
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr<JQuad> JQuadPtr;
#endif
#endif
+1 -1
View File
@@ -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
+1 -1
View File
@@ -314,7 +314,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++)
+2 -2
View File
@@ -445,7 +445,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;
@@ -853,7 +853,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;
}
+6 -9
View File
@@ -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";
}
@@ -5708,7 +5704,8 @@ void ATutorialMessage::Update(float dt)
mElapsed += dt;
IconButtonsController::Update(dt);
if(!mUserCloseRequest)
IconButtonsController::Update(dt);
if (mIsImage)
return;
+19 -7
View File
@@ -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;
}
+12
View File
@@ -1224,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?
+59 -25
View File
@@ -4,6 +4,7 @@ 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)
@@ -21,12 +22,12 @@ void CarouselDeckView::UpdateViewState(float dt)
if(mScrollOffset <= -1.0f)
{
SwitchPosition(-1);
changePosition(-1);
mScrollEasing.translate(1.0f);
}
else if(mScrollOffset >= 1.0f)
{
SwitchPosition(1);
changePosition(1);
mScrollEasing.translate(-1.0f);
}
@@ -43,7 +44,7 @@ void CarouselDeckView::UpdateViewState(float dt)
if(mSlideOffset < -1.0f)
{
mSlideEasing.translate(2.0f);
SwitchFilter(1);
changeFilter(1);
}
}
else if(mSlideOffset > mSlideEasing.start_value)
@@ -52,7 +53,7 @@ void CarouselDeckView::UpdateViewState(float dt)
if(mSlideOffset > 1.0f)
{
mSlideEasing.translate(-2.0f);
SwitchFilter(-1);
changeFilter(-1);
}
}
@@ -60,8 +61,10 @@ void CarouselDeckView::UpdateViewState(float dt)
}
}
void CarouselDeckView::UpdateCardPosition(CardRep &rep, int index)
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);
@@ -84,13 +87,13 @@ void CarouselDeckView::Render()
// in a different order, ie the center card should appear first, then the adjacent ones
if (WResourceManager::Instance()->IsThreaded())
{
WResourceManager::Instance()->RetrieveCard(getCardRep(0).card);
WResourceManager::Instance()->RetrieveCard(getCardRep(3).card);
WResourceManager::Instance()->RetrieveCard(getCardRep(4).card);
WResourceManager::Instance()->RetrieveCard(getCardRep(2).card);
WResourceManager::Instance()->RetrieveCard(getCardRep(5).card);
WResourceManager::Instance()->RetrieveCard(getCardRep(1).card);
WResourceManager::Instance()->RetrieveCard(getCardRep(6).card);
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);
@@ -118,6 +121,31 @@ void CarouselDeckView::Render()
}
}
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);
@@ -132,35 +160,41 @@ MTGCard * CarouselDeckView::Click(int x, int y)
}
else
{
changePosition(n - 2);
changePositionAnimated(n - 2);
}
}
return NULL;
}
void CarouselDeckView::changePosition(int offset)
MTGCard *CarouselDeckView::Click()
{
mScrollEasing.start((float)offset, (float)(0.3f*abs(offset)));
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::changeFilter(int offset)
void CarouselDeckView::changeFilterAnimated(int offset)
{
if(offset < 0)
{
mSlideEasing.start(-2.0f, slide_animation_duration);
}
else if(offset > 0)
{
mSlideEasing.start(2.0f, slide_animation_duration);
}
if(mSlideEasing.finished())
mSlideEasing.start(2.0f * float(offset), float(slide_animation_duration * abs(offset)));
last_user_activity = 0;
}
MTGCard *CarouselDeckView::getActiveCard()
{
return getCardRep(2).card;
return mCards[2].card;
}
+1 -1
View File
@@ -386,7 +386,7 @@ void Credits::computeTournament(GameObserver* g, GameApp * _app,bool tournament,
}
if (mGamesWon>mGamesPlayed*0.80 && mGamesWon<mGamesPlayed)
{
CreditBonus * b = NEW CreditBonus(250, _("Won more then 80 percentage of games"));
CreditBonus * b = NEW CreditBonus(250, _("Won more than 80 percentage of games"));
bonus.push_back(b);
}
+3 -1
View File
@@ -192,8 +192,10 @@ int Damage::resolve()
//return the left over amount after effects have been applied to them.
a = target->dealDamage(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())
+5 -36
View File
@@ -35,38 +35,12 @@ void DeckView::Update(float dt)
{
for(unsigned int i = 0; i < mCards.size(); ++i)
{
UpdateCardPosition(mCards[i], i);
UpdateCardPosition(i);
}
dirtyCardPos = false;
}
}
bool DeckView::ButtonPressed(Buttons button)
{
switch(button)
{
case JGE_BTN_LEFT:
changePosition(-1);
last_user_activity = 0;
break;
case JGE_BTN_RIGHT:
changePosition(1);
last_user_activity = 0;
break;
case JGE_BTN_UP:
changeFilter(1);
last_user_activity = 0;
break;
case JGE_BTN_DOWN:
changeFilter(-1);
last_user_activity = 0;
break;
default:
return false;
}
return true;
}
void DeckView::SetDeck(DeckDataWrapper *toShow)
{
mCurrentDeck = toShow;
@@ -80,14 +54,14 @@ DeckDataWrapper* DeckView::deck()
return mCurrentDeck;
}
void DeckView::SwitchFilter(int delta)
void DeckView::changeFilter(int delta)
{
unsigned int FilterCount = Constants::NB_Colors + 1;
mFilter = (FilterCount + mFilter + delta) % FilterCount;
dirtyFilters = true;
}
void DeckView::SwitchPosition(int delta)
void DeckView::changePosition(int delta)
{
for(int i = 0; i < delta; ++i)
{
@@ -118,16 +92,11 @@ void DeckView::reloadIndexes()
}
}
DeckView::CardRep& DeckView::getCardRep(unsigned int index)
{
return mCards[index];
}
void DeckView::renderCard(int index, int alpha, bool asThumbnail)
{
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT);
const CardRep& cardPosition = getCardRep(index);
const CardRep& cardPosition = mCards[index];
if (!cardPosition.card) return;
@@ -213,7 +182,7 @@ int DeckView::getCardIndexNextTo(int x, int y)
for(unsigned int i = 0; i < mCards.size(); i++)
{
const CardRep& cardPosition = getCardRep(i);
const CardRep& cardPosition = mCards[i];
float dx = (x - cardPosition.x);
float dy = (y - cardPosition.y);
+1
View File
@@ -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++)
+28 -17
View File
@@ -407,9 +407,8 @@ void GameStateDeckViewer::Update(float dt)
case JGE_BTN_RIGHT:
case JGE_BTN_UP:
case JGE_BTN_DOWN:
if(last_user_activity > 0.2)
if(mView->ButtonPressed(button))
{
mView->ButtonPressed(button);
last_user_activity = 0;
mStage = STAGE_WAITING;
}
@@ -443,19 +442,21 @@ void GameStateDeckViewer::Update(float dt)
int x, y;
if (mEngine->GetLeftClickCoordinates(x, y))
{
last_user_activity = 0;
mEngine->LeftClickedProcessed();
if(mView->Click(x, y) == mView->getActiveCard())
if(mView->Click(x, y) != NULL)
{
addRemove(mView->getActiveCard());
}
}
else
{
last_user_activity = 0;
addRemove(mView->getActiveCard());
if(mView->Click() != NULL)
{
addRemove(mView->getActiveCard());
}
}
last_user_activity = 0;
mStage = STAGE_WAITING;
break;
}
@@ -468,17 +469,20 @@ 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 (mView->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)
@@ -1527,11 +1531,18 @@ void GameStateDeckViewer::OnScroll(int inXVelocity, int inYVelocity)
{
//FIXME: this 500 is a bit arbitrary
int numCards = (magnitude / 500) % 8;
mView->changePosition(flickRight ? numCards : - numCards);
mView->changePositionAnimated(flickRight ? numCards : - numCards);
}
}
else
mView->changeFilter(flickUp ? 1 : -1);
{
if(abs(inYVelocity) > 300)
{
//FIXME: this 500 is a bit arbitrary
int numFilters = (magnitude / 500);
mView->changeFilterAnimated(flickUp ? numFilters : - numFilters);
}
}
last_user_activity = 0;
}
+1 -1
View File
@@ -796,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);
+17 -12
View File
@@ -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",
+2 -6
View File
@@ -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);
@@ -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;
+109 -24
View File
@@ -7,7 +7,8 @@ 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)
mScrollEasing(mScrollOffset), mSlideEasing(mSlideOffset), mCurrentSelection(-1),
mButtonMode(false)
{
}
@@ -23,6 +24,7 @@ void GridDeckView::Reset()
mScrollEasing.finish();
mCurrentSelection = 0;
mButtonMode = false;
DeckView::Reset();
}
@@ -35,15 +37,15 @@ void GridDeckView::UpdateViewState(float dt)
if(mScrollOffset <= -1.0f)
{
SwitchPosition(2);
changePosition(2);
moveSelection(-2, false);
mScrollEasing.translate(1.0f);
mCurrentSelection = (mCurrentSelection >= 6) ? mCurrentSelection - 2 : -1;
}
else if(mScrollOffset >= 1.0f)
{
SwitchPosition(-2);
changePosition(-2);
moveSelection(2, false);
mScrollEasing.translate(-1.0f);
mCurrentSelection = (mCurrentSelection >= 0 && mCurrentSelection < 10) ? mCurrentSelection + 2 : -1;
}
dirtyCardPos = true;
@@ -56,20 +58,22 @@ void GridDeckView::UpdateViewState(float dt)
if(mSlideOffset < -1.0f)
{
mSlideEasing.translate(2.0f);
SwitchFilter(1);
changeFilter(1);
}
else if(mSlideOffset > 1.0f)
{
mSlideEasing.translate(-2.0f);
SwitchFilter(-1);
changeFilter(-1);
}
dirtyCardPos = true;
}
}
void GridDeckView::UpdateCardPosition(CardRep &rep, int index)
void GridDeckView::UpdateCardPosition(int index)
{
CardRep &rep = mCards[index];
int col = index / mRows;
int row = index % mRows;
float colWidth = SCREEN_WIDTH_F / (mCols - 3);
@@ -119,7 +123,7 @@ void GridDeckView::Render()
{
if (WResourceManager::Instance()->IsThreaded())
{
WResourceManager::Instance()->RetrieveCard(getCardRep(i).card, RETRIEVE_THUMB);
WResourceManager::Instance()->RetrieveCard(mCards[i].card, RETRIEVE_THUMB);
}
renderCard(i, 255, true);
}
@@ -127,7 +131,7 @@ void GridDeckView::Render()
{
if (WResourceManager::Instance()->IsThreaded())
{
WResourceManager::Instance()->RetrieveCard(getCardRep(i).card);
WResourceManager::Instance()->RetrieveCard(mCards[i].card);
}
}
}
@@ -138,10 +142,50 @@ void GridDeckView::Render()
}
}
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
@@ -151,11 +195,11 @@ MTGCard * GridDeckView::Click(int x, int y)
}
else if(n < 4)
{
changePosition(-1);
changePositionAnimated(-1);
}
else if(n >= 12)
{
changePosition(1);
changePositionAnimated(1);
}
else
{
@@ -167,28 +211,43 @@ MTGCard * GridDeckView::Click(int x, int y)
return NULL;
}
void GridDeckView::changePosition(int offset)
MTGCard * GridDeckView::Click()
{
mScrollEasing.start(-1.0f * offset, scroll_animation_duration * abs(offset));
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::changeFilter(int offset)
void GridDeckView::changeFilterAnimated(int offset)
{
if(offset < 0)
{
mSlideEasing.start(-2.0f, slide_animation_duration);
}
else if(offset > 0)
{
mSlideEasing.start(2.0f, slide_animation_duration);
}
if(mSlideEasing.finished())
mSlideEasing.start(2.0f * offset, float(slide_animation_duration * abs(offset)));
last_user_activity = 0;
}
MTGCard* GridDeckView::getActiveCard()
{
if(mCurrentSelection >= 0 && mCurrentSelection < int(mCards.size()))
if(mCurrentSelection >= 4 && mCurrentSelection < int(mCards.size())-4)
{
return mCards[mCurrentSelection].card;
}
@@ -197,3 +256,29 @@ MTGCard* GridDeckView::getActiveCard()
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;
}
+52 -57
View File
@@ -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<float> ((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<float> (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<WEventPhaseChange*> (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;
}
+1 -1
View File
@@ -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;
-2
View File
@@ -4276,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])
{
+1
View File
@@ -158,6 +158,7 @@ void MTGCardInstance::initMTGCI()
auras = 0;
damageToOpponent = false;
damageToController = false;
damageToCreature = false;
wasDealtDamage = false;
isDualWielding = false;
suspended = false;
+1 -1
View File
@@ -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())
+1 -1
View File
@@ -15,7 +15,7 @@
#include <iomanip>
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;
+12
View File
@@ -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?
+18 -14
View File
@@ -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;
}
}
}
+10 -7
View File
@@ -4,11 +4,11 @@ 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
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
@@ -27,6 +27,7 @@ windows{
# 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
@@ -40,8 +41,8 @@ INCLUDEPATH += ../../Boost
INCLUDEPATH += include
unix:!symbian:LIBS += -lz
win32:LIBS += ../../JGE/Dependencies/lib/fmodvc.lib
win32:LIBS += ../../JGE/Dependencies/lib/zlibd.lib
windows:LIBS += ../../JGE/Dependencies/lib/fmodvc.lib
windows:LIBS += ../../JGE/Dependencies/lib/zlibd.lib
PRECOMPILED_HEADER = include/PrecompiledHeader.h
#DEFINES += TRACK_OBJECT_USAGE
@@ -282,6 +283,7 @@ HEADERS += \
# JGE, could probably be moved outside
SOURCES += \
../../JGE/src/Downloader.cpp\
../../JGE/src/Encoding.cpp\
../../JGE/src/JAnimator.cpp\
../../JGE/src/JApp.cpp\
@@ -319,6 +321,7 @@ SOURCES += \
../../JGE/src/zipFS/zstream.cpp
HEADERS += \
../../JGE/include/Downloader.h\
../../JGE/include/Threading.h\
../../JGE/include/decoder_prx.h\
../../JGE/include/DebugRoutines.h\
+66 -13
View File
@@ -1,10 +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
@@ -12,11 +41,18 @@ cd ..
cd projects/mtg
mkdir objs
make -j 8
mkdir psprelease
mv EBOOT.PBP psprelease/
mv wagic.elf psprelease/
mv wagic.prx psprelease/
zip psprelease.zip -r psprelease/
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
@@ -28,7 +64,7 @@ ant debug -f projects/mtg/Android/build.xml
# we're building a Qt version with GUI here
mkdir qt-gui-build
cd qt-gui-build
qmake ../projects/mtg/wagic-qt.pro CONFIG+=release CONFIG+=graphics
qmake ../projects/mtg/wagic-SDL.pro CONFIG+=release CONFIG+=graphics
make -j 8
cd ..
@@ -36,11 +72,28 @@ cd ..
qmake projects/mtg/wagic-qt.pro CONFIG+=console CONFIG+=debug DEFINES+=CAPTURE_STDERR
make -j 8
# Now we run 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 ../..
# And we create resource package (not before testsuite, it mofifies resources)
cd projects/mtg/bin/Res
python createResourceZip.py
mv core_*.zip core.zip
cd ../../../..
# Now we run the testsuite (Res needs to be in the working directory)
cd projects/mtg
../../wagic
cd ../..
+74 -6
View File
@@ -2,29 +2,97 @@ 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
export IDDI=`cat json.txt | jq '.id'`
-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 @projects/mtg/bin/Res/core.zip \
"https://uploads.github.com/repos/WagicProject/wagic/releases/${IDDI}/assets?name=Wagic-core-${TRAVIS_BUILD_NUMBER}.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-${TRAVIS_BUILD_NUMBER}.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-${TRAVIS_BUILD_NUMBER}.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