diff --git a/projects/mtg/bin/Res/ai/baka/avatars/README.txt b/projects/mtg/bin/Res/ai/baka/avatars/README.txt new file mode 100644 index 000000000..a126af978 --- /dev/null +++ b/projects/mtg/bin/Res/ai/baka/avatars/README.txt @@ -0,0 +1,5 @@ +you can put AI avatars in this folder. +they have to be 35x50 pixels, and in jpeg format. + +The naming convention is avatarXX.jpg , where XX is the number of the associated deck. +For example, avatar1.jpg will be the avatar associated to deck1.txt \ No newline at end of file diff --git a/projects/mtg/bin/Res/sets/RV/_cards.dat b/projects/mtg/bin/Res/sets/RV/_cards.dat index 48e20034f..45fc6aadb 100644 --- a/projects/mtg/bin/Res/sets/RV/_cards.dat +++ b/projects/mtg/bin/Res/sets/RV/_cards.dat @@ -2041,7 +2041,7 @@ id=1182 name=Terror rarity=C type=Instant -mana={0} +mana={1}{B} [/card] [card] text=As The Rack comes into play, choose an opponent. At the beginning of the chosen player's upkeep, The Rack deals X damage to that player, where X is 3 minus the number of cards in his or her hand. diff --git a/projects/mtg/bin/Res/settings/options.txt b/projects/mtg/bin/Res/settings/options.txt index b1910a1a6..df2bddd85 100644 --- a/projects/mtg/bin/Res/settings/options.txt +++ b/projects/mtg/bin/Res/settings/options.txt @@ -1,50 +1,50 @@ -100 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 -0 +0 +100 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 diff --git a/projects/mtg/bin/Res/settings/prices.dat b/projects/mtg/bin/Res/settings/prices.dat index ab0969b89..089199af6 100644 --- a/projects/mtg/bin/Res/settings/prices.dat +++ b/projects/mtg/bin/Res/settings/prices.dat @@ -1,92 +1,92 @@ -1167 -460 -1202 -525 -1340 -92 -1284 -101 -1149 -20 -1264 -20 -1321 -20 -1272 -437 -1126 -485 -1334 -107 -1352 -91 -1279 -20 -1154 -481 -1328 -551 -1335 -20 -1227 -500 -1236 -489 -1186 -20 -1219 -20 -1175 -459 -1136 -111 -1332 -545 -1250 -21 -1204 -19 -1381 -499 -1170 -484 -1097 -102 -1102 -46 -1282 -485 -1378 -490 -1300 -20 -1363 -495 -129665 -90 -1387 -4 -129652 -5 -174957 -108 -175030 -5 -130378 -107 -175031 -5 -1312 -19 -130386 -97 -1275 -21 -1148 -103 -135185 -20 -1100 -109 -153441 -19 +1167 +460 +1202 +525 +1340 +92 +1284 +101 +1149 +20 +1264 +20 +1321 +20 +1272 +437 +1126 +485 +1334 +107 +1352 +91 +1279 +20 +1154 +481 +1328 +551 +1335 +20 +1227 +500 +1236 +489 +1186 +20 +1219 +20 +1175 +459 +1136 +111 +1332 +545 +1250 +21 +1204 +19 +1381 +499 +1170 +484 +1097 +102 +1102 +46 +1282 +485 +1378 +490 +1300 +20 +1363 +495 +129665 +90 +1387 +4 +129652 +5 +174957 +108 +175030 +5 +130378 +107 +175031 +5 +1312 +19 +130386 +97 +1275 +21 +1148 +103 +135185 +20 +1100 +109 +153441 +19 diff --git a/projects/mtg/bin/Res/sound/README.txt b/projects/mtg/bin/Res/sound/README.txt new file mode 100644 index 000000000..4148b96e6 --- /dev/null +++ b/projects/mtg/bin/Res/sound/README.txt @@ -0,0 +1,2 @@ +Track0.mp3 and Track1.mp3 have to be in this folder for the music options to be available. +These file must not contain any ID3v2 tag, or they won't play on the PSP. diff --git a/projects/mtg/bin/Res/sound/sfx/README.txt b/projects/mtg/bin/Res/sound/sfx/README.txt new file mode 100644 index 000000000..3295f7eef --- /dev/null +++ b/projects/mtg/bin/Res/sound/sfx/README.txt @@ -0,0 +1,8 @@ +you can put wave files in this folder. +the name of the file can be any ability (flying.wav, trample.wav, lifelink.wav, ...) +or a supertype (artifact.wav, sorcery.wav, creature.wav...) +or a type (human.wav, dragon.wav...) + +The game will automatically use the files ( if they are available) when a card comes into play. + +Special files are mana.wav and graveyard.wav \ No newline at end of file diff --git a/projects/mtg/bin/Res/sound/sfx/artifact.wav b/projects/mtg/bin/Res/sound/sfx/artifact.wav new file mode 100644 index 000000000..061f57c26 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/artifact.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/bear.wav b/projects/mtg/bin/Res/sound/sfx/bear.wav new file mode 100644 index 000000000..1752c196c Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/bear.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/beast.wav b/projects/mtg/bin/Res/sound/sfx/beast.wav new file mode 100644 index 000000000..12568e4c7 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/beast.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/cat.wav b/projects/mtg/bin/Res/sound/sfx/cat.wav new file mode 100644 index 000000000..370ec772a Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/cat.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/creature.wav b/projects/mtg/bin/Res/sound/sfx/creature.wav new file mode 100644 index 000000000..defb14f89 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/creature.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/dragon.wav b/projects/mtg/bin/Res/sound/sfx/dragon.wav new file mode 100644 index 000000000..2a336f8f1 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/dragon.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/enchantment.wav b/projects/mtg/bin/Res/sound/sfx/enchantment.wav new file mode 100644 index 000000000..78966ff28 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/enchantment.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/faerie.wav b/projects/mtg/bin/Res/sound/sfx/faerie.wav new file mode 100644 index 000000000..c2ca50ff7 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/faerie.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/flying.wav b/projects/mtg/bin/Res/sound/sfx/flying.wav new file mode 100644 index 000000000..327c7637e Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/flying.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/goblin.wav b/projects/mtg/bin/Res/sound/sfx/goblin.wav new file mode 100644 index 000000000..6c26e0a79 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/goblin.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/graveyard.wav b/projects/mtg/bin/Res/sound/sfx/graveyard.wav new file mode 100644 index 000000000..e9260c123 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/graveyard.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/human.wav b/projects/mtg/bin/Res/sound/sfx/human.wav new file mode 100644 index 000000000..28cbe3cad Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/human.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/imp.wav b/projects/mtg/bin/Res/sound/sfx/imp.wav new file mode 100644 index 000000000..d5935fb48 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/imp.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/instant.wav b/projects/mtg/bin/Res/sound/sfx/instant.wav new file mode 100644 index 000000000..9d258508a Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/instant.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/knight.wav b/projects/mtg/bin/Res/sound/sfx/knight.wav new file mode 100644 index 000000000..02b51e607 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/knight.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/mana.wav b/projects/mtg/bin/Res/sound/sfx/mana.wav new file mode 100644 index 000000000..ec72676ae Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/mana.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/sorcery.wav b/projects/mtg/bin/Res/sound/sfx/sorcery.wav new file mode 100644 index 000000000..469bbcd97 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/sorcery.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/troll.wav b/projects/mtg/bin/Res/sound/sfx/troll.wav new file mode 100644 index 000000000..482ab9ac1 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/troll.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/vampire.wav b/projects/mtg/bin/Res/sound/sfx/vampire.wav new file mode 100644 index 000000000..3a7386bcf Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/vampire.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/wurm.wav b/projects/mtg/bin/Res/sound/sfx/wurm.wav new file mode 100644 index 000000000..556d7258b Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/wurm.wav differ diff --git a/projects/mtg/bin/Res/sound/sfx/zombie.wav b/projects/mtg/bin/Res/sound/sfx/zombie.wav new file mode 100644 index 000000000..d95b9d922 Binary files /dev/null and b/projects/mtg/bin/Res/sound/sfx/zombie.wav differ diff --git a/projects/mtg/include/AIPlayer.h b/projects/mtg/include/AIPlayer.h index 25adca748..c89a7cfc9 100644 --- a/projects/mtg/include/AIPlayer.h +++ b/projects/mtg/include/AIPlayer.h @@ -29,7 +29,8 @@ class AIPlayer: public Player{ int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0); AIStats * getStats(); public: - virtual int displayStack(){return 0;} + void End(){}; + virtual int displayStack(){return 0;}; AIStats * stats; ManaCost * getPotentialMana(); AIPlayer(MTGPlayerCards * _deck, string deckFile); @@ -48,14 +49,14 @@ class AIPlayerBaka: public AIPlayer{ int timer; MTGCardInstance * FindCardToPlay(ManaCost * potentialMana, const char * type); public: - AIPlayerBaka(MTGPlayerCards * _deck, char * deckFile); + AIPlayerBaka(MTGPlayerCards * _deck, char * deckFile, char * avatarFile); virtual int Act(float dt); void initTimer(); }; class AIPlayerFactory{ public: - AIPlayer * createAIPlayer(MTGAllCards * collection, MTGPlayerCards * oponents_deck); + AIPlayer * createAIPlayer(MTGAllCards * collection, MTGPlayerCards * oponents_deck, int deckid = 0); }; diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 17e3becd9..65da7cc59 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -8,6 +8,7 @@ #include "CardDisplay.h" #include "Subtypes.h" #include "CardGui.h" +#include "GameOptions.h" #include #include @@ -570,6 +571,11 @@ class AManaProducer: public MTGAbility{ y0 = cardg->y + 20; } controller = source->controller(); + + if (GameOptions::GetInstance()->values[OPTIONS_SFXVOLUME] > 0){ + JSample * sample = SampleCache::GetInstance()->getSample("sound/sfx/mana.wav"); + if (sample) JSoundSystem::GetInstance()->PlaySample(sample); + } return 1; } diff --git a/projects/mtg/include/CardGui.h b/projects/mtg/include/CardGui.h index dbfe64924..20142c7e4 100644 --- a/projects/mtg/include/CardGui.h +++ b/projects/mtg/include/CardGui.h @@ -21,7 +21,7 @@ class CardGui: public PlayGuiObject{ virtual void Render(); virtual void Update(float dt); - void RenderBig(float x=-1, float y = -1); + void RenderBig(float x=-1, float y = -1, int alternate = 0); static void alternateRender(MTGCard * card, JLBFont * mFont, JQuad ** manaIcons, float x, float y, float rotation= 0, float scale=1); ~CardGui(); }; diff --git a/projects/mtg/include/DeckStats.h b/projects/mtg/include/DeckStats.h new file mode 100644 index 000000000..dc3473bac --- /dev/null +++ b/projects/mtg/include/DeckStats.h @@ -0,0 +1,36 @@ +#ifndef _DECKSTATS_H_ +#define _DECKSTATS_H_ + + +#include +#include +using namespace std; + +class Player; +class GameObserver; + +class DeckStat{ +public: + int nbgames; + int victories; + DeckStat(int _nbgames = 0 , int _victories = 0):nbgames(_nbgames),victories(_victories){}; + int percentVictories(); +}; + +class DeckStats{ +protected: + static DeckStats * mInstance; +public: + mapstats; + static DeckStats * GetInstance(); + void saveStats(Player * player, Player * opponent, GameObserver * game); + void save(const char * filename); + void save(Player * player); + void load(const char * filename); + void load(Player * player); + void cleanStats(); + ~DeckStats(); + int percentVictories(string opponentsDeckFile); +}; + +#endif \ No newline at end of file diff --git a/projects/mtg/include/GameOptions.h b/projects/mtg/include/GameOptions.h index bffad59db..190aa64fb 100644 --- a/projects/mtg/include/GameOptions.h +++ b/projects/mtg/include/GameOptions.h @@ -4,7 +4,8 @@ #define MAX_OPTIONS 50 #define OPTIONS_MUSICVOLUME 0 -#define OPTIONS_INTERRUPTATENDOFPHASE_OFFSET 1 +#define OPTIONS_SFXVOLUME 1 +#define OPTIONS_INTERRUPTATENDOFPHASE_OFFSET 2 #define OPTIONS_SAVEFILE "Res/settings/options.txt" class GameOptions { public: diff --git a/projects/mtg/include/GameStateDeckViewer.h b/projects/mtg/include/GameStateDeckViewer.h index a8a70cd8d..480a620bb 100644 --- a/projects/mtg/include/GameStateDeckViewer.h +++ b/projects/mtg/include/GameStateDeckViewer.h @@ -202,7 +202,7 @@ class GameStateDeckViewer: public GameState, public JGuiListener } GameApp::music = JSoundSystem::GetInstance()->LoadMusic("sound/track1.mp3"); if (GameApp::music){ - JSoundSystem::GetInstance()->PlayMusic(GameApp::music, true); + JSoundSystem::GetInstance()->PlayMusic(GameApp::music, true); } } colorFilter = ALL_COLORS; diff --git a/projects/mtg/include/GameStateDuel.h b/projects/mtg/include/GameStateDuel.h index bd07b5d9d..7ba784b60 100644 --- a/projects/mtg/include/GameStateDuel.h +++ b/projects/mtg/include/GameStateDuel.h @@ -14,6 +14,7 @@ #define ERROR_NO_DECK 4 #define DUEL_PLAY 5 #define DUEL_MENU 6 +#define CHOOSE_OPPONENT 7 #ifdef TESTSUITE @@ -32,10 +33,12 @@ class GameStateDuel: public GameState, public JGuiListener MTGPlayerCards * deck[2]; GameObserver * game; SimpleMenu * deckmenu; + SimpleMenu * opponentMenu; SimpleMenu * menu; - JLBFont* mFont; + JLBFont* mFont, *opponentMenuFont; + int nbAIDecks; - void loadPlayer(int playerId, int decknb = 0); + void loadPlayer(int playerId, int decknb = 0, int isAI = 0); public: GameStateDuel(GameApp* parent); virtual ~GameStateDuel(); diff --git a/projects/mtg/include/GameStateMenu.h b/projects/mtg/include/GameStateMenu.h index 9d25dc006..77b0a80ac 100644 --- a/projects/mtg/include/GameStateMenu.h +++ b/projects/mtg/include/GameStateMenu.h @@ -134,9 +134,11 @@ class GameStateMenu: public GameState, public JGuiListener virtual void Destroy() { + if (mGuiController) delete mGuiController; + if (subMenuController) delete subMenuController; @@ -147,8 +149,10 @@ class GameStateMenu: public GameState, public JGuiListener delete mIcons[i]; } - if (mBg) delete mBg; - if (mMovingW) delete mMovingW; + SAFE_DELETE(mBg); + SAFE_DELETE(mMovingW); + SAFE_DELETE(movingWTexture); + SAFE_DELETE(bgTexture); //SAFE_DELETE (bgMusic); } @@ -265,15 +269,18 @@ class GameStateMenu: public GameState, public JGuiListener if( subMenuController != NULL){ subMenuController->Update(dt); }else{ + subMenuController = NEW SimpleMenu(102, this,mFont, 50,170,SCREEN_WIDTH-120); + if (subMenuController){ - subMenuController->Add(11,"1 Player"); + subMenuController->Add(11,"1 Player"); subMenuController->Add(12, "2 Players"); subMenuController->Add(13,"Demo"); subMenuController->Add(14, "Cancel"); #ifdef TESTSUITE subMenuController->Add(666, "Test Suite"); #endif + } } } diff --git a/projects/mtg/include/GameStateOptions.h b/projects/mtg/include/GameStateOptions.h index e80ef3e07..59a15c2c0 100644 --- a/projects/mtg/include/GameStateOptions.h +++ b/projects/mtg/include/GameStateOptions.h @@ -13,6 +13,8 @@ class SimpleMenu; class GameStateOptions: public GameState, public JGuiListener { +private: + float timer; public: SimpleMenu * optionsMenu; diff --git a/projects/mtg/include/Logger.h b/projects/mtg/include/Logger.h index ef3d8eb4f..b1317f81e 100644 --- a/projects/mtg/include/Logger.h +++ b/projects/mtg/include/Logger.h @@ -3,7 +3,6 @@ - #ifdef DOLOG #define LOG(x) Logger::Log(x); #else @@ -14,7 +13,7 @@ class Logger{ public: - static void Log(char * text); + static void Log(const char * text); }; #endif diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index f00d77820..41d54e1e1 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -27,7 +27,7 @@ class MTGCardInstance: public MTGCard, public Damageable, public Targetable { protected: int untapping; int nb_damages; - + string sample; int lifeOrig; Blockers * blockers; @@ -94,6 +94,7 @@ class MTGCardInstance: public MTGCard, public Damageable, public Targetable { void tap(); int isInPlay(); void resetAllDamage(); + JSample * getSample(); }; diff --git a/projects/mtg/include/PlayGuiObjectController.h b/projects/mtg/include/PlayGuiObjectController.h index baad25d57..be5e23771 100644 --- a/projects/mtg/include/PlayGuiObjectController.h +++ b/projects/mtg/include/PlayGuiObjectController.h @@ -1,18 +1,20 @@ #ifndef _PLAYGUIOBJECTCONTROLLER_H_ #define _PLAYGUIOBJECTCONTROLLER_H_ +#define BIG_CARD_RENDER_TIME 0.4 #include "GuiLayers.h" class PlayGuiObjectController : public GuiLayer{ protected: + float last_user_move; int getClosestItem(int direction); int getClosestItem(int direction, float tolerance); - static bool showBigCards; + static int showBigCards;// 0 hide, 1 show, 2 show text public: virtual void Update(float dt); virtual void CheckUserInput(float dt); - PlayGuiObjectController(int id, GameObserver* _game):GuiLayer(id, _game){}; + PlayGuiObjectController(int id, GameObserver* _game):GuiLayer(id, _game){last_user_move=0;}; virtual void Render(){GuiLayer::Render();}; }; diff --git a/projects/mtg/include/Player.h b/projects/mtg/include/Player.h index cccc4d9d1..6c31ba393 100644 --- a/projects/mtg/include/Player.h +++ b/projects/mtg/include/Player.h @@ -15,6 +15,7 @@ class Player: public Damageable, public Targetable{ ManaCost * manaPool; public: + virtual void End(); int typeAsTarget(){return TARGET_PLAYER;} virtual int displayStack(){return 1;} JTexture * mAvatarTex; diff --git a/projects/mtg/include/SimpleMenu.h b/projects/mtg/include/SimpleMenu.h index 5dc7d7226..470969e66 100644 --- a/projects/mtg/include/SimpleMenu.h +++ b/projects/mtg/include/SimpleMenu.h @@ -14,9 +14,11 @@ class SimpleMenu:public JGuiController{ JLBFont* mFont; std::string title; int displaytitle; + int maxItems,startId; public: - SimpleMenu(int id, JGuiListener* listener, JLBFont* font, int x, int y, int width, const char * _title = NULL); + SimpleMenu(int id, JGuiListener* listener, JLBFont* font, int x, int y, int width, const char * _title = NULL, int _maxItems = 10); void Render(); + void Update(float dt); void Add(int id, const char * Text); }; diff --git a/projects/mtg/include/SimpleMenuItem.h b/projects/mtg/include/SimpleMenuItem.h index e93d0a88f..e3bff7844 100644 --- a/projects/mtg/include/SimpleMenuItem.h +++ b/projects/mtg/include/SimpleMenuItem.h @@ -13,7 +13,7 @@ class SimpleMenuItem: public JGuiObject private: bool mHasFocus; JLBFont *mFont; - const char* mText; + string mText; int mX; int mY; @@ -25,6 +25,7 @@ class SimpleMenuItem: public JGuiObject public: SimpleMenuItem(int id, JLBFont *font, const char* text, int x, int y, bool hasFocus = false); + void RenderWithOffset(float yOffset); virtual void Render(); virtual void Update(float dt); diff --git a/projects/mtg/include/Subtypes.h b/projects/mtg/include/Subtypes.h index cf20e25ed..c70444c7a 100644 --- a/projects/mtg/include/Subtypes.h +++ b/projects/mtg/include/Subtypes.h @@ -19,6 +19,7 @@ class Subtypes{ int find(const char * subtype); int Add(string subtype); int find(string subtype); + string find(int id); }; diff --git a/projects/mtg/include/TexturesCache.h b/projects/mtg/include/TexturesCache.h index 90a6b923a..fc0c70e9a 100644 --- a/projects/mtg/include/TexturesCache.h +++ b/projects/mtg/include/TexturesCache.h @@ -10,6 +10,9 @@ #include #include +#include + +using std::map; #include "MTGDeck.h" @@ -55,4 +58,16 @@ class TexturesCache{ }; +class SampleCache{ +protected: + map cache; + static SampleCache * mInstance; + void cleanCache(); + ~SampleCache(); +public: + static SampleCache * GetInstance(); + JSample * getSample(string filename); + +}; + #endif diff --git a/projects/mtg/include/utils.h b/projects/mtg/include/utils.h index 72e2185c1..487bcaabb 100644 --- a/projects/mtg/include/utils.h +++ b/projects/mtg/include/utils.h @@ -46,5 +46,5 @@ int filesize(const char * filename); int read_file (const char * filename, char * buffer, int filesize); int readline (char * in_buffer, char * out_buffer, int cursor); int readfile_to_ints(const char * filename, int * out_buffer); - +int fileExists(const char * filename); #endif diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index 22aa7e50e..565f53fc4 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -15,7 +15,10 @@ AIPlayer::AIPlayer(MTGPlayerCards * _deck, string file): Player(_deck, file){ AIPlayer::~AIPlayer(){ if (potentialMana) delete potentialMana; - SAFE_DELETE(stats); + if (stats){ + stats->save(); + delete stats; + } } MTGCardInstance * AIPlayer::chooseCard(TargetChooser * tc, MTGCardInstance * source, int random){ for (int i = 0; i < game->hand->nb_cards; i++){ @@ -392,24 +395,29 @@ AIStats * AIPlayer::getStats(){ return stats; } -AIPlayer * AIPlayerFactory::createAIPlayer(MTGAllCards * collection, MTGPlayerCards * oponents_deck){ - int nbdecks = 0; - int found = 1; - while (found){ - found = 0; - char buffer[512]; - sprintf(buffer, "Res/ai/baka/deck%i.txt",nbdecks+1); - std::ifstream file(buffer); - if(file){ - found = 1; - file.close(); - nbdecks++; +AIPlayer * AIPlayerFactory::createAIPlayer(MTGAllCards * collection, MTGPlayerCards * oponents_deck, int deckid){ + if (!deckid){ + int nbdecks = 0; + int found = 1; + while (found){ + found = 0; + char buffer[512]; + sprintf(buffer, "Res/ai/baka/deck%i.txt",nbdecks+1); + std::ifstream file(buffer); + if(file){ + found = 1; + file.close(); + nbdecks++; + } } + if (!nbdecks) return NULL; + deckid = 1 + rand() % (nbdecks); } - if (!nbdecks) return NULL; - int deckid = 1 + rand() % (nbdecks); char deckFile[512]; sprintf(deckFile, "Res/ai/baka/deck%i.txt",deckid); + char avatarFile[512]; + sprintf(avatarFile, "ai/baka/avatars/avatar%i.jpg",deckid); + char deckFileSmall[512]; sprintf(deckFileSmall, "ai_baka_deck%i",deckid); #if defined (WIN32) || defined (LINUX) @@ -420,7 +428,7 @@ AIPlayer * AIPlayerFactory::createAIPlayer(MTGAllCards * collection, MTGPlayerCa int deck_cards_ids[100]; int nb_elements = readfile_to_ints(deckFile, deck_cards_ids); MTGPlayerCards * deck = NEW MTGPlayerCards(collection,deck_cards_ids, nb_elements); - AIPlayerBaka * baka = NEW AIPlayerBaka(deck,deckFileSmall); + AIPlayerBaka * baka = NEW AIPlayerBaka(deck,deckFileSmall, avatarFile); return baka; } @@ -460,8 +468,12 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * potentialMana, const c return nextCardToPlay; } -AIPlayerBaka::AIPlayerBaka(MTGPlayerCards * _deck, char * file): AIPlayer(_deck,file){ - mAvatarTex = JRenderer::GetInstance()->LoadTexture("ai/baka/avatar.jpg", TEX_TYPE_USE_VRAM); +AIPlayerBaka::AIPlayerBaka(MTGPlayerCards * _deck, char * file, char * avatarFile): AIPlayer(_deck,file){ + if (fileExists(avatarFile)){ + mAvatarTex = JRenderer::GetInstance()->LoadTexture(avatarFile, TEX_TYPE_USE_VRAM); + }else{ + mAvatarTex = JRenderer::GetInstance()->LoadTexture("ai/baka/avatar.jpg", TEX_TYPE_USE_VRAM); + } if (mAvatarTex) mAvatar = NEW JQuad(mAvatarTex, 0, 0, 35, 50); initTimer(); diff --git a/projects/mtg/src/AIStats.cpp b/projects/mtg/src/AIStats.cpp index 16589ddc4..8aa0c6047 100644 --- a/projects/mtg/src/AIStats.cpp +++ b/projects/mtg/src/AIStats.cpp @@ -61,7 +61,6 @@ void AIStats::updateStats(){ damage = ((Damage * )as->getNext(damage,ACTION_DAMAGE, RESOLVED_OK)); } stats.sort(compare_aistats); - save(); } bool AIStats::isInTop(MTGCardInstance * card, unsigned int max, bool tooSmallCountsForTrue ){ diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 8f404494f..e654c907e 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -7,6 +7,7 @@ #include "../include/GameObserver.h" #include "../include/Damage.h" #include "../include/ManaCost.h" +#include "../include/GameOptions.h" /* NextGamePhase requested by user @@ -85,6 +86,15 @@ int Spell::resolve(){ GameObserver * game = GameObserver::GetInstance(); //TODO Remove target if it's not targettable anymore source->controller()->game->putInPlay(source); + + //Play SFX + if (GameOptions::GetInstance()->values[OPTIONS_SFXVOLUME] > 0){ + JSample * sample = source->getSample(); + if (sample){ + JSoundSystem::GetInstance()->PlaySample(sample); + } + } + AbilityFactory af; af.addAbilities(game->mLayers->actionLayer()->getMaxId(), this); return 1; diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index bd7fc06e1..4e8c3c0c5 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -59,6 +59,7 @@ void CardGui::alternateRender(MTGCard * card, JLBFont * mFont, JQuad ** manaIcon ManaCost * manacost = card->getManaCost(); int nbicons = 0; for (int i = 1; i < MTG_NB_COLORS - 1; i++){ + int cost = manacost->getCost(i); for (int j=0; j < cost; j++){ v.x = (width/2 - 20 - 16*nbicons)*scale; @@ -74,13 +75,13 @@ void CardGui::alternateRender(MTGCard * card, JLBFont * mFont, JQuad ** manaIcon v.y = ((-height/2) + 14) * scale; v.Rotate(rotation); sprintf(buf,"%i",cost); + mFont->SetColor(ARGB(255,255,255,255)); mFont->DrawString(buf,x+v.x,y+v.y); } if (!card->formattedTextInit){ std::string s(card->getText()); std::string::size_type found=s.find_first_of("{}"); - while (found!=string::npos) { s[found]='/'; @@ -201,9 +202,7 @@ void CardGui::Update(float dt){ PlayGuiObject::Update(dt); } -void CardGui::RenderBig(float xpos, float ypos){ - JRenderer * renderer = JRenderer::GetInstance(); - JQuad * quad = card->getQuad(); +void CardGui::RenderBig(float xpos, float ypos, int alternate){ if (xpos == -1){ xpos = 300; if (x > SCREEN_WIDTH / 2) @@ -211,10 +210,19 @@ void CardGui::RenderBig(float xpos, float ypos){ } if(ypos == -1) ypos = 20; - if (quad){ - quad->SetColor(ARGB(220,255,255,255)); - renderer->RenderQuad(quad, xpos , ypos , 0.0f,0.9f,0.9f); - }else{ + if (!alternate){ + JRenderer * renderer = JRenderer::GetInstance(); + JQuad * quad = card->getQuad(); + if (quad){ + quad->SetColor(ARGB(220,255,255,255)); + renderer->RenderQuad(quad, xpos , ypos , 0.0f,0.9f,0.9f); + }else{ + alternate = 1; + } + } + + + if (alternate){ MTGCard * mtgcard = card->model; JLBFont * font = GameApp::CommonRes->GetJLBFont("graphics/magic"); CardGui::alternateRender(mtgcard, font, NULL, xpos + 90 , ypos + 130, 0.0f,0.9f); diff --git a/projects/mtg/src/DeckStats.cpp b/projects/mtg/src/DeckStats.cpp new file mode 100644 index 000000000..0f51a3f4e --- /dev/null +++ b/projects/mtg/src/DeckStats.cpp @@ -0,0 +1,98 @@ +#include "../include/debug.h" +#include "../include/DeckStats.h" +#include "../include/Player.h" + +DeckStats * DeckStats::mInstance = NULL; + +int DeckStat::percentVictories(){ + if (nbgames == 0) return 50; + return (100 * victories / nbgames); +} + +DeckStats * DeckStats::GetInstance(){ + if (!mInstance) mInstance = NEW DeckStats(); + return mInstance; +} + +void DeckStats::cleanStats(){ + map::iterator it; + for (it = stats.begin(); it != stats.end(); it++){ + delete(it->second); + } + stats.clear(); +} + +DeckStats::~DeckStats(){ + cleanStats(); +} + +int DeckStats::percentVictories(string opponentsFile){ + map::iterator it = stats.find(opponentsFile); + if (it == stats.end()){ + return 50; + }else{ + return (it->second->percentVictories()); + } +} + +void DeckStats::load(Player * player){ + char filename[512]; + sprintf(filename, "Res/player/stats/%s.txt",player->deckFile.c_str()); + load(filename); +} + +void DeckStats::load(const char * filename){ + cleanStats(); + std::ifstream file(filename); + std::string s; + + if(file){ + while(std::getline(file,s)){ + string deckfile = s; + std::getline(file,s); + int games = atoi(s.c_str()); + std::getline(file,s); + int victories = atoi(s.c_str()); + stats[deckfile] = NEW DeckStat(games,victories); + } + file.close(); + } +} + +void DeckStats::save(Player * player){ + char filename[512]; + sprintf(filename, "Res/player/stats/%s.txt",player->deckFile.c_str()); + save(filename); +} + +void DeckStats::save(const char * filename){ + std::ofstream file(filename); + char writer[512]; + if (file){ + map::iterator it; + for (it = stats.begin(); it != stats.end(); it++){ + sprintf(writer,"%s\n", it->first.c_str()); + file<second->nbgames); + file<second->victories); + file<gameOver == player) victory = 0; + load(player); + map::iterator it = stats.find(opponent->deckFile); + if (it == stats.end()){ + stats[opponent->deckFile] = NEW DeckStat(1,victory); + }else{ + it->second->victories+=victory; + it->second->nbgames+=1; + } + save(player); + +} diff --git a/projects/mtg/src/GameApp.cpp b/projects/mtg/src/GameApp.cpp index 6a6f4d435..0fa75ec3b 100644 --- a/projects/mtg/src/GameApp.cpp +++ b/projects/mtg/src/GameApp.cpp @@ -15,7 +15,7 @@ #include "../include/GameStateDuel.h" #include "../include/GameStateOptions.h" #include "../include/GameStateShop.h" - +#include "../include/DeckStats.h" const char * const GameState::menuTexts[]= {"--NEW--","Deck 1", "Deck 2", "Deck 3", "Deck 4", "Deck 5", "Deck 6"} ; JResourceManager* GameApp::CommonRes = NEW JResourceManager(); @@ -179,6 +179,10 @@ void GameApp::Destroy() if (Subtypes::subtypesList) delete Subtypes::subtypesList; if (MtgSets::SetsList) delete MtgSets::SetsList; + + SAFE_DELETE(music); + + delete(DeckStats::GetInstance()); LOG("==Destroying GameApp Successful=="); } diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index a7aad5cc5..1be98e696 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -3,6 +3,8 @@ #include "../include/utils.h" #include "../include/AIPlayer.h" #include "../include/PlayerData.h" +#include "../include/DeckStats.h" + #ifdef TESTSUITE #include "../include/TestSuiteAI.h" @@ -16,6 +18,7 @@ GameStateDuel::GameStateDuel(GameApp* parent): GameState(parent) { game = NULL; deckmenu = NULL; + opponentMenu = NULL; menu = NULL; #ifdef TESTSUITE testSuite = NULL; @@ -43,6 +46,7 @@ void GameStateDuel::Start() mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); mFont->SetBase(0); // using 2nd font + opponentMenuFont = NEW JLBFont("graphics/f3",16); menu = NEW SimpleMenu(11,this,mFont,SCREEN_WIDTH/2-100,20,200); @@ -79,16 +83,22 @@ void GameStateDuel::Start() } -void GameStateDuel::loadPlayer(int playerId, int decknb){ - if (decknb){ //Human Player - char deckFile[255]; - sprintf(deckFile, "Res/player/deck%i.txt",decknb); - char deckFileSmall[255]; - sprintf(deckFileSmall, "player_deck%i",decknb); - int deck_cards_ids[100]; - int nb_elements = readfile_to_ints(deckFile, deck_cards_ids); - deck[playerId] = NEW MTGPlayerCards(mParent->collection,deck_cards_ids, nb_elements); - mPlayers[playerId] = NEW HumanPlayer(deck[playerId],deckFileSmall); +void GameStateDuel::loadPlayer(int playerId, int decknb, int isAI){ + if (decknb){ + if (!isAI){ //Human Player + char deckFile[255]; + sprintf(deckFile, "Res/player/deck%i.txt",decknb); + char deckFileSmall[255]; + sprintf(deckFileSmall, "player_deck%i",decknb); + int deck_cards_ids[100]; + int nb_elements = readfile_to_ints(deckFile, deck_cards_ids); + deck[playerId] = NEW MTGPlayerCards(mParent->collection,deck_cards_ids, nb_elements); + mPlayers[playerId] = NEW HumanPlayer(deck[playerId],deckFileSmall); + }else{ //AI Player, chose deck + AIPlayerFactory playerCreator; + mPlayers[playerId] = playerCreator.createAIPlayer(mParent->collection,NULL,decknb); + deck[playerId] = mPlayers[playerId]->game; + } }else{ AIPlayerFactory playerCreator; mPlayers[playerId] = playerCreator.createAIPlayer(mParent->collection,NULL); @@ -127,15 +137,21 @@ void GameStateDuel::End() #if defined (WIN32) || defined (LINUX) OutputDebugString("Ending GamestateDuel\n"); #endif - GameObserver::EndInstance(); - game = NULL; + SAFE_DELETE(deckmenu); JRenderer::GetInstance()->EnableVSync(false); + if (mPlayers[0] && mPlayers[1]) mPlayers[0]->End(); + GameObserver::EndInstance(); + game = NULL; + for (int i = 0; i < 2; i++){ SAFE_DELETE(mPlayers[i]); SAFE_DELETE(deck[i]); } + SAFE_DELETE(menu); + SAFE_DELETE(opponentMenu); + SAFE_DELETE(opponentMenuFont); #ifdef TESTSUITE SAFE_DELETE(testSuite); #endif @@ -176,8 +192,43 @@ void GameStateDuel::Update(float dt) } else{ - loadPlayer(1); - mGamePhase = DUEL_PLAY; + if (mParent->players[0] == PLAYER_TYPE_HUMAN){ + if (!opponentMenu){ + opponentMenu = NEW SimpleMenu(13,this,opponentMenuFont,10,10,SCREEN_WIDTH/2,"choose Opponent"); + opponentMenu->Add(0,"Random"); + nbAIDecks = 0; + int found = 1; + while (found){ + found = 0; + char buffer[512]; + char aiSmallDeckName[512]; + char deckDesc[512]; + sprintf(buffer, "Res/ai/baka/deck%i.txt",nbAIDecks+1); + if(fileExists(buffer)){ + found = 1; + nbAIDecks++; + sprintf(aiSmallDeckName, "ai_baka_deck%i",nbAIDecks); + DeckStats * stats = DeckStats::GetInstance(); + stats->load(mPlayers[0]); + int percentVictories = stats->percentVictories(string(aiSmallDeckName)); + string difficulty; + if (percentVictories < 34){ + difficulty = "(hard)"; + }else if (percentVictories < 67){ + difficulty = ""; + }else{ + difficulty = "(easy)"; + } + sprintf(deckDesc, "Deck %i %s",nbAIDecks, difficulty.c_str()); + opponentMenu->Add(nbAIDecks,deckDesc); + } + } + } + opponentMenu->Update(dt); + }else{ + loadPlayer(1); + mGamePhase = DUEL_PLAY; + } } }else if (mGamePhase == DUEL_PLAY){ @@ -259,14 +310,17 @@ void GameStateDuel::Render() }else{ int winner = 2; if (game->gameOver !=mPlayers[0]){ - winner = 1; + winner = 1; } sprintf(buffer, "Player %i wins (%i)", winner, p0life ); } mFont->DrawString(buffer, 10, 150); }else if (mGamePhase == DUEL_CHOOSE_DECK1 || mGamePhase == DUEL_CHOOSE_DECK2){ - if (deckmenu) + if (opponentMenu){ + opponentMenu->Render(); + }else if (deckmenu){ deckmenu->Render(); + } }else if (mGamePhase == ERROR_NO_DECK){ mFont->DrawString("NO DECK AVAILABLE,",0,SCREEN_HEIGHT/2); mFont->DrawString("PRESS CIRCLE TO GO TO THE DECK EDITOR!",0,SCREEN_HEIGHT/2 + 20); @@ -278,30 +332,50 @@ void GameStateDuel::Render() void GameStateDuel::ButtonPressed(int controllerId, int controlId) { - switch (controlId) - { - case 1: - case 2: - case 3: - case 4: - case 5: - { - if (mGamePhase == DUEL_CHOOSE_DECK1){ - loadPlayer(0,controlId); - mGamePhase = DUEL_CHOOSE_DECK2; - }else{ - loadPlayer(1,controlId); - mGamePhase = DUEL_PLAY; - } - break; - } - case 12: - mParent->SetNextState(GAME_STATE_MENU); - break; + switch (controllerId){ case 13: - mGamePhase = DUEL_PLAY; - break; - } + { + switch(controlId){ + case 0: + loadPlayer(1); + mGamePhase = DUEL_PLAY; + break; + default: + loadPlayer(1,controlId,1); + mGamePhase = DUEL_PLAY; + break; + + } + break; + } + default: + { + switch (controlId) + { + case 1: + case 2: + case 3: + case 4: + case 5: + { + if (mGamePhase == DUEL_CHOOSE_DECK1){ + loadPlayer(0,controlId); + mGamePhase = DUEL_CHOOSE_DECK2; + }else{ + loadPlayer(1,controlId); + mGamePhase = DUEL_PLAY; + } + break; + } + case 12: + mParent->SetNextState(GAME_STATE_MENU); + break; + case 13: + mGamePhase = DUEL_PLAY; + break; + } + } + } } diff --git a/projects/mtg/src/GameStateOptions.cpp b/projects/mtg/src/GameStateOptions.cpp index bd199dacc..3c973a6c0 100644 --- a/projects/mtg/src/GameStateOptions.cpp +++ b/projects/mtg/src/GameStateOptions.cpp @@ -17,12 +17,15 @@ GameStateOptions::~GameStateOptions() { void GameStateOptions::Start() { + + timer = 0; mState = SHOW_OPTIONS; JRenderer::GetInstance()->ResetPrivateVRAM(); JRenderer::GetInstance()->EnableVSync(true); optionsList = NEW OptionsList(); if (GameApp::HasMusic) optionsList->Add(NEW OptionItem(OPTIONS_MUSICVOLUME, "Music volume", 100, 10)); + optionsList->Add(NEW OptionItem(OPTIONS_SFXVOLUME, "SFX volume", 100, 10)); JLBFont * mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); optionsMenu = NEW SimpleMenu(102, this,mFont, 50,170,SCREEN_WIDTH-120); optionsMenu->Add(1, "Save & Back to Main Menu"); @@ -41,6 +44,8 @@ void GameStateOptions::End() void GameStateOptions::Update(float dt) { + + timer+= dt; if (mState == SHOW_OPTIONS){ if (mEngine->GetButtonClick(PSP_CTRL_START)){ mState = SHOW_OPTIONS_MENU; @@ -59,17 +64,18 @@ void GameStateOptions::Render() { //Erase JRenderer::GetInstance()->ClearScreen(ARGB(0,0,0,0)); - optionsList->Render(); const char * const CreditsText[] = { "Wagic, The Homebrew ?! by WilLoW", "This is a work in progress and it contains bugs, deal with it", "updates on http://www.wololo.net/wagic", + "Many thanks to Abrasax and J for their help in this release", "", - "Developped with the JGE++ Library", - "http://jge.khors.com", + "Developped with the JGE++ Library (http://jge.khors.com)", "", "this freeware app is not endorsed by Wizards of the Coast, Inc", + "", + "SFX From www.soundsnap.com", }; @@ -80,24 +86,35 @@ void GameStateOptions::Render() }; - JLBFont * mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); + JLBFont * mFont = GameApp::CommonRes->GetJLBFont("graphics/magic"); mFont->SetColor(ARGB(255,200,200,200)); - mFont->SetScale(0.80); - for (int i = 0; i < 8; i++){ - mFont->DrawString(CreditsText[i],SCREEN_WIDTH/2, 40 +18*i,JGETEXT_CENTER); + mFont->SetScale(1.0); + float startpos = 272 - timer * 10; + float pos = startpos; + for (int i = 0; i < 10; i++){ + pos = startpos +20*i; + if (pos > -20){ + mFont->DrawString(CreditsText[i],SCREEN_WIDTH/2,pos ,JGETEXT_CENTER); + } } if (GameApp::HasMusic){ for (int i = 0; i < 3; i++){ - mFont->DrawString(MusicText[i],SCREEN_WIDTH/2, 40 +18*(8+i),JGETEXT_CENTER); + pos = startpos +20*(10+i); + if (pos > -20){ + mFont->DrawString(MusicText[i],SCREEN_WIDTH/2, pos,JGETEXT_CENTER); + } } } + if (pos < -20) timer = 0; mFont->SetScale(1.f); if (mState == SHOW_OPTIONS_MENU){ optionsMenu->Render(); } + optionsList->Render(); + } diff --git a/projects/mtg/src/GameStateShop.cpp b/projects/mtg/src/GameStateShop.cpp index 3daf7d4ed..511d987ca 100644 --- a/projects/mtg/src/GameStateShop.cpp +++ b/projects/mtg/src/GameStateShop.cpp @@ -26,14 +26,19 @@ void GameStateShop::Start() { menu = NULL; mFont = GameApp::CommonRes->GetJLBFont("graphics/magic"); + + mStage = STAGE_SHOP_SHOP; + bgTexture = JRenderer::GetInstance()->LoadTexture("graphics/shop.jpg", TEX_TYPE_USE_VRAM); mBg = NEW JQuad(bgTexture, 0, 0, 400, 280); // Create background quad for rendering. backTexture = JRenderer::GetInstance()->LoadTexture("sets/back.jpg", TEX_TYPE_USE_VRAM); mBack = NEW JQuad(backTexture, 0, 0, 200, 285); // Create background quad for rendering. + JRenderer::GetInstance()->ResetPrivateVRAM(); JRenderer::GetInstance()->EnableVSync(true); + int sets[500]; int nbsets = 0; for (int i = 0; i < MtgSets::SetsList->nb_items; i++){ @@ -48,6 +53,9 @@ void GameStateShop::Start() setId = (rand() % MtgSets::SetsList->nb_items); } JQuad * mBackThumb = GameApp::CommonRes->GetQuad("back_thumb"); + + shop = NULL; + shop = NEW ShopItems(10, this, mFont, 10, 10, mParent->collection, setId); sprintf(starterBuffer, "%s Starter (60 cards)",MtgSets::SetsList->values[setId].c_str()); sprintf(boosterBuffer, "%s Booster (15 cards)",MtgSets::SetsList->values[setId].c_str()); @@ -63,9 +71,9 @@ void GameStateShop::Start() void GameStateShop::End() { JRenderer::GetInstance()->EnableVSync(false); - if (shop) - SAFE_DELETE(shop); + SAFE_DELETE(shop); SAFE_DELETE(mBack); + SAFE_DELETE(backTexture); if(bgTexture) SAFE_DELETE(bgTexture); if(mBg) @@ -115,11 +123,11 @@ void GameStateShop::ButtonPressed(int controllerId, int controlId) { switch (controllerId){ case 10: - shop->pricedialog(controlId); + if (shop) shop->pricedialog(controlId); break; case 11: if (controlId == 12){ - shop->saveAll(); + if (shop) shop->saveAll(); mParent->SetNextState(GAME_STATE_MENU); }else{ mStage = STAGE_SHOP_SHOP; diff --git a/projects/mtg/src/Logger.cpp b/projects/mtg/src/Logger.cpp index 3766fe3ad..19fa15f55 100644 --- a/projects/mtg/src/Logger.cpp +++ b/projects/mtg/src/Logger.cpp @@ -8,7 +8,7 @@ using namespace std; #include #endif -void Logger::Log(char * text){ +void Logger::Log(const char * text){ ofstream file (LOG_FILE,ios_base::app); if (file){ file << text; diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index e5ce5695b..f88e24f1f 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -8,6 +8,7 @@ #include "../include/MTGCardInstance.h" #include "../include/CardDescriptor.h" #include "../include/Counters.h" +#include "../include/Subtypes.h" MTGCardInstance::MTGCardInstance(): MTGCard(), Damageable(0){ LOG("==Creating MTGCardInstance=="); @@ -33,6 +34,7 @@ MTGCardInstance::~MTGCardInstance(){ LOG("==Deleting MTGCardInstance Succesfull=="); } void MTGCardInstance::initMTGCI(){ + sample = ""; model=NULL; lifeOrig = 0; doDamageTest = 0; @@ -405,3 +407,42 @@ int MTGCardInstance::protectedAgainst(MTGCardInstance * card){ } return 0; } + +/* Choose a sound sample to associate to that card */ +JSample * MTGCardInstance::getSample(){ + if (!sample.size()){ + for (int i = nb_types-1; i>0; i--){ + string type = Subtypes::subtypesList->find(types[i]); + type = "sound/sfx/" + type + ".wav"; +#ifdef WIN32 + OutputDebugString(type.c_str()); +#endif + if (fileExists(type.c_str())){ + sample = string(type); + break; + } + } + } + if (!sample.size()){ + for (int i = 0; i < NB_BASIC_ABILITIES; i++){ + if (!basicAbilities[i]) continue; + string type = MTGBasicAbilities[i]; + type = "sound/sfx/" + type + ".wav"; + if (fileExists(type.c_str())){ + sample = type; + break; + } + } + } + if (!sample.size()){ + string type = Subtypes::subtypesList->find(types[0]); + type = "sound/sfx/" + type + ".wav"; + if (fileExists(type.c_str())){ + sample = type; + } + } + + if (sample.size()) return SampleCache::GetInstance()->getSample(sample); + + return NULL; +} \ No newline at end of file diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index 6b5b525fa..0132add4a 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -77,7 +77,7 @@ int MTGAllCards::processConfLine(char *buffer, MTGCard *card){ card->setType( "Artifact"); card->setColor(MTG_COLOR_ARTIFACT); if (value.c_str()[8] == ' ' && value.c_str()[9] == 'C') - card->setSubtype("Creature"); + card->setSubtype("Creature"); break; case 'E': card->setType( "Enchantment"); diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 50f615c9f..614873592 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -1,6 +1,7 @@ #include "../include/debug.h" #include "../include/MTGGameZones.h" #include "../include/Player.h" +#include "../include/GameOptions.h" #if defined (WIN32) || defined (LINUX) #include @@ -90,9 +91,16 @@ void MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGa if (from->removeCard(card)){ to->addCard(card); card->changedZoneRecently = 1.f; - //if (to == graveyard){ + card->reset(); - //} + if (GameOptions::GetInstance()->values[OPTIONS_SFXVOLUME] > 0){ + if (to == graveyard){ + if (card->isACreature()){ + JSample * sample = SampleCache::GetInstance()->getSample("sound/sfx/graveyard.wav"); + if (sample) JSoundSystem::GetInstance()->PlaySample(sample); + } + } + } } } diff --git a/projects/mtg/src/MTGGuiHand.cpp b/projects/mtg/src/MTGGuiHand.cpp index 766ea2050..d1ed77540 100644 --- a/projects/mtg/src/MTGGuiHand.cpp +++ b/projects/mtg/src/MTGGuiHand.cpp @@ -95,7 +95,7 @@ void MTGGuiHand::Render(){ } if (mCount && mObjects[mCurr] != NULL){ mObjects[mCurr]->Render(); - if (showBigCards) ((CardGui *)mObjects[mCurr])->RenderBig(10); + if (showBigCards) ((CardGui *)mObjects[mCurr])->RenderBig(10,-1,showBigCards-1); } } } diff --git a/projects/mtg/src/MTGGuiPlay.cpp b/projects/mtg/src/MTGGuiPlay.cpp index f794e023c..d5a316b10 100644 --- a/projects/mtg/src/MTGGuiPlay.cpp +++ b/projects/mtg/src/MTGGuiPlay.cpp @@ -361,8 +361,9 @@ void MTGGuiPlay::Render(){ if (mCount && mObjects[mCurr] != NULL){ mObjects[mCurr]->Render(); - if (hasFocus && mCurr >= offset && showBigCards) - ((CardGui *)mObjects[mCurr])->RenderBig(); + if (hasFocus && mCurr >= offset && showBigCards && last_user_move > BIG_CARD_RENDER_TIME){ + ((CardGui *)mObjects[mCurr])->RenderBig(-1,-1,showBigCards-1); + } } if (mGlitterAlpha < 0){ diff --git a/projects/mtg/src/OptionItem.cpp b/projects/mtg/src/OptionItem.cpp index 4ca1a8651..78e2c1dc0 100644 --- a/projects/mtg/src/OptionItem.cpp +++ b/projects/mtg/src/OptionItem.cpp @@ -31,6 +31,7 @@ void OptionItem::Render(){ mFont->SetColor(ARGB(255,255,255,255)); } JRenderer * renderer = JRenderer::GetInstance(); + renderer->FillRoundRect(x-5,y-2,SCREEN_WIDTH -x - 5,20,2,ARGB(150,50,50,50)); mFont->DrawString(displayValue.c_str(),x,y); char buf[512]; sprintf(buf, "%i", value); diff --git a/projects/mtg/src/PlayGuiObjectController.cpp b/projects/mtg/src/PlayGuiObjectController.cpp index b3e590e9c..d06bd3129 100644 --- a/projects/mtg/src/PlayGuiObjectController.cpp +++ b/projects/mtg/src/PlayGuiObjectController.cpp @@ -4,7 +4,7 @@ #include "../include/PlayGuiObject.h" #include "../include/GameObserver.h" -bool PlayGuiObjectController::showBigCards = true; +int PlayGuiObjectController::showBigCards = 1; int PlayGuiObjectController::getClosestItem(int direction){ return getClosestItem(direction, 35); @@ -177,6 +177,7 @@ void PlayGuiObjectController::Update(float dt){ void PlayGuiObjectController::CheckUserInput(float dt){ + last_user_move +=dt; if (!mCount) return; if (game != NULL){ @@ -193,6 +194,8 @@ void PlayGuiObjectController::CheckUserInput(float dt){ if (mEngine->GetButtonState(PSP_CTRL_LEFT)) { + + last_user_move = 0; if (KeyRepeated(PSP_CTRL_LEFT, dt)) { int n = getClosestItem(DIR_LEFT); @@ -205,6 +208,7 @@ void PlayGuiObjectController::CheckUserInput(float dt){ } else if (mEngine->GetButtonState(PSP_CTRL_RIGHT)) { + last_user_move = 0; if (KeyRepeated(PSP_CTRL_RIGHT, dt)) { int n = getClosestItem(DIR_RIGHT); @@ -217,6 +221,7 @@ void PlayGuiObjectController::CheckUserInput(float dt){ } else if (mEngine->GetButtonState(PSP_CTRL_UP)) { + last_user_move = 0; if (KeyRepeated(PSP_CTRL_UP, dt)) { int n = getClosestItem(DIR_UP); @@ -229,6 +234,7 @@ void PlayGuiObjectController::CheckUserInput(float dt){ } else if (mEngine->GetButtonState(PSP_CTRL_DOWN)) { + last_user_move = 0; if (KeyRepeated(PSP_CTRL_DOWN, dt)) { int n = getClosestItem(DIR_DOWN); @@ -239,7 +245,7 @@ void PlayGuiObjectController::CheckUserInput(float dt){ } } }else if (mEngine->GetButtonClick(PSP_CTRL_TRIANGLE)){ - showBigCards = !showBigCards; + showBigCards = (++showBigCards) %3; } else{ diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index b310a70ee..04c626eef 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -1,7 +1,7 @@ #include "../include/debug.h" #include "../include/Player.h" #include "../include/GameObserver.h" - +#include "../include/DeckStats.h" Player::Player(MTGPlayerCards * _deck, string file): Damageable(20){ @@ -14,6 +14,11 @@ Player::Player(MTGPlayerCards * _deck, string file): Damageable(20){ type_as_damageable = DAMAGEABLE_PLAYER; } +/*Method to call at the end of a game, before all objects involved in the game are destroyed */ +void Player::End(){ + DeckStats::GetInstance()->saveStats(this, opponent(),GameObserver::GetInstance()); +} + Player::~Player(){ if (manaPool) delete manaPool; if (mAvatarTex) delete mAvatarTex; diff --git a/projects/mtg/src/SimpleMenu.cpp b/projects/mtg/src/SimpleMenu.cpp index dd7012fd9..5fe7ec5c9 100644 --- a/projects/mtg/src/SimpleMenu.cpp +++ b/projects/mtg/src/SimpleMenu.cpp @@ -2,7 +2,7 @@ #include "../include/SimpleMenu.h" #include "../include/SimpleMenuItem.h" -SimpleMenu::SimpleMenu(int id, JGuiListener* listener, JLBFont* font, int x, int y, int width, const char * _title): JGuiController(id, listener){ +SimpleMenu::SimpleMenu(int id, JGuiListener* listener, JLBFont* font, int x, int y, int width, const char * _title, int _maxItems): JGuiController(id, listener){ mHeight = 0; mWidth = width; mX = x; @@ -15,6 +15,8 @@ SimpleMenu::SimpleMenu(int id, JGuiListener* listener, JLBFont* font, int x, int }else{ displaytitle = 0; } + startId = 0; + maxItems = _maxItems; } void SimpleMenu::Render(){ @@ -25,10 +27,24 @@ void SimpleMenu::Render(){ renderer->FillRoundRect(mX+2,mY+2,mWidth - 4,mHeight-4,10,ARGB(255,62,62,62)); if (displaytitle) mFont->DrawString(title.c_str(), mX+10, mY+10); - JGuiController::Render(); + for (int i = startId; i < startId + maxItems ; i++){ + if (i > mCount-1) break; + ((SimpleMenuItem * )mObjects[i])->RenderWithOffset(-20*startId); + } +} + +void SimpleMenu::Update(float dt){ + JGuiController::Update(dt); + if (mCurr > startId + maxItems-1){ + startId = mCurr - maxItems +1; + }else if (mCurr < startId){ + startId = mCurr; + } } void SimpleMenu::Add(int id, const char * text){ - JGuiController::Add(NEW SimpleMenuItem(id, mFont, text, mWidth/2 + mX + 10, mY + 10 + mHeight, (mCount == 0))); - mHeight += 20; + int y = mCount*20; + if (displaytitle) y+=20; + JGuiController::Add(NEW SimpleMenuItem(id, mFont, text, mWidth/2 + mX + 10, mY + 10 + y, (mCount == 0))); + if (mCount <= maxItems) mHeight += 20; } diff --git a/projects/mtg/src/SimpleMenuItem.cpp b/projects/mtg/src/SimpleMenuItem.cpp index 58b4481b1..d8706e9d1 100644 --- a/projects/mtg/src/SimpleMenuItem.cpp +++ b/projects/mtg/src/SimpleMenuItem.cpp @@ -2,10 +2,10 @@ #include "../include/SimpleMenuItem.h" -SimpleMenuItem::SimpleMenuItem(int id, JLBFont *font, const char* text, int x, int y, bool hasFocus): JGuiObject(id), mFont(font), mText(text), mX(x), mY(y) +SimpleMenuItem::SimpleMenuItem(int id, JLBFont *font, const char* text, int x, int y, bool hasFocus): JGuiObject(id), mFont(font), mX(x), mY(y) { - + mText = text; mHasFocus = hasFocus; mScale = 1.0f; @@ -20,7 +20,7 @@ SimpleMenuItem::SimpleMenuItem(int id, JLBFont *font, const char* text, int x, i } -void SimpleMenuItem::Render() +void SimpleMenuItem::RenderWithOffset(float yOffset) { mFont->SetScale(mScale); @@ -29,10 +29,16 @@ void SimpleMenuItem::Render() { mFont->SetColor(ARGB(255,255,255,0)); } - mFont->DrawString(mText, mX, mY, JGETEXT_CENTER); + mFont->DrawString(mText.c_str(), mX, mY + yOffset, JGETEXT_CENTER); mFont->SetScale(1.0f); } +void SimpleMenuItem::Render() +{ + + RenderWithOffset(0); +} + void SimpleMenuItem::Update(float dt) { if (mScale < mTargetScale) diff --git a/projects/mtg/src/Subtypes.cpp b/projects/mtg/src/Subtypes.cpp index dc9b5d233..585901288 100644 --- a/projects/mtg/src/Subtypes.cpp +++ b/projects/mtg/src/Subtypes.cpp @@ -43,3 +43,12 @@ int Subtypes::find(const char * subtype){ return (find(value)); } + +/*This will be slow... */ +string Subtypes::find(int id){ + map::iterator it; + for (it = values.begin(); it != values.end(); it++){ + if (it->second == id) return it->first; + } + return NULL; +} \ No newline at end of file diff --git a/projects/mtg/src/TexturesCache.cpp b/projects/mtg/src/TexturesCache.cpp index db36dbaf3..23cdd4e62 100644 --- a/projects/mtg/src/TexturesCache.cpp +++ b/projects/mtg/src/TexturesCache.cpp @@ -117,3 +117,37 @@ CardTexture::~CardTexture(){ LOG("CardTexture Object deletion Succesful"); } + +SampleCache * SampleCache::mInstance = NULL; + +SampleCache * SampleCache::GetInstance(){ + if (!mInstance) mInstance = NEW SampleCache(); + return mInstance; +} + +JSample * SampleCache::getSample(string filename){ + map::iterator it = cache.find(filename); + if (it == cache.end()){ + if (cache.size() >10) cleanCache(); //Poor man's limit + JSample * sample = JSoundSystem::GetInstance()->LoadSample(filename.c_str()); + if (!sample && fileExists(filename.c_str())){ //Out of Ram ?? + cleanCache(); + sample = JSoundSystem::GetInstance()->LoadSample(filename.c_str()); + } + return sample; + }else{ + return (it->second); + } +} + +void SampleCache::cleanCache(){ + map::iterator it; + for (it = cache.begin(); it != cache.end(); it++){ + delete(it->second); + } + cache.clear(); +} + +SampleCache::~SampleCache(){ + cleanCache(); +} \ No newline at end of file diff --git a/projects/mtg/src/utils.cpp b/projects/mtg/src/utils.cpp index a80e6b122..172dc7922 100644 --- a/projects/mtg/src/utils.cpp +++ b/projects/mtg/src/utils.cpp @@ -142,3 +142,20 @@ int readfile_to_ints(const char * filename, int * out_buffer){ return count; } + +int fileExists(const char * filename){ + std::ifstream fichier(filename); +if(fichier){ + fichier.close(); + return 1; +} + +char alternateFilename[512]; +sprintf(alternateFilename, "Res/%s",filename); + std::ifstream fichier2(alternateFilename); +if(fichier2){ + fichier2.close(); + return 1; +} +return 0; +} \ No newline at end of file diff --git a/projects/mtg/template.vcproj b/projects/mtg/template.vcproj index 2aee522b9..15b91c64e 100644 --- a/projects/mtg/template.vcproj +++ b/projects/mtg/template.vcproj @@ -276,6 +276,10 @@ RelativePath=".\src\DeckDataWrapper.cpp" > + + @@ -565,6 +569,10 @@ RelativePath=".\include\DeckDataWrapper.h" > + +